기술자료
[E2E 스레드] F28x의 16비트 주소 지정과 엔디안(Endian) 정리
TMS320C2000 에서 sizeof(Uint32)를 찍으면 4가 아니라 2가 나옵니다. - 당황하지 마세요.
1. ARM에서 넘어온 개발자가 가장 먼저 부딪히는 벽
F28x 코어에서 아래 코드를 실행하면:
printf("%d\n", sizeof(Uint32)); // 결과: 2 (?!)4가 아니라 2가 출력됩니다. 버그가 아닙니다. C28x는 메모리를 바이트(8비트)가 아니라 16비트 워드 단위로 주소지정하기 때문입니다. sizeof의 단위 자체가 "바이트"가 아니라 "워드(16비트)"입니다.
- sizeof(char) = 1 → 그런데 이 char가 16비트입니다
- sizeof(int16) = 1 워드
- sizeof(Uint32) = 2 워드
- 주소가 1 증가하면 16비트만큼 이동
통신 버퍼를 바이트 단위로 파싱하는 코드를 다른 MCU에서 그대로 가져오면 이 지점에서 반드시 문제가 생깁니다.
2. 32비트 데이터는 메모리에 어떻게 저장될까?
0x12345678을 저장하면:

하위 워드가 낮은 주소에 오는 리틀 엔디안 워드 순서입니다.
3. "빅 엔디안으로 바꾸는 레지스터는 없나요?" — 없습니다
모든 C28x 디바이스에는 엔디안을 전환하는 레지스터, 설정 비트, 컴파일러 지시문이 존재하지 않습니다. C28x는 리틀 엔디안으로 하드와이어드(hardwired)된 아키텍처입니다. 포인터 연산과 레지스터 레이아웃 전부가 이를 전제로 설계되어 있습니다.
4. 빅 엔디안 호스트와 통신해야 한다면: 경계에서 워드 스왑
빅 엔디안 시스템(일부 네트워크 프로토콜, 타사 호스트 컨트롤러)과 32비트 데이터를 주고받을 때는 통신 경계에서 소프트웨어로 변환합니다.
// 32비트 값의 상/하위 16비트 워드 순서 스왑
Uint32 swap_word_order(Uint32 val)
{
return (val >>16) | (val << 16);
}송신 직전·수신 직후에만 적용하고, 내부 연산은 네이티브 리틀 엔디안으로 유지하는 것이 원칙입니다. TI 공식 문서로는 SPRAD88A (Porting Applications to C2000 – Endianness)를 참고하세요.
5. 실무 체크리스트
1) memcpy 등으로 구조체를 통신 버퍼에 직행시키는 코드는 워드 크기·패킹 차이를 반드시 검증
2) CRC 계산 시 바이트 단위 알고리즘을 쓰면 워드 주소지정 때문에 결과가 달라질 수 있음 → 워드 단위 구현으로 수정
3) 상대 장비가 8비트 바이트 스트림(UART 등)이면 각 16비트 워드의 상/하위 바이트 추출 순서를 프로토콜 문서로 명문화
6. 핵심교훈
16비트 워드 주소지정은 버그가 아니라 DSP 혈통의 설계 철학입니다. "바이트"라는 가정이 숨어 있는 모든 코드(통신, CRC, 직렬화)는 이식 시 반드시 재검토해야 합니다.
원문(출처) : TI E2E커뮤니티 https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1666877/tms320f28377s-c28x-endianess
정리/번역: 싱크웍스 (본게시물)
| 번호 | 제목 | 작성자 | 날짜 |
|---|
- 1




