19.2.1.2. 스칼라(Scalar) 타입(`uint8`, `float32` 등)과 배열(Array) 선언 규칙

19.2.1.2. 스칼라(Scalar) 타입(uint8, float32 등)과 배열(Array) 선언 규칙

시스템 메시지 최상단의 uint64 timestamp 절대 앵커 뼈대 타설이 무사히 완료되었다면, 이제 그 밑바닥의 빈 공간에는 본격적으로 당신이 시스템망에 전송하고 흩뿌리고자 하는 순수 비즈니스 페이로드(Payload) 로우 데이터들을 채워 넣을 차례이다. 하지만 이 공간은 메모리가 무한정 뻗어 나가는 자바(Java)의 가비지 컬렉터(GC)나 뇌를 빼고 코딩하는 파이썬(Python) 객체 인스턴스의 자유로운 세상이 아니다. 이곳은 철저하게 단 1바이트(Byte) 단위로 쪼개져 계산되고, C++ 원시 구조체로 압축 패킹(Packing)될 임베디드 코어의 그라운드 제로(Ground Zero)이다.

PX4 툴체인의 genmsg 파서는 픽스호크 보드 칩셋의 캐시 레지스터 병목 오버헤드 방지와 시스템 런타임 힙(Heap) 메모리 단편화(Fragmentation) 참사를 원천 차단하기 위해, 우리가 이곳에 타이핑해 사용할 수 있는 스칼라 변수 타입의 종류와 텍스트 열거 방식을 극도의 잔혹한 철권통치로 제한한다.

1. 지원되는 고정폭 스칼라(Scalar) 타입 메트릭스의 강제성

PX4 커스텀 메시지 문법에서는 C/C++ 아키텍처 세계에서 은근슬쩍 넘어가는 애매모호한 intlong 같은 타깃 플랫폼 종속적(Platform Dependent) 모호한 크기 타입을 절대 용서하지 않고 허용조차 하지 않는다. 오직 메모리 컴파일 크기가 명확하고 강하게 고정된(Fixed-width) POSIX 표준형 타입 변수만을 선언할 수 있다.

  • 논리형 지시자: bool (정확히 1바이트 공간 점유)
  • 절대 정수형 (Signed / Unsigned): int8, uint8, int16, uint16, int32, uint32, int64, uint64
  • 물리 실수형 (부동소수점): float32 (단정밀도), float64 (배정밀도). 참고로 픽스호크 MCU의 FPU 하드웨어 부하 오버헤드가 극심하므로 float64 사용은 코어 아키텍처 상 극도로 엄격하게 지양 및 경계 대상이다.
# 스칼라 선언 합법적 문법 예시
uint8   sensor_id      # 고작 1바이트를 차지하는 경량 ID 식별자
float32 temperature    # 4바이트 단정밀도로 계산되는 센서 물리 데이터

2. 가변 배열(Dynamic Array)의 철저한 처형과 고정 배열(Fixed Array)의 강요

현대 응용 C++ 프로그래머들이 너무나도 사랑하고 무심코 즐겨 쓰는 동적 가변 크기 배열 객체인 std::vector나, 동적으로 malloc/new 사이즈가 할당된 포인터(*) 배열 구조는, uORB 마이크로 메시지 생태계 내에서는 **가장 끔찍하고 혐오스러운 당장 사형에 처할 최악의 안티 패턴(Anti-pattern)**으로 간주된다.
uORB 파일 디스크립터 시스템을 이루는 코어 링 버퍼는, 통신할 개별 메시지의 단일 메모리 사이즈가 컴파일 타임(Compile-time) 수준에 sizeof(struct) 연산자로 한 치의 오차나 요동치지 않고 완벽하게 고정(Static Allocation)되어 있어야지만, VFS 커널 단에서 무지성 C memcpy() 함수만을 동원하여 메모리를 복사할 때 어떠한 버퍼 오버플로우나 힙 파편화(Splinter) 공격 없이 초고속으로 데이터를 수백 명의 구독자에게 퍼 나를 수 있기 때문이다.

따라서 배열 데이터를 선언할 때는 반드시 억세스가 닫혀 있고 폭발하지 않는 “정적 고정 크기(Fixed Size)” 숫자로만 문법을 타설해야 한다.

# [파멸의 예시] 동적 크기 할당 (PX4 genmsg 파서가 즉각 빌드를 폭파시킴)
# float32[] dynamic_data 

# [생존의 예시] 시스템 규칙에 승복하여 엄격하게 크기가 고정 타설된 정적 배열
float32[3] accel_xyz   # 정확히 12바이트(4바이트 x 3칸)가 물리 할당되는 X,Y,Z 3차원 가속도 배열 묶음
uint8[128] raw_buffer  # 데이터 손실 없이 128바이트의 공간만을 정확히 보장하는 연속형 바이트 덩어리 버퍼망

3. 코어 해커들의 은밀한 패딩(Byte Padding) 정렬 최적화 이슈 극복

천재적인 genmsg 파이썬 컴파일러는 위에서 정의된 텍스트 변수 줄들을 파싱하여 핏빛 C++ 구조체를 하단에 찍어낼 때, 알아서 빈 공간에 더미 패딩(Padding) 위치를 덧대어 폰 노이만 아키텍처의 CPU가 가장 읽기 쉬운 구조로 구조체를 자동 정렬(Alignment)해 준다.
하지만 진정으로 극한의 최적화를 쫓는 코어 아키텍트라면, 시스템 컴파일러가 빈 바이트 쓰레기 더미 패딩 공간을 삽입하며 아까운 RAM을 낭비하지 않도록, 구조체 안의 변수 텍스트 줄 자체를 데이터 크기가 가장 육중한 놈(예: uint64)부터 가벼운 놈(예: uint8, bool) 순서로 위에서 아래 피라미드식으로 정렬 배치하는 내림차순 데이터 선언(Descending Declaration) 팁을 의도적으로 눈치껏 구사한다.

# 아키텍처적으로 극한의 아름다운 바이트 정렬 예시 (Padding 메모리 낭비 제로화)
uint64 timestamp             # 8 Bytes
float32[3] angular_velocity  # 4x3 = 12 Bytes
int32 attitude_error         # 4 Bytes
uint16 read_count            # 2 Bytes
uint8 hw_status              # 1 Byte
bool is_data_valid           # 1 Byte

이 가혹하고 파시스터적인 msg 선언 규칙들을 절대로 어기지 않고 당신의 데이터를 블록처럼 우아하게 레고 조립해 낼 수 있다면, 당신의 커스텀 메시지 .msg 텍스트 스크립트는 툴체인 상에서 단 한 줄의 붉은 파싱 에러 도배 굴욕 없이, 터미널 타격 즉시 무결점의 빛나는 C++ 구조체 헤더 덩어리로 기적처럼 컴파일 변환을 마칠 것이다.