본문 바로가기
MCU/C2000

[TMS320F28377D] CLA 사용법 : Bitfield 구조 활용 예제 코드

by linuxgo 2025. 8. 18.
반응형

TI의 TMS320F28377D는 C2000 Delfino 시리즈의 32비트 마이크로컨트롤러로, 고속 연산을 위해 설계된 Control Law Accelerator(CLA)를 포함하고 있습니다. CLA는 CPU와 독립적으로 동작하는 코프로세서로, 모터 제어, 디지털 신호 처리(DSP), 전력 변환 등 실시간 고속 연산에 최적화되어 있습니다. 이 글에서는 TMS320F28377D의 CLA 모듈의 상세한 설정 방법, Bitfield 구조를 활용한 레지스터 설정, 링커 커맨드 파일 수정, 그리고 실용적인 예제 코드를 제공하여 초보자와 숙련된 개발자 모두가 쉽게 활용할 수 있도록 돕겠습니다.

1. TMS320F28377D CLA 모듈 개요

TMS320F28377D는 두 개의 CLA 코프로세서(CLA1, CLA2)를 포함하며, 각 CLA는 실시간 제어 작업을 병렬로 처리할 수 있습니다. 아래는 주요 사양입니다:

  • 클럭 소스: 시스템 클럭(SYSCLK, 최대 200MHz)
  • 연산 성능: 32비트 부동소수점 연산 지원
  • 메모리: 독립적인 프로그램 메모리(LSM0~LSM7, 4KB/CLA) 및 데이터 메모리
  • 태스크: 8개의 태스크(Task1~Task8), 각 태스크는 인터럽트로 트리거 가능
  • 주요 기능:
    • 고속 부동소수점 연산 (덧셈, 곱셈, 나눗셈 등)
    • CPU와 독립적인 병렬 처리
    • ADC, ePWM, 타이머 등 주변 장치와 직접 인터페이스
    • 데이터 공유를 위한 메시지 RAM
  • 인터럽트: 각 태스크에 대해 개별 인터럽트 벡터 지원
  • 동기화: CPU와 CLA 간 동기화 및 데이터 교환 가능

2. CLA Bitfield 설정 상세

TMS320F28377D의 CLA 레지스터는 Bitfield 구조로 정의되어 있어, F2837xD_cla.h 헤더 파일을 통해 접근합니다. Bitfield는 레지스터의 개별 비트를 명확히 설정하여 코드 가독성과 유지보수성을 높입니다. 주요 레지스터와 Bitfield는 다음과 같습니다:

2.1 MCTL (CLA 제어 레지스터)

  • bit.IACKE: 인터럽트 확인 활성화 (1: 활성화)
  • bit.HARDRESET: 하드 리셋 (1: 리셋)
  • bit.SOFTRESET: 소프트 리셋 (1: 리셋)

2.2 MIER (CLA 인터럽트 활성화 레지스터)

  • bit.INT1~bit.INT8: 각 태스크(Task1~Task8)에 대한 인터럽트 활성화 (1: 활성화)

2.3 MIFR (CLA 인터럽트 플래그 레지스터)

  • bit.INT1~bit.INT8: 각 태스크의 인터럽트 플래그 (1: 인터럽트 발생)

2.4 MPISRCSELx (CLA 태스크 인터럽트 소스 선택 레지스터)

  • bit.PERINTxSEL: 태스크 x의 인터럽트 소스 선택 (예: ADCINT1, EPWMx_INT 등)

2.5 MMEMCFG (CLA 메모리 구성 레지스터)

  • bit.PROGE: 프로그램 메모리 활성화 (1: 활성화)
  • bit.RAMxE: 데이터 RAM x 활성화 (1: 활성화)
  • bit.RAMxCPUE: CPU 접근 허용 (1: 허용)

Bitfield 사용 이점:

  • 명확한 비트 단위 설정으로 실수 감소
  • 코드 가독성 및 유지보수성 향상
  • F2837xD_cla.h에서 제공하는 구조체로 직관적 접근

3. CLA 설정 절차

CLA 모듈을 효과적으로 설정하려면 다음 단계를 따라야 합니다:

  1. 시스템 초기화:
    • InitSysCtrl()를 호출하여 시스템 클럭과 PLL을 초기화합니다.
    • 인터럽트를 비활성화하고 PIE(Peripheral Interrupt Expansion)를 초기화합니다 (DINT, InitPieCtrl, InitPieVectTable).
  2. CLA 클럭 활성화:
    • CpuSysRegs.PCLKCR0.bit.CLA1 = 1을 설정하여 CLA1 클럭을 활성화합니다.
    • 보호된 레지스터 접근을 위해 EALLOW와 EDIS 사용.
  3. 메모리 구성:
    • Cla1Regs.MMEMCFG.bit.PROGE로 프로그램 메모리 활성화.
    • Cla1Regs.MMEMCFG.bit.RAMxE로 데이터 RAM 활성화.
    • CPU와 CLA 간 데이터 공유를 위해 메시지 RAM 설정.
  4. 태스크 인터럽트 설정:
    • Cla1Regs.MPISRCSEL1.bit.PERINTxSEL로 각 태스크의 트리거 소스 설정 (예: ADCINT1, EPWMx_INT).
    • Cla1Regs.MIER.bit.INTx로 인터럽트 활성화.
  5. CLA 프로그램 로드:
    • CLA 프로그램을 LSM(로컬 공유 메모리)에 로드.
    • Cla1Regs.MVECTx로 각 태스크의 벡터 주소 설정.
  6. CLA 실행:
    • Cla1Regs.MCTL.bit.IACKE = 1로 인터럽트 확인 활성화.
    • Cla1Regs.MIER.all로 원하는 태스크 인터럽트 활성화.

4. CLA 설정 고려사항

  • 클럭 설정: CLA는 SYSCLK(200MHz)에서 동작하며, 별도 클럭 분주 설정 없음.
  • 메모리 관리: LSM0~LSM7은 CLA와 CPU 간 공유 가능, 올바른 메모리 매핑 필수.
  • 태스크 우선순위: Task1이 최고 우선순위, Task8이 최저 우선순위.
  • 인터럽트 트리거: ADC, ePWM, 타이머 등 외부 이벤트를 활용하여 태스크 트리거.
  • 디버깅: CLA 디버깅은 제한적이며, CCS의 메모리 뷰를 통해 레지스터와 데이터 확인.

5. 실용적인 CLA 예제 코드 (Bitfield 구조)

아래는 TMS320F28377D CLA 모듈을 Bitfield 구조로 설정한 3개의 실용적인 예제 코드입니다. 각 예제는 Code Composer Studio(CCS)와 C2000Ware 환경에서 실행 가능합니다.

5.1 예제 1: 기본 CLA 태스크 (사인파 계산)

// File: cla_basic_sine.c
// Description: TMS320F28377D CLA 기본 태스크(사인파 계산) 예제 (Bitfield 구조)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D

#include "F28x_Project.h"

// CLA 데이터 섹션 정의
#pragma DATA_SECTION(Cla1DataRam0, "Cla1DataRam0")
float input = 0.0;
#pragma DATA_SECTION(Cla1DataRam1, "Cla1DataRam1")
float output = 0.0;

// CLA 태스크 정의
__attribute__((interrupt)) void Cla1Task1(void)
{
    output = __sin(input); // CLA에서 부동소수점 사인 계산
}

void main(void) {
    // 시스템 초기화
    InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
    DINT; // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 초기화
    IER = 0x0000; // CPU 인터럽트 비활성화
    IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
    InitPieVectTable(); // PIE 벡터 테이블 초기화

    // GPIO 설정 (LED)
    EALLOW;
    GpioCtrlRegs.GPBDIR.bit.GPIO31 = 1; // GPIO31을 출력(LED)으로 설정
    GpioDataRegs.GPBSET.bit.GPIO31 = 1; // LED 켜기
    EDIS;

    // CLA 클럭 활성화
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.CLA1 = 1; // CLA1 클럭 활성화
    EDIS;

    // CLA 메모리 구성
    EALLOW;
    Cla1Regs.MMEMCFG.bit.PROGE = 1; // 프로그램 메모리 활성화
    Cla1Regs.MMEMCFG.bit.RAM0E = 1; // 데이터 RAM0 활성화
    Cla1Regs.MMEMCFG.bit.RAM1E = 1; // 데이터 RAM1 활성화
    EDIS;

    // CLA 태스크 벡터 설정
    EALLOW;
    Cla1Regs.MVECT1 = (uint16_t)(&Cla1Task1); // Task1 벡터 설정
    EDIS;

    // CLA 태스크 트리거 설정
    EALLOW;
    Cla1Regs.MPISRCSEL1.bit.PERINT1SEL = CLA_INT1_NONE; // 소프트 트리거
    Cla1Regs.MIER.bit.INT1 = 1; // Task1 인터럽트 활성화
    Cla1Regs.MCTL.bit.IACKE = 1; // 인터럽트 확인 활성화
    EDIS;

    // 입력 데이터 설정
    input = 1.5708; // 90도 (PI/2 라디안)

    // CLA 태스크 소프트 트리거
    Cla1Regs.MIFR.bit.INT1 = 1;

    // CLA 태스크 완료 대기
    while(Cla1Regs.MIRUN.bit.INT1 == 1);

    // 결과 확인 (디버깅용)
    if(output > 0.999 && output < 1.001) { // sin(90도) ≈ 1.0
        GpioDataRegs.GPBSET.bit.GPIO31 = 1; // LED 유지
    } else {
        GpioDataRegs.GPBCLEAR.bit.GPIO31 = 1; // LED 끄기
    }

    for(;;); // 무한 루프
}

설명:

  • 기능: CLA Task1을 사용하여 입력 각도(90도)의 사인 값을 계산.
  • 설정: CLA1 활성화, 데이터 RAM0/RAM1 사용, Task1에 사인 계산 로직.
  • GPIO: GPIO31(LED).
  • 출력: 사인 값 계산 후 LED로 결과 표시 (정상: LED ON, 오류: LED OFF).

5.2 예제 2: ADC와 연동된 CLA 태스크

// File: cla_adc_trigger.c
// Description: TMS320F28377D CLA ADC 트리거 예제 (Bitfield 구조)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D

#include "F28x_Project.h"

// CLA 데이터 섹션 정의
#pragma DATA_SECTION(Cla1DataRam0, "Cla1DataRam0")
float adc_result = 0.0;
#pragma DATA_SECTION(Cla1DataRam1, "Cla1DataRam1")
float processed_result = 0.0;

// CLA 태스크 정의
__attribute__((interrupt)) void Cla1Task1(void)
{
    adc_result = (float)AdcaResultRegs.ADCRESULT0 * (3.3 / 4096.0); // 12비트 ADC 변환
    processed_result = adc_result * 2.0; // 간단한 스케일링
}

void main(void) {
    // 시스템 초기화
    InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
    DINT; // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 초기화
    IER = 0x0000; // CPU 인터럽트 비활성화
    IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
    InitPieVectTable(); // PIE 벡터 테이블 초기화

    // GPIO 설정 (LED)
    EALLOW;
    GpioCtrlRegs.GPBDIR.bit.GPIO31 = 1; // GPIO31을 출력(LED)으로 설정
    GpioDataRegs.GPBSET.bit.GPIO31 = 1; // LED 켜기
    EDIS;

    // ADC 설정
    EALLOW;
    AdcaRegs.ADCCTL2.bit.PRESCALE = 6; // ADC 클럭 분주비
    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; // 인터럽트 펄스 위치
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; // ADC 전원 활성화
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; // ADC 채널 A0
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 15; // 샘플링 윈도우
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // ePWM1 SOCA 트리거
    EDIS;

    // ePWM1 설정 (ADC 트리거용)
    EALLOW;
    CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; // ePWM1 클럭 활성화
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 업 카운트 모드
    EPwm1Regs.TBPRD = 2000; // 주기 = 100kHz
    EPwm1Regs.ETSEL.bit.SOCAEN = 1; // SOCA 활성화
    EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // TBCTR=0에서 SOCA
    EPwm1Regs.ETPS.bit.SOCAPRD = 1; // 첫 번째 이벤트에서 SOCA
    EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드
    EDIS;

    // CLA 클럭 활성화
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.CLA1 = 1; // CLA1 클럭 활성화
    EDIS;

    // CLA 메모리 구성
    EALLOW;
    Cla1Regs.MMEMCFG.bit.PROGE = 1; // 프로그램 메모리 활성화
    Cla1Regs.MMEMCFG.bit.RAM0E = 1; // 데이터 RAM0 활성화
    Cla1Regs.MMEMCFG.bit.RAM1E = 1; // 데이터 RAM1 활성화
    EDIS;

    // CLA 태스크 벡터 설정
    EALLOW;
    Cla1Regs.MVECT1 = (uint16_t)(&Cla1Task1); // Task1 벡터 설정
    EDIS;

    // CLA 태스크 트리거 설정
    EALLOW;
    Cla1Regs.MPISRCSEL1.bit.PERINT1SEL = CLA_INT1_ADCA1; // ADCINT1 트리거
    Cla1Regs.MIER.bit.INT1 = 1; // Task1 인터럽트 활성화
    Cla1Regs.MCTL.bit.IACKE = 1; // 인터럽트 확인 활성화
    EDIS;

    for(;;); // 무한 루프
}

설명:

  • 기능: ePWM1의 SOCA로 ADC를 트리거하고, CLA Task1에서 ADC 결과를 처리.
  • 설정: ADC A0 채널, ePWM1 100kHz SOCA 트리거, CLA Task1에서 ADC 결과 스케일링.
  • GPIO: GPIO31(LED).
  • 출력: ADC 결과 처리 후 processed_result에 저장, LED ON으로 동작 표시.

5.3 예제 3: CLA를 이용한 PID 제어

// File: cla_pid_control.c
// Description: TMS320F28377D CLA PID 제어 예제 (Bitfield 구조)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D

#include "F28x_Project.h"

// CLA 데이터 섹션 정의
#pragma DATA_SECTION(Cla1DataRam0, "Cla1DataRam0")
float setpoint = 1.0; // 목표값
#pragma DATA_SECTION(Cla1DataRam1, "Cla1DataRam1")
float feedback = 0.0; // 피드백 값
#pragma DATA_SECTION(Cla1DataRam2, "Cla1DataRam2")
float error = 0.0;
#pragma DATA_SECTION(Cla1DataRam3, "Cla1DataRam3")
float integral = 0.0;
#pragma DATA_SECTION(Cla1DataRam4, "Cla1DataRam4")
float output = 0.0;

// PID 파라미터
float Kp = 1.0, Ki = 0.1, Kd = 0.01;

// CLA 태스크 정의
__attribute__((interrupt)) void Cla1Task1(void)
{
    static float prev_error = 0.0;
    error = setpoint - feedback;
    integral += error;
    float derivative = error - prev_error;
    output = Kp * error + Ki * integral + Kd * derivative;
    prev_error = error;
}

void main(void) {
    // 시스템 초기화
    InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
    DINT; // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 초기화
    IER = 0x0000; // CPU 인터럽트 비활성화
    IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
    InitPieVectTable(); // PIE 벡터 테이블 초기화

    // GPIO 설정 (LED)
    EALLOW;
    GpioCtrlRegs.GPBDIR.bit.GPIO31 = 1; // GPIO31을 출력(LED)으로 설정
    GpioDataRegs.GPBSET.bit.GPIO31 = 1; // LED 켜기
    EDIS;

    // ePWM1 설정 (타이머 트리거용)
    EALLOW;
    CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; // ePWM1 클럭 활성화
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 업 카운트 모드
    EPwm1Regs.TBPRD = 2000; // 주기 = 100kHz
    EPwm1Regs.ETSEL.bit.INTEN = 1; // 인터럽트 활성화
    EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // TBCTR=0에서 인터럽트
    EPwm1Regs.ETPS.bit.INTPRD = 1; // 첫 번째 이벤트에서 인터럽트
    EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드
    EDIS;

    // CLA 클럭 활성화
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.CLA1 = 1; // CLA1 클럭 활성화
    EDIS;

    // CLA 메모리 구성
    EALLOW;
    Cla1Regs.MMEMCFG.bit.PROGE = 1; // 프로그램 메모리 활성화
    Cla1Regs.MMEMCFG.bit.RAM0E = 1; // 데이터 RAM0 활성화
    Cla1Regs.MMEMCFG.bit.RAM1E = 1; // 데이터 RAM1 활성화
    Cla1Regs.MMEMCFG.bit.RAM2E = 1; // 데이터 RAM2 활성화
    Cla1Regs.MMEMCFG.bit.RAM3E = 1; // 데이터 RAM3 활성화
    Cla1Regs.MMEMCFG.bit.RAM4E = 1; // 데이터 RAM4 활성화
    EDIS;

    // CLA 태스크 벡터 설정
    EALLOW;
    Cla1Regs.MVECT1 = (uint16_t)(&Cla1Task1); // Task1 벡터 설정
    EDIS;

    // CLA 태스크 트리거 설정
    EALLOW;
    Cla1Regs.MPISRCSEL1.bit.PERINT1SEL = CLA_INT1_EPWM1; // ePWM1 인터럽트 트리거
    Cla1Regs.MIER.bit.INT1 = 1; // Task1 인터럽트 활성화
    Cla1Regs.MCTL.bit.IACKE = 1; // 인터럽트 확인 활성화
    EDIS;

    // 피드백 값 초기화 (테스트용)
    feedback = 0.5;

    for(;;); // 무한 루프
}

설명:

  • 기능: CLA Task1을 사용하여 PID 제어 알고리즘 실행.
  • 설정: ePWM1 인터럽트로 Task1 트리거, PID 계산 수행.
  • GPIO: GPIO31(LED).
  • 출력: PID 출력값 계산 후 output에 저장, LED ON으로 동작 표시.

6. 사용 방법

6.1 환경 설정

  • C2000Ware 설치: C:\ti\c2000\C2000Ware_x_xx_xx_xx에서 라이브러리 다운로드
  • CCS 프로젝트: TMS320F28377D 타겟으로 프로젝트 생성, F28x_Project.h 포함
  • CLA 컴파일러 옵션: CCS에서 CLA 소스 파일에 대해 --cla_support=cla2 옵션 추가

6.2 링커 커맨드 파일(.cmd) 수정

CLA를 사용하려면 링커 커맨드 파일(.cmd)을 수정하여 CLA 프로그램과 데이터 섹션을 올바른 메모리 영역(LSM 또는 메시지 RAM)에 매핑해야 합니다. TMS320F28377D의 메모리 맵은 CLA 전용 로컬 공유 메모리(LSM0~LSM7)와 CPU-CLA 간 데이터 공유를 위한 메시지 RAM을 포함합니다. 아래는 예제 코드에 맞게 수정된 2837xD_RAM_lnk_cpu1.cmd 파일의 관련 섹션입니다.

링커 커맨드 파일 예제

// File: 2837xD_RAM_lnk_cpu1.cmd
// Description: TMS320F28377D CLA 메모리 매핑을 위한 링커 커맨드 파일
MEMORY
{
   PAGE 0: // 프로그램 메모리
      /* CLA 프로그램 메모리 */
      LS0_RAM        : origin = 0x008000, length = 0x000800  // 2KB, CLA 프로그램 메모리
      RAMM0          : origin = 0x000123, length = 0x0002DD
      RAMD0          : origin = 0x00B000, length = 0x000800
      RAMLS4         : origin = 0x00A800, length = 0x000800
      RAMLS5         : origin = 0x00B800, length = 0x000800
      RESET          : origin = 0x3FFFC0, length = 0x000002

   PAGE 1: // 데이터 메모리
      /* CLA 데이터 메모리 */
      Cla1DataRam0   : origin = 0x00C000, length = 0x000800  // 2KB, CLA 데이터 RAM0
      Cla1DataRam1   : origin = 0x00C800, length = 0x000800  // 2KB, CLA 데이터 RAM1
      Cla1DataRam2   : origin = 0x00D000, length = 0x000800  // 2KB, CLA 데이터 RAM2
      Cla1DataRam3   : origin = 0x00D800, length = 0x000800  // 2KB, CLA 데이터 RAM3
      Cla1DataRam4   : origin = 0x00E000, length = 0x000800  // 2KB, CLA 데이터 RAM4
      RAMM1          : origin = 0x000400, length = 0x000400
      RAMD1          : origin = 0x00B800, length = 0x000800
      Cla1ToCpuMsgRAM: origin = 0x00D800, length = 0x000800  // CPU->CLA 메시지 RAM
      CpuToCla1MsgRAM: origin = 0x00E000, length = 0x000800  // CLA->CPU 메시지 RAM
}

SECTIONS
{
   /* CLA 프로그램 섹션 */
   .text_cla : > LS0_RAM, PAGE = 0
   /* CLA 데이터 섹션 */
   Cla1DataRam0 : > Cla1DataRam0, PAGE = 1
   Cla1DataRam1 : > Cla1DataRam1, PAGE = 1
   Cla1DataRam2 : > Cla1DataRam2, PAGE = 1
   Cla1DataRam3 : > Cla1DataRam3, PAGE = 1
   Cla1DataRam4 : > Cla1DataRam4, PAGE = 1
   /* 표준 섹션 */
   .text      : > RAMM0 | RAMD0 | RAMLS4 | RAMLS5, PAGE = 0
   .cinit     : > RAMM0, PAGE = 0
   .pinit     : > RAMM0, PAGE = 0
   .switch    : > RAMM0, PAGE = 0
   .reset     : > RESET, PAGE = 0, TYPE = DSECT
   .stack     : > RAMM1, PAGE = 1
   .ebss      : > RAMD1, PAGE = 1
   .econst    : > RAMD1, PAGE = 1
   .esysmem   : > RAMD1, PAGE = 1
}

수정 포인트

  1. 메모리 정의:
    • LS0_RAM: CLA 프로그램을 위해 LSM0(0x008000~0x0087FF)을 할당. 예제에서는 Task1의 코드를 이 영역에 배치.
    • Cla1DataRam0~Cla1DataRam4: CLA 데이터 메모리로 LSM0~LSM4를 사용. 각 예제에서 사용된 데이터 변수(input, output, setpoint 등)를 해당 RAM에 매핑.
    • Cla1ToCpuMsgRAM, CpuToCla1MsgRAM: CPU와 CLA 간 데이터 교환을 위한 메시지 RAM.
  2. 섹션 매핑:
    • .text_cla: CLA 태스크 코드(예: Cla1Task1)를 LS0_RAM에 배치.
    • Cla1DataRam0~Cla1DataRam4: 각 예제의 데이터 섹션(#pragma DATA_SECTION)을 해당 데이터 RAM에 매핑.
    • 표준 섹션(.text, .cinit 등)은 CPU용 메모리에 유지.
  3. 고려사항:
    • 메모리 충돌 방지: CLA와 CPU가 동일한 LSM을 공유하지 않도록 Cla1Regs.MMEMCFG 설정과 .cmd 파일의 메모리 정의가 일치해야 함.
    • 메모리 크기: 각 LSM은 2KB로 제한되므로, 데이터와 프로그램 크기를 초과하지 않도록 주의.
    • C2000Ware 템플릿: C:\ti\c2000\C2000Ware_x_xx_xx_xx\device_support\f2837xd\common\cmd의 2837xD_RAM_lnk_cpu1.cmd를 기반으로 수정.
    • 컴파일러 옵션: CLA 소스 파일에 --cla_support=cla2 옵션을 추가하여 CLA2 아키텍처를 대상으로 컴파일.
  4. 적용 방법:
    • CCS 프로젝트에서 2837xD_RAM_lnk_cpu1.cmd를 복사하여 프로젝트에 추가.
    • 위 예제 코드를 반영하여 메모리와 섹션 정의 수정.
    • 프로젝트 속성에서 링커 파일 경로를 지정(--cmd_file 옵션).

디버깅 팁

  • 메모리 매핑 오류: Cla1Regs.MMEMCFG 설정과 .cmd 파일의 메모리 정의가 일치하는지 확인.
  • CLA 코드 실행 안 됨: .text_cla 섹션이 LS0_RAM에 올바르게 매핑되었는지 확인.
  • 데이터 접근 오류: Cla1DataRamX 섹션이 올바른 LSM에 매핑되었는지 확인 (CCS 메모리 뷰 사용).

6.3 코드 실행

  • 각 예제를 별도의 .c 파일로 저장하거나, main.c에 복사.
  • 원하는 예제만 실행되도록 다른 코드 주석 처리.
  • 링커 커맨드 파일을 프로젝트에 추가하고, CLA 소스 파일에 --cla_support=cla2 옵션 적용.

6.4 하드웨어 준비

  • LED: GPIO31에 LED 연결 (정상 동작 확인용).
  • ADC 입력: 예제 2의 경우 ADC A0 핀에 아날로그 신호 입력.
  • ePWM 출력: 예제 2, 3에서 ePWM1 관련 핀 확인.
  • 디버깅 도구: 오실로스코프 또는 CCS 디버거.

6.5 디버깅

  • CCS의 Expressions 창에서 Cla1Regs.MIFR, Cla1Regs.MIRUN 확인.
  • 데이터 RAM(Cla1DataRam0 등)에서 변수 값 모니터링.
  • CLA 태스크 실행 상태 확인 (Cla1Regs.MVECTx).
  • 링커 매핑 오류 시, 메모리 뷰에서 LS0_RAM, Cla1DataRamX 영역 점검.

7. 추가 팁

  • 캘리브레이션: CLA 사용 시 Device_cal() 호출로 클럭 보정.
  • 메모리 최적화: CLA 데이터 RAM 크기 제한(4KB) 고려, 불필요한 변수 최소화.
  • 링커 파일 관리: CLA 프로그램과 데이터 섹션의 메모리 충돌 방지.
  • C2000Ware 참고: C:\ti\c2000\C2000Ware_x_xx_xx_xx\device_support\f2837xd\examples\cpu1\cla.
  • 문제 해결:
    • CLA 태스크 실행 안 됨: Cla1Regs.MIER, Cla1Regs.MPISRCSEL1, .cmd 파일 확인.
    • 메모리 접근 오류: Cla1Regs.MMEMCFG와 .cmd 파일의 메모리 정의 일치 여부 확인.
    • 인터럽트 실패: 트리거 소스(PERINTxSEL)와 PIE 설정 확인.
  • TI 리소스: TI E2E 포럼, C2000Ware CLA 예제.

8. 결론

이 문서는 TMS320F28377D CLA 모듈의 설정 방법, Bitfield 구조를 활용한 레지스터 설정, 링커 커맨드 파일 수정, 그리고 실용적인 예제 코드를 제공하여, 초보자부터 숙련된 개발자까지 쉽게 활용할 수 있도록 구성했습니다. 기본 사인파 계산, ADC 연동, PID 제어 예제를 통해 다양한 실시간 제어 애플리케이션에 적용 가능합니다.

키워드: TMS320F28377D, CLA, C2000, Control Law Accelerator, 마이크로컨트롤러, Code Composer Studio, ADC 트리거, PID 제어, 부동소수점 연산, 태스크 인터럽트, 메모리 구성, 링커 커맨드 파일

반응형