Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial Internet of Things >> Встроенный

Структуры в встроенном C: практическое руководство по определению, использованию и оптимизации памяти

Структуры — краеугольный камень эффективного встроенного программирования на C. В этой статье мы рассмотрим их практические применения, синтаксис объявления и влияние выравнивания данных на использование памяти. Грамотная упорядочивание членов структуры часто позволяет сократить размер объектов данных, что критично в ресурсоограниченных средах.

Статья дает лаконичный, но исчерпывающий обзор структур во встроенном C. Мы покроем их реальные применения, правильное объявление и тонкие правила выравнивания данных, влияющие на размер структур.

Структуры

Когда несколько переменных одного типа связаны логически, удобен массив. Например, для хранения последних 50 отсчетов АЦП, оцифровывающего голосовой вход, можно использовать:

uint16_t voice[50];

Здесь uint16_t — беззнаковое 16-битное целое, определенное в stdint.h, гарантирующее одинаковый размер на всех платформах.

Но что, если нужно сгруппировать переменные разных типов — скажем, массив отсчетов и частоту дискретизации АЦП? Объявление их как отдельных независимых переменных создает лишние накладные расходы. Вместо этого можно инкапсулировать их в структуру:

struct record { uint16_t voice[50]; float sample_rate; };

Структура record теперь содержит и массив uint16_t, и float в едином логически связанном объекте данных.

Почему структуры важны?

Структуры позволяют ассоциировать разнородные переменные в сплошную единицу, упрощая манипуляции и повышая читаемость. Они лежат в основе более сложных структур данных — связных списков и буферов сообщений, повсеместно используемых во встроенных коммуникациях и обработке сенсорных данных.

Например, память-отображаемые периферийные устройства микроконтроллеров часто представлены структурами, зеркалящими раскладку аппаратных регистров, что дает прямой доступ к регистрам через синтаксис членов.

Структуры в встроенном C: практическое руководство по определению, использованию и оптимизации памяти

Рисунок 1. Структуры могут использоваться для реализации связного списка.

Структуры в встроенном C: практическое руководство по определению, использованию и оптимизации памяти

Рисунок 2. Карта памяти STM32 MCU. Изображение предоставлено Embedded Systems with ARM.

Объявление структуры

Сначала определяете шаблон структуры. Пример:

struct record { uint16_t voice[4]; float sample_rate; };

Сам шаблон не потребляет память; выделение происходит только при объявлении переменной этого типа:

struct record mic1;

Теперь mic1 занимает место для четырех элементов uint16_t и одного float. Доступ к членам через точечный оператор:

mic1.voice[0] = 100; float fs = mic1.sample_rate;

Другие способы объявления структуры

Хотя самый частый паттерн — сначала определить структуру, потом объявить переменные, C предлагает альтернативные синтаксисы:

Синтаксис 1: тег и переменная вместе

struct record { uint16_t voice[4]; float sample_rate; } mic1;

Последующие переменные можно объявлять отдельно:

struct record mic2;

Синтаксис 2: анонимный шаблон

struct { uint16_t voice[4]; float sample_rate; } mic1;

Здесь шаблон нельзя переиспользовать, так как у него нет имени.

Синтаксис 3: анонимная вложенная структура

struct test { struct { float f; char a; }; } test_var;

Доступ к внутренним членам напрямую:

test_var.f = 1.2f;

Анонимные структуры уменьшают вербальность, но используйте их с осторожностью для ясности.

Расположение в памяти для структуры

Стандарт C гарантирует, что члены расположены в памяти последовательно, в порядке объявления. Например:

struct Test2 { uint8_t c; uint32_t d; uint8_t e; uint16_t f; } MyStruct;

На 32-битной машине sizeof(MyStruct) = 12 байт из-за выравнивания, которое выравнивает uint32_t по 4-байтовой границе. Переупорядочивание членов может устранить выравнивание:

struct Test2 { uint32_t d; uint16_t f; uint8_t c; uint8_t e; } MyStruct;

Теперь sizeof(MyStruct) сокращается до 8 байт — ценная экономия в памяти-ограниченной прошивке.

Структуры в встроенном C: практическое руководство по определению, использованию и оптимизации памяти

Рисунок 3. Выравнивание данных может добавлять заполнение в память структуры.

Резюме

Изучите больше наших уроков по встроенному C здесь.

Встроенный

  1. Что такое рефрактерные металлы? Экспертный обзор их свойств и применений
  2. Палубные винты (Deck Screws): виды, преимущества и сравнение с деревянными винтами
  3. Пружинно-энергизированные уплотнения (spring-energized seals): конструкция, функция и промышленные преимущества
  4. Деревянные винты (Wood Screws): типы, особенности и советы по выбору
  5. Сплавы стали: типы, состав и применение
  6. Использование данных в Интернете надежности: стратегии эффективного управления
  7. Структуры данных в Java: основные классы и Collections Framework
  8. Промышленный интернет вещей (IIoT): определение, область и промышленное влияние
  9. Данные технического обслуживания: ключ к надежному управлению активами
  10. Современное столярное дело: тренды, технологии и техники