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

Использование объединений в C для эффективной упаковки и распаковки данных

Использование объединений в C для эффективной упаковки и распаковки данных

Объединения предоставляют мощный, экономный по памяти способ переинтерпретировать одни и те же байты как разные типы данных. Изначально предназначенные для совместного использования памяти между взаимоисключающими переменными, в современном C объединения часто применяют для упаковки, распаковки и type punning — особенно при работе с последовательными протоколами или низкоуровневым обменом данными.

Как объединение разделяют память

Все члены объединения разделяют одну область памяти. Размер объединения определяется самым большим членом, и каждый член начинается по одному адресу.

union { uint16_t word; struct { uint8_t byte1; uint8_t byte2; }; } u1;

Здесь word занимает два байта, а вложенная структура разбивает их на byte1 и byte2. Расположение можно представить так:

Использование объединений в C для эффективной упаковки и распаковки данных

Упаковка двух байт в 16-битное слово

Чтобы объединить два 8-битных значения x и y в 16-битное слово, присвойте их членам структуры, а затем прочитайте член word:

u1.byte1 = y; u1.byte2 = x; uint16_t packed = u1.word;

Такой «type punning» прост, но зависит от порядка байтов процессора.

Порядок байтов (endianness) имеет значение

В little-endian системах младший байт хранится первым, в big-endian — старший. Рассмотрим последовательность 0x01020304:

Использование объединений в C для эффективной упаковки и распаковки данных

Простой тест на little-endian машине дает:

#include <stdio.h> #include <stdint.h> int main() { union { struct { uint8_t byte1; uint8_t byte2; }; uint16_t word; } u1; u1.byte1 = 0x21; u1.byte2 = 0x43; printf("Word is: %#X\n", u1.word); return 0; }

Вывод: Word is: 0X4321 — подтверждает little-endian. На big-endian том же код выдал бы 0X2143.

Битовая альтернатива: упаковка, независимая от endianness

Сдвиги и маски дают переносимый способ построить 16-битное значение:

uint16_t word2 = (((uint16_t)byte3) << 8) | ((uint16_t)byte4);

Сравнение обоих методов:

#include <stdio.h> #include <stdint.h> int main() { union { struct { uint8_t byte1; uint8_t byte2; }; uint16_t word1; } u1; u1.byte1 = 0x21; u1.byte2 = 0x43; printf("Word1 is: %#X\n", u1.word1); uint8_t byte3 = 0x21, byte4 = 0x43; uint16_t word2 = (((uint16_t)byte3) << 8) | ((uint16_t)byte4); printf("Word2 is: %#X\n", word2); return 0; }

На big-endian: Word1 is: 0X2143, Word2 is: 0X2143. На little-endian: Word1 is: 0X4321, Word2 is: 0X2143. Битовый подход гарантирует одинаковый результат на любой архитектуре.

Практический пример: передача float по UART

Последовательные линии передают по одному байту. Чтобы отправить 32-битный float, можно использовать объединение, чтобы представить float как массив из четырех байт:

union buffer { float f; struct { uint8_t byte[4]; }; };

Передающая сторона:

union buffer tx; union buffer rx; float f1 = 5.5f; tx.f = f1; for (int i = 0; i < 4; ++i) { // send tx.byte[i] over UART rx.byte[i] = tx.byte[i]; // Simulated receive } printf("The received data is: %f\n", rx.f); 

Вывод: The received data is: 5.500000. Объединение чисто разделяет байтовое представление и значение с плавающей точкой, делая код читаемым и поддерживаемым.

Использование объединений в C для эффективной упаковки и распаковки данных

Выводы

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

Встроенный

  1. Семафоры в Nucleus RTOS: Утилитарные сервисы и структуры данных
  2. Армия США развивает состояние-ориентированное обслуживание с инновационными датчиками и предиктивной анали…
  3. Как IIoT и аналитика данных трансформируют EHS: повышение безопасности, эффективности и экономии
  4. Создание ответственного и надежного AI: руководство по объяснимости, подотчетности и этике
  5. Fog Computing: трансформация потока данных IoT и снижение нагрузки на облако
  6. Объединения в C (union): эффективное использование памяти для разных типов данных
  7. Раскрытие видимости цепочки поставок: решающая роль данных и контекста
  8. Революция в управлении автопарками: интеграция ИИ и IoT для более умных операций
  9. Промышленный AIoT: слияние ИИ и IoT для инноваций Индустрии 4.0
  10. Litmus и Oden запускают интегрированные IIoT решения для Smart Manufacturing