TI의 C2000 Delfino 시리즈 32비트 마이크로컨트롤러(TMS320F28377D)는 모터 제어, 전력 변환, 실시간 제어 애플리케이션에 최적화되어 있습니다. CMD 파일(Linker Command File)은 Code Composer Studio(CCS)에서 프로젝트 빌드 시 메모리 할당과 섹션 배치를 제어하는 핵심 파일입니다. 이 문서는 CMD 파일의 역할, 구조, 작성 방법, 실용적인 예제를 상세히 설명하여 초보자와 숙련자 모두가 C2000 메모리 관리를 효과적으로 수행할 수 있도록 돕습니다.
1. CMD 파일 개요
CMD 파일은 TI의 링커가 소스 코드와 오브젝트 파일을 결합하여 실행 가능한 이미지(.out)를 생성할 때 사용하는 스크립트 파일입니다. TMS320F28377D는 복잡한 메모리 구조를 가지므로, CMD 파일은 메모리 맵 정의와 코드/데이터 배치를 위해 필수적입니다.
1.1 CMD 파일의 역할
- 메모리 정의: 디바이스의 물리적 메모리(Flash, RAM, OTP 등)를 주소와 크기로 정의.
- 섹션 배치: 컴파일러가 생성한 섹션(.text, .data, .bss 등)을 메모리 영역에 매핑.
- 링크 제어: 스택/힙 크기, 엔트리 포인트, 초기화 루틴 지정.
- 특수 섹션 처리: Flash API, IQmath, CLA(Control Law Accelerator)용 섹션 관리.
- 디버깅 지원: 메모리 배치를 명확히 하여 CCS에서 메모리 상태 확인.
1.2 TMS320F28377D 메모리 구조
TMS320F28377D의 메모리 구조는 CMD 파일 작성의 기반입니다. 주요 메모리 영역은 다음과 같습니다:
- Flash:
- 크기: 1024KB (512K x 16)
- 주소: 0x080000 ~ 0x0FFFFF
- 용도: 프로그램 코드, 상수, Flash API 저장.
- RAM:
- M0 RAM: 1.9KB (0x000080 ~ 0x0007FF), CPU1/CPU2 공용, 스택/데이터.
- M1 RAM: 2KB (0x000800 ~ 0x000FFF), CPU1/CPU2 공용, 스택/데이터.
- LS0~LS5 RAM: 각 4KB (0x008000 ~ 0x00BFFF), 로컬 공유 RAM, 코드/데이터.
- GS0~GS15 RAM: 각 4KB (0x00C000 ~ 0x01FFFF), 글로벌 공유 RAM, 데이터/버퍼.
- Boot ROM:
- 크기: 32KB (0x3F8000 ~ 0x3FFFFF)
- 용도: 부트로더, 기본 루틴, 읽기 전용.
- OTP (One-Time Programmable):
- 크기: 1KB (0x078000 ~ 0x0783FF)
- 용도: 보안 설정(DCSM), 캘리브레이션 데이터, 읽기 전용.
- CLA RAM:
- CLAL0RAM: CLA 프로그램용, 1KB (RAMLS0 공유, 0x008000).
- CLAMSGxRAM: CLA 데이터/메시지용, 1KB (0x001480 ~ 0x00187F).
- Peripheral Registers:
- 주소: 0x000000 ~ 0x007FFF
- 용도: 주변 장치 제어 레지스터.
- Reset Vector:
- 주소: 0x3FFFC0 ~ 0x3FFFC1
- 용도: 부트 시 프로그램 시작 지점.
1.3 CMD 파일의 중요성
- 정확한 메모리 관리: 잘못된 배치는 런타임 오류나 비효율적 실행 초래.
- 성능 최적화: 자주 실행되는 코드를 RAM에 배치하여 속도 향상.
- 프로덕션 대비: Flash 기반 CMD는 배포용, RAM 기반 CMD는 디버깅용.
- CLA 및 Flash API 지원: 고급 기능 활용 시 특수 섹션 정의 필요.
2. CMD 파일의 구조
CMD 파일은 두 가지 주요 섹션으로 구성됩니다:
- MEMORY 섹션: 디바이스의 물리적 메모리 영역 정의.
- SECTIONS 섹션: 코드 및 데이터 섹션을 메모리 영역에 매핑.
2.1 MEMORY 섹션
MEMORY 섹션은 디바이스의 메모리 영역을 정의합니다. 각 영역은 이름, 시작 주소, 크기, 속성을 지정합니다.
구문:
MEMORY
{
NAME : origin = ADDRESS, length = SIZE, attr = [R|W|X]
}
- NAME: 메모리 영역의 고유 이름 (예: FLASH, RAMM0).
- origin: 시작 주소 (16진수).
- length: 메모리 크기 (16진수, 워드 단위).
- attr: 속성 (R: 읽기, W: 쓰기, X: 실행 가능).
2.2 SECTIONS 섹션
SECTIONS 섹션은 컴파일러가 생성한 섹션(.text, .data 등)을 메모리 영역에 매핑합니다.
구문:
SECTIONS
{
.SECTION_NAME :> MEMORY_NAME
}
- .SECTION_NAME: 컴파일러 섹션 이름 (예: .text, .data).
- MEMORY_NAME: MEMORY 섹션에서 정의한 메모리 영역.
주요 섹션:
- .text: 실행 가능한 코드.
- .data: 초기화된 전역/정적 변수.
- .bss: 초기화되지 않은 전역/정적 변수.
- .const: 읽기 전용 상수.
- .econst: C2000 전용 읽기 전용 상수.
- .ebss: C2000 전용 초기화되지 않은 변수.
- .stack: 스택 메모리.
- .cinit: C 초기화 테이블.
- .pinit: C++ 초기화 테이블.
- .switch: 스위치 문 테이블.
- codestart: 프로그램 시작 지점.
- ramfuncs: Flash에서 로드되고 RAM에서 실행되는 함수.
- Fapi_Flash: Flash API 함수.
- .Cla1Prog: CLA 프로그램 코드.
- Cla1DataRam: CLA 데이터.
2.3 고급 기능
- LOAD/RUN 분리: 섹션을 Flash에서 로드하고 RAM에서 실행.
- LOAD_START, LOAD_SIZE, RUN_START: 복사 프로세스 심볼 정의.
- table(RAM): 복사 테이블 생성.
- 스택/힙 설정:
--stack_size=0x400 /* 1KB 스택 */ --heap_size=0x200 /* 512B 힙 */
- 엔트리 포인트:
--entry_point=code_start
3. CMD 파일 작성 절차
- 디바이스 메모리 맵 확인:
- 레퍼런스 매뉴얼(SPRUI25) 또는 C2000Ware(device_support\f2837xd)에서 주소와 크기 확인.
- MEMORY 섹션 작성:
- Flash, RAM, OTP, CLA RAM 등의 주소와 크기 정의.
- 실행 코드와 데이터 구분.
- SECTIONS 섹션 작성:
- 코드(.text, .const)는 Flash 또는 RAMLSx.
- 데이터(.data, .bss)는 RAMLSx 또는 RAMGSx.
- 스택(.stack)은 RAMM0/M1.
- 특수 섹션 처리:
- ramfuncs: Flash LOAD, RAM RUN.
- Fapi_Flash: Flash API.
- .Cla1Prog, Cla1DataRam: CLA 프로그램/데이터.
- 링커 옵션 설정:
- 스택/힙 크기, 엔트리 포인트 지정.
- 검증 및 디버깅:
- .map 파일로 섹션 배치 확인.
- CCS Memory Browser로 메모리 상태 점검.
4. CMD 파일 작성 고려사항
- 메모리 최적화: 코드(RAMLSx), 상수(Flash), CLA(CLAL0RAM, CLAMSGxRAM).
- 스택/힙: 기본 스택 1KB(0x400), 동적 할당 시 힙 조정.
- Flash 프로그래밍: Fapi_Flash 섹션 추가, 부트 시 RAM 복사.
- 보안 및 OTP: OTP는 DCSM 및 캘리브레이션 데이터, 읽기 전용.
- 디버깅 vs. 프로덕션: RAM(디버깅), Flash(배포).
- C2000Ware: C:\ti\c2000\C2000Ware_6_00_00_00\device_support\f2837xd\linker_cmd 활용.
5. 실용적인 CMD 파일 예제
5.1 예제 1: 기본 Flash 기반 CMD 파일
/* File: 2837xD_FLASH_lnk_cpu1.cmd */
/* Description: TMS320F28377D Flash 기반 기본 CMD 파일 */
/* Compiler: Code Composer Studio (TI C2000 Compiler) */
/* Target: TMS320F28377D */
/* 링커 옵션 설정 */
--stack_size=0x400 /* 스택 크기: 1KB, 함수 호출 및 로컬 변수 저장 */
--heap_size=0x200 /* 힙 크기: 512B, 동적 메모리 할당 */
--entry_point=code_start /* 프로그램 시작 지점: 부트 시 실행 시작 주소 */
/* MEMORY 섹션: 디바이스의 물리적 메모리 정의 */
MEMORY
{
/* 리셋 벡터: 부트 시 CPU가 시작하는 주소 */
RESET : origin = 0x3FFFC0, length = 0x000002
/* Flash: 프로그램 코드 및 상수 저장, 1024KB */
FLASH : origin = 0x080000, length = 0x080000 /* 1024KB */
/* RAMM0: 공용 RAM, 스택/데이터, 1.9KB */
RAMM0 : origin = 0x000080, length = 0x000780 /* 1.9KB */
/* RAMM1: 공용 RAM, 스택/데이터, 2KB */
RAMM1 : origin = 0x000800, length = 0x000800 /* 2KB */
/* RAMLS0: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS0 : origin = 0x008000, length = 0x001000 /* 4KB */
/* RAMLS1: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS1 : origin = 0x009000, length = 0x001000 /* 4KB */
/* RAMGS0: 글로벌 공유 RAM, 데이터/버퍼, 4KB */
RAMGS0 : origin = 0x00C000, length = 0x001000 /* 4KB */
/* Boot ROM: 부트로더 및 기본 루틴, 읽기 전용, 32KB */
BOOTROM : origin = 0x3F8000, length = 0x008000 /* 32KB */
/* OTP: 보안 설정 및 캘리브레이션 데이터, 읽기 전용, 1KB */
OTP : origin = 0x078000, length = 0x000400 /* 1KB */
}
/* SECTIONS 섹션: 컴파일러 섹션을 메모리 영역에 매핑 */
SECTIONS
{
/* codestart: 부트 시 시작 코드 */
codestart :> FLASH
/* .text: 실행 가능한 프로그램 코드 */
.text :> FLASH
/* .cinit: C 초기화 테이블 */
.cinit :> FLASH
/* .pinit: C++ 초기화 테이블 */
.pinit :> FLASH
/* .switch: 스위치 문 테이블 */
.switch :> FLASH
/* .const: 읽기 전용 상수 */
.const :> FLASH
/* .data: 초기화된 전역/정적 변수 */
.data :> RAMLS0
/* .bss: 초기화되지 않은 전역/정적 변수 */
.bss :> RAMLS0
/* .ebss: C2000 전용 초기화되지 않은 변수 */
.ebss :> RAMLS0
/* .econst: C2000 전용 읽기 전용 상수 */
.econst :> RAMLS0
/* .stack: 함수 호출 및 로컬 변수용 스택 */
.stack :> RAMM0
/* ramfuncs: Flash에서 로드, RAMLS1에서 실행, 속도 최적화 */
ramfuncs : LOAD = FLASH,
RUN = RAMLS1,
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
RUN_START(_RamfuncsRunStart)
table(RAM) /* 부트 시 복사 테이블 */
}
설명:
- 목적: 기본 Flash 기반 애플리케이션 (예: 모터 제어).
- 메모리 배치:
- 코드(.text, .const 등)는 Flash에 저장하여 저장 공간 절약.
- 데이터(.data, .bss 등)는 RAMLS0에 배치하여 빠른 액세스.
- 스택은 RAMM0에 배치하여 안정적 함수 호출 보장.
- ramfuncs는 Flash에서 로드되고 RAMLS1에서 실행되어 실행 속도 최적화.
- 특징: 부트 시 ramfuncs를 RAM으로 복사하여 속도 향상. 스택 1KB, 힙 512B로 표준 설정.
5.2 예제 2: RAM 기반 CMD 파일 (디버깅용)
/* File: 2837xD_RAM_lnk_cpu1.cmd */
/* Description: TMS320F28377D RAM 기반 디버깅용 CMD 파일 */
/* Compiler: Code Composer Studio (TI C2000 Compiler) */
/* Target: TMS320F28377D */
/* 링커 옵션 설정 */
--stack_size=0x400 /* 스택 크기: 1KB, 함수 호출 및 로컬 변수 저장 */
--heap_size=0x200 /* 힙 크기: 512B, 동적 메모리 할당 */
--entry_point=code_start /* 프로그램 시작 지점: 부트 시 실행 시작 주소 */
/* MEMORY 섹션: 디바이스의 물리적 메모리 정의, 디버깅용 RAM만 포함 */
MEMORY
{
/* 리셋 벡터: 부트 시 CPU가 시작하는 주소 */
RESET : origin = 0x3FFFC0, length = 0x000002
/* RAMM0: 공용 RAM, 스택/데이터, 1.9KB */
RAMM0 : origin = 0x000080, length = 0x000780 /* 1.9KB */
/* RAMM1: 공용 RAM, 스택/데이터, 2KB */
RAMM1 : origin = 0x000800, length = 0x000800 /* 2KB */
/* RAMLS0: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS0 : origin = 0x008000, length = 0x001000 /* 4KB */
/* RAMLS1: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS1 : origin = 0x009000, length = 0x001000 /* 4KB */
/* RAMGS0: 글로벌 공유 RAM, 데이터/버퍼, 4KB */
RAMGS0 : origin = 0x00C000, length = 0x001000 /* 4KB */
}
/* SECTIONS 섹션: 컴파일러 섹션을 메모리 영역에 매핑 */
SECTIONS
{
/* codestart: 부트 시 시작 코드 */
codestart :> RAMLS0
/* .text: 실행 가능한 프로그램 코드 */
.text :> RAMLS0
/* .cinit: C 초기화 테이블 */
.cinit :> RAMLS0
/* .pinit: C++ 초기화 테이블 */
.pinit :> RAMLS0
/* .switch: 스위치 문 테이블 */
.switch :> RAMLS0
/* .const: 읽기 전용 상수 */
.const :> RAMLS0
/* .data: 초기화된 전역/정적 변수 */
.data :> RAMLS1
/* .bss: 초기화되지 않은 전역/정적 변수 */
.bss :> RAMLS1
/* .ebss: C2000 전용 초기화되지 않은 변수 */
.ebss :> RAMLS1
/* .econst: C2000 전용 읽기 전용 상수 */
.econst :> RAMLS1
/* .stack: 함수 호출 및 로컬 변수용 스택 */
.stack :> RAMM0
}
설명:
- 목적: 디버깅 시 빠른 코드 실행을 위한 RAM 기반 설정.
- 메모리 배치:
- 모든 코드와 데이터는 RAMLS0과 RAMLS1에 배치하여 빠른 빌드/테스트.
- 스택은 RAMM0에 배치.
- 특징: Flash 사용 제외로 디버깅 속도 향상. 프로덕션 환경에서는 Flash 기반 CMD로 전환 필요.
5.3 예제 3: CLA 및 Flash API 포함 CMD 파일
/* File: 2837xD_CLA_Flash_lnk_cpu1.cmd */
/* Description: TMS320F28377D CLA 및 Flash API 포함 CMD 파일 */
/* Compiler: Code Composer Studio (TI C2000 Compiler) */
/* Target: TMS320F28377D */
/* 링커 옵션 설정 */
--stack_size=0x400 /* 스택 크기: 1KB, 함수 호출 및 로컬 변수 저장 */
--heap_size=0x200 /* 힙 크기: 512B, 동적 메모리 할당 */
--entry_point=code_start /* 프로그램 시작 지점: 부트 시 실행 시작 주소 */
/* MEMORY 섹션: 디바이스의 물리적 메모리 정의, CLA 포함 */
MEMORY
{
/* 리셋 벡터: 부트 시 CPU가 시작하는 주소 */
RESET : origin = 0x3FFFC0, length = 0x000002
/* Flash: 프로그램 코드 및 상수 저장, 1024KB */
FLASH : origin = 0x080000, length = 0x080000 /* 1024KB */
/* RAMM0: 공용 RAM, 스택/데이터, 1.9KB */
RAMM0 : origin = 0x000080, length = 0x000780 /* 1.9KB */
/* RAMM1: 공용 RAM, 스택/데이터, 2KB */
RAMM1 : origin = 0x000800, length = 0x000800 /* 2KB */
/* RAMLS0: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS0 : origin = 0x008000, length = 0x001000 /* 4KB */
/* RAMLS1: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS1 : origin = 0x009000, length = 0x001000 /* 4KB */
/* RAMGS0: 글로벌 공유 RAM, 데이터/버퍼, 4KB */
RAMGS0 : origin = 0x00C000, length = 0x001000 /* 4KB */
/* CLAL0RAM: CLA 프로그램용, RAMLS0 공유, 1KB */
CLAL0RAM : origin = 0x008000, length = 0x000400 /* 1KB */
/* CLAMSGxRAM: CLA 데이터/메시지용, 1KB */
CLAMSGxRAM : origin = 0x001480, length = 0x000400 /* 1KB */
}
/* SECTIONS 섹션: 컴파일러 섹션을 메모리 영역에 매핑 */
SECTIONS
{
/* codestart: 부트 시 시작 코드 */
codestart :> FLASH
/* .text: 실행 가능한 프로그램 코드 */
.text :> FLASH
/* .cinit: C 초기화 테이블 */
.cinit :> FLASH
/* .pinit: C++ 초기화 테이블 */
.pinit :> FLASH
/* .switch: 스위치 문 테이블 */
.switch :> FLASH
/* .const: 읽기 전용 상수 */
.const :> FLASH
/* .data: 초기화된 전역/정적 변수 */
.data :> RAMLS0
/* .bss: 초기화되지 않은 전역/정적 변수 */
.bss :> RAMLS0
/* .ebss: C2000 전용 초기화되지 않은 변수 */
.ebss :> RAMLS0
/* .econst: C2000 전용 읽기 전용 상수 */
.econst :> RAMLS0
/* .stack: 함수 호출 및 로컬 변수용 스택 */
.stack :> RAMM0
/* Fapi_Flash: Flash API 함수 저장 */
Fapi_Flash :> FLASH
/* .Cla1Prog: CLA 프로그램 코드, Flash에서 로드, CLAL0RAM에서 실행 */
.Cla1Prog : LOAD = FLASH,
RUN = CLAL0RAM,
LOAD_START(_Cla1ProgLoadStart),
LOAD_SIZE(_Cla1ProgLoadSize),
RUN_START(_Cla1ProgRunStart)
table(RAM) /* 부트 시 복사 테이블 */
/* Cla1DataRam: CLA 데이터 저장 */
Cla1DataRam :> CLAMSGxRAM
}
설명:
- 목적: CLA와 Flash API를 사용하는 고급 애플리케이션 (예: 고속 연산).
- 메모리 배치:
- 코드와 상수는 Flash에 배치.
- CLA 프로그램은 Flash에서 로드, CLAL0RAM에서 실행.
- CLA 데이터는 CLAMSGxRAM에 배치.
- Flash API는 Flash에 저장.
- 특징: CLA를 활용한 고속 연산, Flash 프로그래밍 지원.
5.4 예제 4: IQmath 및 대용량 데이터 처리 CMD 파일
/* File: 2837xD_IQmath_lnk_cpu1.cmd */
/* Description: TMS320F28377D IQmath 및 대용량 데이터 처리 CMD 파일 */
/* Compiler: Code Composer Studio (TI C2000 Compiler) */
/* Target: TMS320F28377D */
/* 링커 옵션 설정 */
--stack_size=0x600 /* 스택 크기: 1.5KB, 복잡한 연산용 증가 */
--heap_size=0x400 /* 힙 크기: 1KB, 동적 메모리 할당 증가 */
--entry_point=code_start /* 프로그램 시작 지점: 부트 시 실행 시작 주소 */
/* MEMORY 섹션: 디바이스의 물리적 메모리 정의 */
MEMORY
{
/* 리셋 벡터: 부트 시 CPU가 시작하는 주소 */
RESET : origin = 0x3FFFC0, length = 0x000002
/* Flash: 프로그램 코드 및 상수 저장, 1024KB */
FLASH : origin = 0x080000, length = 0x080000 /* 1024KB */
/* RAMM0: 공용 RAM, 스택/데이터, 1.9KB */
RAMM0 : origin = 0x000080, length = 0x000780 /* 1.9KB */
/* RAMM1: 공용 RAM, 스택/데이터, 2KB */
RAMM1 : origin = 0x000800, length = 0x000800 /* 2KB */
/* RAMLS0: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS0 : origin = 0x008000, length = 0x001000 /* 4KB */
/* RAMLS1: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS1 : origin = 0x009000, length = 0x001000 /* 4KB */
/* RAMGS0: 글로벌 공유 RAM, 데이터/버퍼, 4KB */
RAMGS0 : origin = 0x00C000, length = 0x001000 /* 4KB */
/* RAMGS1: 글로벌 공유 RAM, 데이터/버퍼, 4KB */
RAMGS1 : origin = 0x00D000, length = 0x001000 /* 4KB */
}
/* SECTIONS 섹션: 컴파일러 섹션을 메모리 영역에 매핑 */
SECTIONS
{
/* codestart: 부트 시 시작 코드 */
codestart :> FLASH
/* .text: 실행 가능한 프로그램 코드 */
.text :> FLASH
/* .cinit: C 초기화 테이블 */
.cinit :> FLASH
/* .pinit: C++ 초기화 테이블 */
.pinit :> FLASH
/* .switch: 스위치 문 테이블 */
.switch :> FLASH
/* .const: 읽기 전용 상수 */
.const :> FLASH
/* .data: 초기화된 전역/정적 변수 */
.data :> RAMLS0
/* .bss: 초기화되지 않은 전역/정적 변수 */
.bss :> RAMLS0
/* .ebss: C2000 전용 초기화되지 않은 변수, 대용량 데이터용 */
.ebss :> RAMGS0
/* .econst: C2000 전용 읽기 전용 상수 */
.econst :> RAMLS0
/* .stack: 함수 호출 및 로컬 변수용 스택 */
.stack :> RAMM0
/* ramfuncs: Flash에서 로드, RAMLS1에서 실행, 속도 최적화 */
ramfuncs : LOAD = FLASH,
RUN = RAMLS1,
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
RUN_START(_RamfuncsRunStart)
table(RAM) /* 부트 시 복사 테이블 */
/* IQmath: IQmath 라이브러리 함수 */
IQmath :> FLASH
/* IQmathTables: IQmath 룩업 테이블 */
IQmathTables :> FLASH
}
설명:
- 목적: IQmath 라이브러리를 사용하는 고정소수점 연산 애플리케이션.
- 메모리 배치:
- 코드와 IQmath 라이브러리는 Flash에 배치.
- 대용량 데이터(.ebss)는 RAMGS0에 배치.
- ramfuncs는 RAMLS1에서 실행.
- 특징: IQmath로 고속 수학 연산, 스택/힙 증가(1.5KB, 1KB)로 복잡한 연산 지원.
5.5 예제 5: 다중 CPU (CPU1/CPU2) 지원 CMD 파일
/* File: 2837xD_DualCPU_lnk_cpu1.cmd */
/* Description: TMS320F28377D CPU1 및 CPU2 지원 CMD 파일 */
/* Compiler: Code Composer Studio (TI C2000 Compiler) */
/* Target: TMS320F28377D (CPU1) */
/* 링커 옵션 설정 */
--stack_size=0x400 /* 스택 크기: 1KB, 함수 호출 및 로컬 변수 저장 */
--heap_size=0x200 /* 힙 크기: 512B, 동적 메모리 할당 */
--entry_point=code_start /* 프로그램 시작 지점: 부트 시 실행 시작 주소 */
/* MEMORY 섹션: 디바이스의 물리적 메모리 정의, IPC 포함 */
MEMORY
{
/* 리셋 벡터: 부트 시 CPU가 시작하는 주소 */
RESET : origin = 0x3FFFC0, length = 0x000002
/* Flash: 프로그램 코드 및 상수 저장, 1024KB */
FLASH : origin = 0x080000, length = 0x080000 /* 1024KB */
/* RAMM0: 공용 RAM, 스택/데이터, 1.9KB */
RAMM0 : origin = 0x000080, length = 0x000780 /* 1.9KB */
/* RAMM1: 공용 RAM, 스택/데이터, 2KB */
RAMM1 : origin = 0x000800, length = 0x000800 /* 2KB */
/* RAMLS0: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS0 : origin = 0x008000, length = 0x001000 /* 4KB */
/* RAMLS1: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS1 : origin = 0x009000, length = 0x001000 /* 4KB */
/* RAMGS0: 글로벌 공유 RAM, 데이터/버퍼, 4KB */
RAMGS0 : origin = 0x00C000, length = 0x001000 /* 4KB */
/* RAMGS1: 글로벌 공유 RAM, 데이터/버퍼, 4KB */
RAMGS1 : origin = 0x00D000, length = 0x001000 /* 4KB */
/* IPC_MSGRAM: CPU1/CPU2 간 통신용 메시지 RAM */
IPC_MSGRAM : origin = 0x0003F8, length = 0x000008 /* 8B */
}
/* SECTIONS 섹션: 컴파일러 섹션을 메모리 영역에 매핑 */
SECTIONS
{
/* codestart: 부트 시 시작 코드 */
codestart :> FLASH
/* .text: 실행 가능한 프로그램 코드 */
.text :> FLASH
/* .cinit: C 초기화 테이블 */
.cinit :> FLASH
/* .pinit: C++ 초기화 테이블 */
.pinit :> FLASH
/* .switch: 스위치 문 테이블 */
.switch :> FLASH
/* .const: 읽기 전용 상수 */
.const :> FLASH
/* .data: 초기화된 전역/정적 변수 */
.data :> RAMLS0
/* .bss: 초기화되지 않은 전역/정적 변수 */
.bss :> RAMLS0
/* .ebss: C2000 전용 초기화되지 않은 변수 */
.ebss :> RAMGS0
/* .econst: C2000 전용 읽기 전용 상수 */
.econst :> RAMLS0
/* .stack: 함수 호출 및 로컬 변수용 스택 */
.stack :> RAMM0
/* ramfuncs: Flash에서 로드, RAMLS1에서 실행, 속도 최적화 */
ramfuncs : LOAD = FLASH,
RUN = RAMLS1,
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
RUN_START(_RamfuncsRunStart)
table(RAM) /* 부트 시 복사 테이블 */
/* .ipc_msgram: CPU1/CPU2 간 IPC 메시지 데이터 */
.ipc_msgram :> IPC_MSGRAM
}
설명:
- 목적: CPU1과 CPU2 간 통신(IPC)을 지원.
- 메모리 배치:
- 기본 코드는 Flash에 배치.
- 데이터는 RAMLS0과 RAMGS0에 배치.
- IPC 메시지용 메모리(IPC_MSGRAM) 추가.
- 특징: CPU1/CPU2 동기화 및 데이터 교환 지원.
5.6 예제 6: 고속 PWM 애플리케이션용 CMD 파일
/* File: 2837xD_PWM_lnk_cpu1.cmd */
/* Description: TMS320F28377D 고속 PWM 애플리케이션용 CMD 파일 */
/* Compiler: Code Composer Studio (TI C2000 Compiler) */
/* Target: TMS320F28377D */
/* 링커 옵션 설정 */
--stack_size=0x500 /* 스택 크기: 1.25KB, PWM 데이터 처리용 증가 */
--heap_size=0x300 /* 힙 크기: 768B, 동적 메모리 할당 증가 */
--entry_point=code_start /* 프로그램 시작 지점: 부트 시 실행 시작 주소 */
/* MEMORY 섹션: 디바이스의 물리적 메모리 정의 */
MEMORY
{
/* 리셋 벡터: 부트 시 CPU가 시작하는 주소 */
RESET : origin = 0x3FFFC0, length = 0x000002
/* Flash: 프로그램 코드 및 상수 저장, 1024KB */
FLASH : origin = 0x080000, length = 0x080000 /* 1024KB */
/* RAMM0: 공용 RAM, 스택/데이터, 1.9KB */
RAMM0 : origin = 0x000080, length = 0x000780 /* 1.9KB */
/* RAMM1: 공용 RAM, 스택/데이터, 2KB */
RAMM1 : origin = 0x000800, length = 0x000800 /* 2KB */
/* RAMLS0: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS0 : origin = 0x008000, length = 0x001000 /* 4KB */
/* RAMLS1: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS1 : origin = 0x009000, length = 0x001000 /* 4KB */
/* RAMLS2: 로컬 공유 RAM, 코드/데이터, 4KB */
RAMLS2 : origin = 0x00A000, length = 0x001000 /* 4KB */
/* RAMGS0: 글로벌 공유 RAM, 데이터/버퍼, 4KB */
RAMGS0 : origin = 0x00C000, length = 0x001000 /* 4KB */
}
/* SECTIONS 섹션: 컴파일러 섹션을 메모리 영역에 매핑 */
SECTIONS
{
/* codestart: 부트 시 시작 코드 */
codestart :> FLASH
/* .text: 실행 가능한 프로그램 코드 */
.text :> FLASH
/* .cinit: C 초기화 테이블 */
.cinit :> FLASH
/* .pinit: C++ 초기화 테이블 */
.pinit :> FLASH
/* .switch: 스위치 문 테이블 */
.switch :> FLASH
/* .const: 읽기 전용 상수 */
.const :> FLASH
/* .data: 초기화된 전역/정적 변수 */
.data :> RAMLS0
/* .bss: 초기화되지 않은 전역/정적 변수 */
.bss :> RAMLS0
/* .ebss: C2000 전용 초기화되지 않은 변수 */
.ebss :> RAMGS0
/* .econst: C2000 전용 읽기 전용 상수 */
.econst :> RAMLS0
/* .stack: 함수 호출 및 로컬 변수용 스택 */
.stack :> RAMM0
/* ramfuncs: Flash에서 로드, RAMLS1에서 실행, 속도 최적화 */
ramfuncs : LOAD = FLASH,
RUN = RAMLS1,
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
RUN_START(_RamfuncsRunStart)
table(RAM) /* 부트 시 복사 테이블 */
/* pwmfuncs: PWM 제어 함수, Flash에서 로드, RAMLS2에서 실행 */
pwmfuncs : LOAD = FLASH,
RUN = RAMLS2,
LOAD_START(_PwmfuncsLoadStart),
LOAD_SIZE(_PwmfuncsLoadSize),
RUN_START(_PwmfuncsRunStart)
table(RAM) /* 부트 시 복사 테이블 */
}
설명:
- 목적: 고속 PWM 애플리케이션 (예: 모터 제어).
- 메모리 배치:
- 기본 코드는 Flash에 배치.
- PWM 관련 함수(pwmfuncs)는 Flash에서 로드, RAMLS2에서 실행.
- 데이터는 RAMLS0과 RAMGS0에 배치.
- 특징: PWM 제어 함수를 RAMLS2에 배치하여 고속 실행, 스택/힙 증가(1.25KB, 768B).
6. CMD 파일 사용 방법
6.1 환경 설정
- C2000Ware 설치: C:\ti\c2000\C2000Ware_6_00_00_00\device_support\f2837xd\linker_cmd에서 템플릿 다운로드.
- CCS 프로젝트 설정: TMS320F28377D 타겟, F28x_Project.h 포함, CMD 파일 경로 지정 (CCS Build > C2000 Linker > File Search Path).
- SysConfig 활용: C2000Ware 6.00.00.00 이상에서 SysConfig로 메모리 매핑 자동 생성 가능.
6.2 CMD 파일 적용
- CMD 파일을 프로젝트 폴더에 추가.
- 프로젝트 속성에서 링커 설정에 CMD 경로 지정.
- 빌드 후 .map 파일로 섹션 배치 확인.
6.3 하드웨어 준비
- 개발 보드: TI ControlCARD 또는 LaunchPad.
- JTAG 디버깅: XDS100v2, XDS200 등 연결.
- Flash 프로그래밍: CCS Flash 도구 또는 Flash API 사용.
6.4 디버깅
- .map 파일 분석: 섹션 주소와 크기 확인.
- Memory Browser: RAMM0, RAMLSx, Flash 데이터 검증.
- CLA 디버깅: CLAL0RAM, CLAMSGxRAM 확인.
- 링커 에러: "section overflow" 시 MEMORY 크기 조정, "undefined symbol" 시 codestart 확인.
7. 추가 팁
- C2000Ware 활용: device_support\f2837xd\examples의 예제 및 템플릿(2837xD_FLASH_lnk_cpu1.cmd) 참조.
- 메모리 최적화: 자주 실행되는 함수는 ramfuncs로 RAM 배치, 대용량 데이터는 RAMGSx.
- Flash 프로그래밍: Fapi_Flash 섹션 추가, 부트 시 memcpy로 RAM 복사.
- CLA 활용: CLA 프로그램은 CLAL0RAM, 데이터는 CLAMSGxRAM.
- 문제 해결:
- PWM 출력 없음: ePWM 코드와 ramfuncs 확인.
- 메모리 충돌: .map 파일로 경계 점검.
- TI 리소스: TI E2E 포럼, SPRUI25 매뉴얼, C2000Ware 예제.
8. 결론
이 문서는 TMS320F28377D의 CMD 파일 작성 방법을 한글과 영어로 설명하고, 다양한 시나리오(Flash, RAM, CLA, IQmath, 다중 CPU, PWM)에 맞는 예제를 제공했습니다. 상세 주석은 초보자가 메모리 매핑의 목적을 이해하는 데 도움을 줍니다. CMD 파일은 메모리 관리와 코드 배치를 최적화하여 안정적이고 효율적인 애플리케이션 실행을 보장합니다. 초보자는 C2000Ware 템플릿을, 숙련자는 애플리케이션 요구사항에 맞게 커스터마이징하세요.
키워드: TMS320F28377D, CMD 파일, C2000, 링커 스크립트, 메모리 맵, Flash, RAM, CLA, Flash API, IQmath, 다중 CPU, 고속 PWM, Code Composer Studio, 섹션 배치, 스택, 힙
'MCU > C2000' 카테고리의 다른 글
TI C2000 DSP ePWM Module 설정 가이드 (0) | 2025.09.14 |
---|---|
TI C2000 DSP TMS320F28377D, TMS320F28379D, TMS320F28388D 비교 (2) | 2025.08.18 |
TMS320F28377D DSP SDFM 사용법 : Bitfield 구조 활용 예제 코드(수정) (1) | 2025.08.18 |
TMS320F28377D DSP ePWM CMPASS 사용법: Bitfield 구조 활용 예제 코드(수정) (0) | 2025.08.18 |
TMS320F28377D DSP SPI 사용법 : Bitfield 구조 활용 예제 코드(수정) (2) | 2025.08.18 |
TMS320F28377D DSP DMA 사용법 : Bitfield 구조 활용 예제 코드(수정) (0) | 2025.08.18 |
TMS320F28377D DSP CAN 사용법 : Bitfield 구조 활용 예제 코드(수정) (0) | 2025.08.18 |
TMS320F28377D DSP EMIF 사용법 : Bitfield 구조 활용 예제 코드(수정) (1) | 2025.08.17 |