Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial Internet of Things >> Integrado

Usando Uniões em C para Empacotamento e Desempacotamento Eficiente de Dados

Usando Uniões em C para Empacotamento e Desempacotamento Eficiente de Dados

Uniões fornecem uma maneira poderosa e eficiente em memória de reinterpretar os mesmos bytes como diferentes tipos de dados. Embora originalmente destinadas a memória compartilhada entre variáveis mutuamente exclusivas, programadores C modernos frequentemente usam uniões para empacotamento, desempacotamento e type punning – especialmente ao lidar com protocolos seriais ou comunicação de baixo nível.

Como uma União Compartilha Memória

Todos os membros de uma união compartilham a mesma região de memória. O maior membro determina o tamanho da união, e cada membro começa no mesmo endereço.

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

Aqui, word ocupa dois bytes, enquanto a estrutura aninhada divide esses dois bytes em byte1 e byte2. O layout pode ser visualizado como:

Usando Uniões em C para Empacotamento e Desempacotamento Eficiente de Dados

Empacotando Dois Bytes em uma Palavra de 16 bits

Para combinar dois valores de 8 bits x e y em uma palavra de 16 bits, atribua-os aos membros da estrutura e então leia o membro word:

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

Este "type punning" é direto, mas depende da ordem de bytes do processador.

Endianness do Processador Importa

Sistemas little-endian armazenam o byte menos significativo primeiro, enquanto sistemas big-endian armazenam o byte mais significativo primeiro. Considere a sequência 0x01020304:

Usando Uniões em C para Empacotamento e Desempacotamento Eficiente de Dados

Executar um teste simples em uma máquina little-endian resulta em:

#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; }

Saída: Word is: 0X4321 – confirmando armazenamento little-endian. Em um alvo big-endian, o mesmo código produziria 0X2143.

Alternativa Bitwise: Empacotamento Independente de Endianness

Deslocamento e máscara fornecem uma maneira portátil de construir um valor de 16 bits:

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

Comparando ambos os métodos:

#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; }

Em um processador big-endian: Word1 is: 0X2143, Word2 is: 0X2143. Em um processador little-endian: Word1 is: 0X4321, Word2 is: 0X2143. A abordagem bitwise garante resultados consistentes entre arquiteturas.

Exemplo Prático: Enviando um Float via UART

Links seriais normalmente transmitem um byte por vez. Para enviar um float de 32 bits, podemos usar uma união para visualizar o float como um array de quatro bytes:

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

Lado transmissor:

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); 

Saída: The received data is: 5.500000. A união separa limpa a representação em bytes do valor de ponto flutuante, tornando o código legível e de fácil manutenção.

Usando Uniões em C para Empacotamento e Desempacotamento Eficiente de Dados

Principais Conclusões

Para explorar mais sobre C, uniões e sistemas embarcados, navegue pela minha lista completa de artigos.

Integrado

  1. Semáforos no Nucleus RTOS: Serviços Utilitários e Estruturas de Dados
  2. Exército dos EUA Avança em Manutenção Baseada em Condição com Sensores Inovadores e Análise Preditiva
  3. Como IIoT e Análise de Dados Transformam EHS: Aumentando Segurança, Eficiência e Economia
  4. Construindo IA Responsável e Confiável: Guia para Explicabilidade, Responsabilidade e Ética
  5. Fog Computing Explicado: Transformando o Fluxo de Dados IoT e Reduzindo Carga na Nuvem
  6. Uniões em C Explicadas: Gerenciamento Eficiente de Memória para Múltiplos Tipos de Dados
  7. Visibilidade da Cadeia de Suprimentos: O Papel Crucial de Dados e Contexto
  8. Revolucionando a Gestão de Frotas: Integração de IA e IoT para Operações Mais Inteligentes
  9. AIoT Industrial: Unindo IA e IoT para Impulsionar a Inovação da Indústria 4.0
  10. Litmus e Oden Lançam Soluções IIoT Integradas para Manufatura Inteligente