前言
本项目基于TI官方例程进行学习
例程位于ti\c2000\C2000Ware_5_02_00_00\device_support\f2837xd\examples\cpu1
参考资料
TMS320F2837xD Dual-Core Microcontrollers Technical Reference Manual (第六章)
调试参考
CLA Hands On Workshop - Part 4 Debugging on the CLA | Video | TI.com
一、配置cmd文件
可直接调用ti\c2000\C2000Ware_5_02_00_00\device_support\f2837xd\common\cmd文件夹中的2837xD_RAM_CLA_lnk_cpu1.cmd文件
对cmd文件中涉及的有关CLA模块的内容稍加解释
1.文件开头定义
定义 CLA 暂存器区域的大小
CLA_SCRATCHPAD_SIZE = 0x100;
2.MEMORY PAGE 0中
分配RAM用于CLA的程序空间
RAMLS4_5 : origin = 0x00A000, length = 0x001000
3.MEMORY PAGE 1中
(1)分配RAMLS0-5用于CLA的数据空间
RAMLS0 : origin = 0x008000, length = 0x000800
RAMLS1 : origin = 0x008800, length = 0x000800
RAMLS2 : origin = 0x009000, length = 0x000800
RAMLS3 : origin = 0x009800, length = 0x000800
(2)分配内存空间用于CLA与CPU交互
CLA1_MSGRAMLOW : origin = 0x001480, length = 0x000080
CLA1_MSGRAMHIGH : origin = 0x001500, length = 0x000080
4.SECTION中
CLA1mathTables : LOAD = FLASHL,
RUN = RAMLS3,
LOAD_START(_Cla1mathTablesLoadStart),
LOAD_END(_Cla1mathTablesLoadEnd),
LOAD_SIZE(_Cla1mathTablesLoadSize),
RUN_START(_Cla1mathTablesRunStart),
PAGE = 1
Cla1Prog : > RAMLS4_5, PAGE=0 //cla程序空间
CLADataLS0 : > RAMLS0, PAGE=1
CLADataLS1 : > RAMLS1, PAGE=1
Cla1ToCpuMsgRAM : > CLA1_MSGRAMLOW, PAGE = 1
CpuToCla1MsgRAM : > CLA1_MSGRAMHIGH, PAGE = 1
#ifdef CLA_C
/* CLA C compiler sections */
//
// Must be allocated to memory the CLA has write access to
//CLA存储临时数据
CLAscratch :
{ *.obj(CLAscratch)
. += CLA_SCRATCHPAD_SIZE;
*.obj(CLAscratch_end) } > RAMLS1, PAGE = 1
.scratchpad : > RAMLS1, PAGE = 1
.bss_cla : > RAMLS1, PAGE = 1
.const_cla : > RAMLS1, PAGE = 1
#endif //CLA_C
二、在工程项目的APP/CLA文件夹中创建include、lib、rom_symbol_libs文件夹
include中添加clamath.h
文件路径: ti\c2000\C2000Ware_2_01_00_00\libraries\math\CLAmath\c28\include
lib中添加cla1_math_library_datarom_fpu32.lib及cla1_math_library_fpu32.lib
文件路径: ti\c2000\C2000Ware_2_01_00_00\libraries\math\CLAmath\c28\lib
rom_symbol_lib中添加F2837xRevB_c1bootROM_CLADataROMSymbols_fpu32.lib
文件路径:ti\c2000\C2000Ware_2_01_00_00\libraries\boot_rom\f2837xd\rev0\rom_symbol_libs
三、修改项目属性
1.定义CLA_C=1
properties→Build→C2000 Linker→Advanced Options→Command File Prepocessing中定义CLA_C=1,如图所示
2.CPU1预定义
properties→Build→C2000 Compiler→Predefined Symbols中预定义CPU1,如图所示
四、创建cla_init.h头文件、cla_init.c初始化、cla_share.cla
cla_init.h
/*
* cla_init.h
*
* Created on: 2024年5月7日
* Author: cmy
*/
#ifndef APP_CLA_CLA_INIT_H_
#define APP_CLA_CLA_INIT_H_
//
// Included Files
//
#include <F28x_Project.h>
#include "F2837xD_Cla_defines.h"
#include <stdint.h>
#include <LED/LED.h>
#ifdef __cplusplus
extern "C" {
#endif
//
//Task 1 (C) Variables
//事件一交互变量
extern float fVal; //input
extern float fVal1; //
extern float fVal2; //input
extern float fResult; //Estimated result
//
//Task 2 (C) Variables
//
//
//Task 3 (C) Variables
//
//
//Task 4 (C) Variables
//
//
//Task 5 (C) Variables
//
//
//Task 6 (C) Variables
//
//
//Task 7 (C) Variables
//
//
//Task 8 (C) Variables
//
//
//Common (C) Variables
//
//
// Function Prototypes
//
// The following are symbols defined in the CLA assembly code
// Including them in the shared header file makes them
// .global and the main CPU can make use of them.
//CLA事件
__interrupt void Cla1Task1();
__interrupt void Cla1Task2();
__interrupt void Cla1Task3();
__interrupt void Cla1Task4();
__interrupt void Cla1Task5();
__interrupt void Cla1Task6();
__interrupt void Cla1Task7();
__interrupt void Cla1Task8();
void CLA_init(void);
void CLA_configClaMemory(void);
void CLA_initCpu1Cla1(void);
void CLA_runTest(void);
#define WAITSTEP asm(" RPT #255 || NOP")
//cla事件处理结束之后触发相应中断
__interrupt void cla1Isr1();
__interrupt void cla1Isr2();
__interrupt void cla1Isr3();
__interrupt void cla1Isr4();
__interrupt void cla1Isr5();
__interrupt void cla1Isr6();
__interrupt void cla1Isr7();
__interrupt void cla1Isr8();
#ifdef __cplusplus
}
#endif // extern "C"
#endif //end of _CLA_SQRT_SHARED_H_ definition
cla_init.c
/*
* cla_init.c
*
* Created on: 2024年5月7日
* Author: cmy
*/
#include <CLA/cla_init.h>
//
//Task 1 (C) Variables
// NOTE: Do not initialize the Message RAM variables globally, they will be
// reset during the message ram initialization phase in the CLA memory
// configuration routine
//将变量放置在指定的共享内存段中,以便两个模块访问
#ifdef __cplusplus
#pragma DATA_SECTION("CpuToCla1MsgRAM");
float fVal;
#pragma DATA_SECTION("Cla1ToCpuMsgRAM");
float fResult;
#else
#pragma DATA_SECTION(fVal,"CpuToCla1MsgRAM");
float fVal;
#pragma DATA_SECTION(fVal1,"CpuToCla1MsgRAM");
float fVal1;
#pragma DATA_SECTION(fVal2,"CpuToCla1MsgRAM");
float fVal2;
#pragma DATA_SECTION(fResult,"Cla1ToCpuMsgRAM");
float fResult;
#endif //__cplusplus
//float y[BUFFER_SIZE];
//
//Task 2 (C) Variables
//
//
//Task 3 (C) Variables
//
//
//Task 4 (C) Variables
//
//
//Task 5 (C) Variables
//
//
//Task 6 (C) Variables
//
//
//Task 7 (C) Variables
//
//
//Task 8 (C) Variables
//
//
//Common (C) Variables
//
uint16_t pass=0;
uint16_t fail=0;
void CLA_init(void)
{
//EALLOW;
CLA_configClaMemory();
CLA_initCpu1Cla1();
//EDIS;
}
void CLA_configClaMemory(void)
{
extern uint32_t Cla1funcsRunStart, Cla1funcsLoadStart, Cla1funcsLoadSize;
EALLOW;
#ifdef _FLASH
//
// Copy over code from FLASH to RAM
//
memcpy((uint32_t *)&Cla1funcsRunStart, (uint32_t *)&Cla1funcsLoadStart,
(uint32_t)&Cla1funcsLoadSize);
#endif //_FLASH
//
// Initialize and wait for CLA1ToCPUMsgRAM
//
MemCfgRegs.MSGxINIT.bit.INIT_CLA1TOCPU = 1;//RAM初始化控制
while(MemCfgRegs.MSGxINITDONE.bit.INITDONE_CLA1TOCPU != 1){};//=1 is done
//
// Initialize and wait for CPUToCLA1MsgRAM
//
MemCfgRegs.MSGxINIT.bit.INIT_CPUTOCLA1 = 1;
while(MemCfgRegs.MSGxINITDONE.bit.INITDONE_CPUTOCLA1 != 1){};
//
// Select LS4RAM and LS5RAM to be the programming space for the CLA
// First configure the CLA to be the master for LS4 and LS5 and then
// set the space to be a program block
//
MemCfgRegs.LSxMSEL.bit.MSEL_LS4 = 1;//将存储器所有权分配给CLA
MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS4 = 1;
MemCfgRegs.LSxMSEL.bit.MSEL_LS5 = 1;
MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS5 = 1;
//
// Next configure LS0RAM and LS1RAM as data spaces for the CLA
// First configure the CLA to be the master for LS0(1) and then
// set the spaces to be code blocks
//
MemCfgRegs.LSxMSEL.bit.MSEL_LS0 = 1;
MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS0 = 0;
MemCfgRegs.LSxMSEL.bit.MSEL_LS1 = 1;
MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS1 = 0;
EDIS;
}
void CLA_initCpu1Cla1(void)
{
//
// Compute all CLA task vectors
// On Type-1 CLAs the MVECT registers accept full 16-bit task addresses as
// opposed to offsets used on older Type-0 CLAs
//
EALLOW;
Cla1Regs.MVECT1 = (uint16_t)(&Cla1Task1);
Cla1Regs.MVECT2 = (uint16_t)(&Cla1Task2);
Cla1Regs.MVECT3 = (uint16_t)(&Cla1Task3);
Cla1Regs.MVECT4 = (uint16_t)(&Cla1Task4);
Cla1Regs.MVECT5 = (uint16_t)(&Cla1Task5);
Cla1Regs.MVECT6 = (uint16_t)(&Cla1Task6);
Cla1Regs.MVECT7 = (uint16_t)(&Cla1Task7);
Cla1Regs.MVECT8 = (uint16_t)(&Cla1Task8);
//CLA触发源设置:软件触发
//DmaClaSrcSelRegs.CLA1TASKSRCSEL1.all=0;
//DmaClaSrcSelRegs.CLA1TASKSRCSEL2.all=0;
//
// Enable the IACK instruction to start a task on CLA in software
// for all 8 CLA tasks. Also, globally enable all 8 tasks (or a
// subset of tasks) by writing to their respective bits in the
// MIER register
//
Cla1Regs.MCTL.bit.IACKE = 1;
Cla1Regs.MIER.all = 0x00FF;
//
// Configure the vectors for the end-of-task interrupt for all
// 8 tasks
//
PieVectTable.CLA1_1_INT = &cla1Isr1;
PieVectTable.CLA1_2_INT = &cla1Isr2;
PieVectTable.CLA1_3_INT = &cla1Isr3;
PieVectTable.CLA1_4_INT = &cla1Isr4;
PieVectTable.CLA1_5_INT = &cla1Isr5;
PieVectTable.CLA1_6_INT = &cla1Isr6;
PieVectTable.CLA1_7_INT = &cla1Isr7;
PieVectTable.CLA1_8_INT = &cla1Isr8;
//
// Enable CLA interrupts at the group and subgroup levels
//
PieCtrlRegs.PIEIER11.all = 0xFFFF;
IER |= (M_INT11 );
}
void CLA_runTest(void)
{
fVal = 45;
Cla1ForceTask1andWait();
//WAITSTEP;
#if 0
Cla1ForceTask2andWait();
WAITSTEP;
Cla1ForceTask3andWait();
WAITSTEP;
Cla1ForceTask4andWait();
WAITSTEP;
Cla1ForceTask5andWait();
WAITSTEP;
Cla1ForceTask6andWait();
WAITSTEP;
Cla1ForceTask7andWait();
WAITSTEP;
#endif
}
//
// cla1Isr1 - CLA1 ISR 1
//
__interrupt void cla1Isr1 ()
{
//
// Acknowledge the end-of-task interrupt for task 1
//
PieCtrlRegs.PIEACK.all = M_INT11;
LED1_TOGGLE;
//
// Uncomment to halt debugger and stop here
//
// asm(" ESTOP0");
}
//
// cla1Isr1 - CLA1 ISR 2
//
__interrupt void cla1Isr2 ()
{
asm(" ESTOP0");
}
//
// cla1Isr1 - CLA1 ISR 3
//
__interrupt void cla1Isr3 ()
{
asm(" ESTOP0");
}
//
// cla1Isr1 - CLA1 ISR 4
//
__interrupt void cla1Isr4 ()
{
asm(" ESTOP0");
}
//
// cla1Isr1 - CLA1 ISR 5
//
__interrupt void cla1Isr5 ()
{
asm(" ESTOP0");
}
//
// cla1Isr1 - CLA1 ISR 6
//
__interrupt void cla1Isr6 ()
{
asm(" ESTOP0");
}
//
// cla1Isr1 - CLA1 ISR 7
//
__interrupt void cla1Isr7 ()
{
asm(" ESTOP0");
}
//
// cla1Isr1 - CLA1 ISR 8
//
__interrupt void cla1Isr8 ()
{
//
// Acknowledge the end-of-task interrupt for task 8
//
PieCtrlRegs.PIEACK.all = M_INT11;
//
// Uncomment to halt debugger and stop here
//
// asm(" ESTOP0");
}
//
// End of file
//
cla_share.cla
#include <CLA/cla_init.h>
#include "CLAmath.h"
extern float fVal;
extern float fResult;
__interrupt void Cla1Task1 ( void )
{
//__mdebugstop();
fResult = CLAsin(fVal);
//__mdebugstop();
}
interrupt void Cla1Task2 ( void )
{
//fResult = CLAdiv_inline(fVal1, fVal2);
}
interrupt void Cla1Task3 ( void )
{
}
interrupt void Cla1Task4 ( void )
{
}
interrupt void Cla1Task5 ( void )
{
}
interrupt void Cla1Task6 ( void )
{
}
interrupt void Cla1Task7 ( void )
{
}
interrupt void Cla1Task8 ( void )
{
}