산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial Internet of Things >> 임베디드

C 언어 공용체 활용: 효율적인 데이터 패킹과 언패킹

C 언어 공용체를 이용한 효율적인 데이터 패킹과 언패킹

공용체는 동일한 바이트를 다른 데이터 타입으로 재해석하는 강력하고 메모리 효율적인 방법을 제공합니다. 원래는 상호 배타적인 변수 간의 공유 메모리를 위해 의도되었지만, 최신 C 프로그래머들은 직렬 프로토콜이나 저수준 통신 처리 시 데이터 패킹, 언패킹, 타입 펀닝을 위해 공용체를 자주 사용합니다.

공용체의 메모리 공유 방식

공용체의 모든 멤버는 동일한 메모리 영역을 공유합니다. 가장 큰 멤버가 공용체의 크기를 결정하며, 모든 멤버는 같은 주소에서 시작합니다.

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

여기서 word는 2바이트를 차지하고, 중첩 구조체는 이 2바이트를 byte1과 byte2로 분할합니다. 레이아웃은 다음과 같이 시각화할 수 있습니다:

C 언어 공용체 활용: 효율적인 데이터 패킹과 언패킹

두 바이트를 16비트 워드로 패킹

두 8비트 값 x와 y를 16비트 워드로 결합하려면 구조체 멤버에 할당한 후 word 멤버를 읽습니다:

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

이 '데이터 펀닝'은 간단하지만 프로세서의 바이트 순서에 의존합니다.

프로세서 엔디안이 중요하다

리틀 엔디안 시스템은 최하위 바이트를 먼저 저장하고, 빅 엔디안 시스템은 최상위 바이트를 먼저 저장합니다. 시퀀스 0x01020304를 고려해 보세요:

C 언어 공용체 활용: 효율적인 데이터 패킹과 언패킹

리틀 엔디안 머신에서 간단한 테스트를 실행하면:

#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 — 리틀 엔디안 저장임을 확인합니다. 빅 엔디안 타겟에서 같은 코드는 0X2143을 출력합니다.

비트 연산 대안: 엔디안 독립적 패킹

시프트와 마스킹은 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; }

빅 엔디안 프로세서: Word1 is: 0X2143, Word2 is: 0X2143. 리틀 엔디안 프로세서: Word1 is: 0X4321, Word2 is: 0X2143. 비트 연산 접근 방식은 아키텍처 간 일관된 결과를 보장합니다.

실전 예제: UART로 float 전송

직렬 링크는 일반적으로 한 번에 한 바이트씩 전송합니다. 32비트 float를 전송하기 위해 공용체를 사용하여 float를 4바이트 배열로 볼 수 있습니다:

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) { // UART로 tx.byte[i] 전송 rx.byte[i] = tx.byte[i]; // 시뮬레이션 수신 } printf("The received data is: %f\n", rx.f); 

출력: The received data is: 5.500000. 공용체는 바이트 표현과 부동소수점 값을 깔끔하게 분리하여 코드를 읽기 쉽고 유지보수하기 쉽게 만듭니다.

C 언어 공용체 활용: 효율적인 데이터 패킹과 언패킹

핵심 요약

C, 공용체, 임베디드 시스템에 대해 더 알아보려면 전체 기사 목록을 둘러보세요.

임베디드

  1. Nucleus RTOS의 세마포어: 유틸리티 서비스 및 데이터 구조
  2. 미 육군, 혁신적 센서와 예측 분석으로 상태기반 정비(CBM) 진전
  3. IIoT와 데이터 분석이 EHS를 혁신하다: 안전, 효율성, 비용 절감 증대
  4. 책임감 있고 신뢰할 수 있는 AI 구축: 설명가능성, 책임성, 윤리 가이드
  5. 포그 컴퓨팅 설명: IoT 데이터 흐름 혁신과 클라우드 부하 감소
  6. C 공용체(Union) 완전 이해: 메모리 공유, 타입 펀칭, 실전 활용
  7. 공급망 가시성 확보: 데이터와 컨텍스트의 결정적 역할
  8. 플릿 관리 혁신: 더 스마트한 운영을 위한 AI와 IoT 통합
  9. 산업용 AIoT: AI와 IoT 융합으로 인더스트리 4.0 혁신 주도
  10. 리트머스(Litmus)와 오덴(Oden), 스마트 제조 위한 통합 IIoT 솔루션 출시