我正在尝试向项目中添加 CLA 功能(作为实验)。 项目框架在没有被调用 CLA 任务的情况下运行良好、但一旦我尝试调用一个(简单的计数器增量)、我就会遇到问题。
通过添加断点、我可以看到我正确进入 CLA 任务、我的计数器(DataonlyinCLA)递增、我正确地保留任务、但似乎没有调用与任务关联的中断。 当我继续运行时、程序会保留我的 if 语句、最后会进行复位(我的所有监视变量和寄存器都会被擦除)、处理器会挂起、并在3fe493: 7625 ESTOP0处停止。
如果有人能帮助我解决我的代码有什么问题、甚至能给我一些关于如何找出我的错误的建议、我将永远不胜感激。 我认为我的链接器文件是正确的、因为程序运行时不调用 CLA 任务、我可以运行 CLA 任务一次。 我的 CLA 设置例程在分配存储器方面与链接器文件匹配、因此我不确定现在要查看的位置。 我也无法找到内存位置3fe493处的内容以及我可能在那里结束的原因。
Jon
CCSV7.1.0.00016
程序以4Hz 的频率运行中断以运行某些通信、并以20kHz 的频率运行单独的中断以读取一些 ADC 值并对其进行过滤。
代码片段:
调用 CLA1Task1 (在以20kHz 运行的程序段中):
如果(CURRENT_STACD = TEST_ST&&ControlISRCount >= 200000) //等待200000以确认程序正在正确运行,然后再启动 CLA 任务1。
{
Cla1ForceTask1();
//据我所知、一旦 Cla1Task1完成、CLA 应该在这里触发"cla1_task1_isr"、但这一点从未发生过
}
我的.cla 文件中的任务1代码:
__attribute__((中断)) void Cla1Task1 ( void )
{
DataonlyinCLA=DataonlyinCLA+1; //我看到正在执行此计算
}
链接器 CMD 文件、基于2837xS_RAM_CLA_lnk_CPU1.cmd
MEMORY { PAGE 0://PAGE 0中列出的所有存储器块都定义为程序空间 /* BEGIN 用于"引导至 SARAM"引导加载程序模式*/ BEGIN:origin = 0x000000,length = 0x000002 RAMM0:origin = 0x000122、length = 0x0002DE RAMD0:origin = 0x00B000、length = 0x000800 RAMD1 :origin = 0x00B800,length = 0x000800 RAMLS3:origin = 0x009800,length = 0x000800 RAMLS4:origin = 0x00A000、length = 0x000800 RAMLS5 :origin = 0x00A800,length = 0x000800 reset:origin = 0x3FFFC0,length = 0x000002 RAMGS0 :origin = 0x00C000、length = 0x001000 RAMGS1 :origin = 0x00D000、length = 0x001000 RAMGS2 :origin = 0x00E000、length = 0x001000 RAMGS3 :origin = 0x00F000、length = 0x001000 RAMGS4 :origin = 0x010000,length = 0x001000 FLASHC:origin = 0x084000,length = 0x002000//片上闪存,reserved for CLA*/ page 1://第1页中列出的所有内存块都定义为 data space boot_RSVD :origin = 0x000002、length = 0x000120// M0的一部分,引导 ROM 将使用此栈*/ RAMM1 :origin = 0x000400、length = 0x000400 RAMLS0:origin = 0x008000、length = 0x000800 RAMLS1:origin = 0x008800,length = 0x000800 RAMLS2:origin = 0x009000,length = 0x000800 RAMGS5 :origin = 0x011000,length = 0x001000 RAMGS6 :origin = 0x012000,length = 0x001000 RAMGS7 :origin = 0x013000、length = 0x001000 RAMGS8 :origin = 0x014000、length = 0x001000 RAMGS9 :origin = 0x015000,length = 0x001000 RAMGS10 :origin = 0x016000,length = 0x001000 RAMGS11 :origin = 0x017000、length = 0x001000 RAMGS12 :origin = 0x018000、length = 0x001000 /*仅在、F28377S、F28375S 器件上可用。 移除其他设备上的线路。 */ RAMGS13 :origin = 0x019000、length = 0x001000 /*仅在、F28377S、F28375S 器件上可用。 移除其他设备上的线路。 */ RAMGS14 :origin = 0x01A000、length = 0x001000 /*仅在、F28377S、F28375S 器件上可用。 移除其他设备上的线路。 */ RAMGS15 :origin = 0x01B000、length = 0x001000 /*仅在、F28377S、F28375S 器件上可用。 移除其他设备上的线路。 * / CANA_MSG_RAM :origin = 0x049000、length = 0x000800 CANB_MSG_RAM :origin = 0x04B000、length = 0x000800 CLA1_MSGRAMLOW:origin = 0x001480、length = 0x000080 CLA1_MSGRAMHIGH: origin = 0x001500、length = 0x000080 } SECTIONS { //程序存储 器//>MEMLOC1|MEMLOC2表示尝试存储器位置1、如果不适合、请改用存储器位置2 //>MEMLOC1|MEMLOC2表示在存储器位置1和存储器位置2 codestart 之间拆分 :>开始,页= 0 ramfuncs:> RAMM0,页= 0 .text :>> RAMGS0|RAMGS1|RAMGS2|RAMGS3|RAMGS4,PAGE = 0 .cinit :> RAMM0,page = 0 .pinit :>RAMM0,page = 0 .switch :>RAMM0,page = 0 .reset :>重置,PAGE = 0,TYPE = DSECT //未使用,*/ //数据存储 器.stack :> RAMM1,page = 1.ebss :> RAMLS0,PAGE = 1 .econst :> RAMLS0,页= 1 .esysmem :> RAMLS1,page = 1 .sysmem:> RAMLS1,page = 1 filter_RegsFile:> RAMGS5,page = 1 ramfuncs:> RAMM0 PAGE = 0 /* CLA 特定段*// 程序存储 器 Cla1Prog :>> RAMLS3|RAMLS4|RAMLS5,PAGE=0 //数据存储 器 CLADataLS0:>RAMLS0,PAGE=1 CLADataLS1:>RAMLS1,PAGE=1 //消息存储 器 Cla1ToCpuMsgRAM:>CLA1_MSGRAMSOW,PAGE = 1 CpuCLTo1MsgRAM :>CLA1_CLGRAM,PAGE = 1 CpuCLGRAM:1 CpuCLMCLMGS1,不确定:/CLGRAGRAGRAM:1 > RAMM0、PAGE = 0 /* CLA C 编译器段*/ / ////必须分配给 CLA 具有对 // .scratchpad 写入访问权限的存储器 :> RAMLS1、 PAGE = 1.bss_cla :> RAMLS1、 PAGE = 1.CONST_CLA :> RAMLS1、 页= 1 }
CLA 设置:
void InitCLA (void) { extern uint32_t Cla1ProgRunStart、Cla1ProgLoadStart、Cla1ProgLoadSize; extern uint32_t Cla1funcsRunStart、Cla1funcsLoadStart、Cla1funcsLoadSize; // extern uint32_t CLA1mathTablesRunStart、CLA1mathTablesLoadStart、CLA1mathTablesLoadSize; EALLOW; DevCfgRegs.DC1.bit.CPU1_CLA1 = 1; //初始化并等待 CLA1ToCPUMsgRAM MemCfgRegs.MSGxINIT.bit.init_CLA1TOCPU = 1; while (MemCfgRegs.MSGxINITDONE.bit.INITDONE_CLA1TOCPU!= 1){}; //初始化并等待 CPUToCLA1MsgRAM MemCfgRegs.MSGxINIT.bit.init_CPUTOCLA1 = 1; while (MemCfgRegs.MSGxINITDONE.bit.INITDONE_CPUTOCLA1!= 1){}; //本地共享 RAM 主选择器 MemCfgRegs.LSxMSEL.bit.MSEL_LS0 = 1; //1 =在 CPU 和 CLA1之间共享、0 =仅 CPU MemCfgRegs.LSxMSEL.bit.MSEL_LS1 = 1; //1 =在 CPU 和 CLA1之间共享、0 =仅 CPU MemCfgRegs.LSxMSEL.bit.MSEL_LS2 = 1; //1 =在 CPU 和 CLA1之间共享、0 =仅 CPU MemCfgRegs.LSxMSEL.bit.MSEL_LS3 = 1; //1 =在 CPU 和 CLA1之间共享、0 =仅 CPU MemCfgRegs.LSxMSEL.bit.MSEL_LS4 = 1; //1 =在 CPU 和 CLA1之间共享、0 =仅 CPU MemCfgRegs.LSxMSEL.bit.MSEL_LS5 = 1; //1 =在 CPU 和 CLA1之间共享、0 =仅 CPU //内存配置- CLA 数据内存和 CLA 程序内存选择 MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS0 = 0; //1 = CLA 程序存储器、0 = CLA 数据存储器 MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS1 = 0; //1 = CLA 程序存储器、0 = CLA 数据存储器 MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS2 = 0; //1 = CLA 程序存储器、0 = CLA 数据存储器 MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS3 = 1; //1 = CLA 程序存储器、0 = CLA 数据存储器 MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS4 = 1; //1 = CLA 程序存储器、0 = CLA 数据存储器 MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS5 = 1; //1 = CLA 程序存储器、0 = CLA 数据存储器 //内存写入和提取保护 MemCfgRegs.LSxACCROT0.bit.CPUWRPROT_LS0 = 0; //0 =允许 CPU 写入、1 =阻止 CPU 写入 MemCfgRegs.LSxACCROT0.bit.FETCHPROT_LS0 = 0; //0 =允许 CPU 取指令、1 =阻止 CPU 取指令 MemCfgRegs.LSxACCROT0.bit.CPUWRPROT_LS1 = 0; //0 =允许 CPU 写入、1 =阻止 CPU 写入 MemCfgRegs.LSxACCROT0.bit.FETCHPROT_LS1 = 0; //0 =允许 CPU 取指令、1 =阻止 CPU 取指令 MemCfgRegs.LSxACCROT0.bit.CPUWRPROT_LS2 = 0; //0 =允许 CPU 写入、1 =阻止 CPU 写入 MemCfgRegs.LSxACCROT0.bit.FETCHPROT_LS2 = 0; //0 =允许 CPU 取指令、1 =阻止 CPU 取指令 MemCfgRegs.LSxACCROT0.bit.CPUWRPROT_LS3 = 0; //0 =允许 CPU 写入、1 =阻止 CPU 写入 MemCfgRegs.LSxACCROT0.bit.FETCHPROT_LS3 = 0; //0 =允许 CPU 取指令、1 =阻止 CPU 取指令 MemCfgRegs.LSxACCROT1.bit.CPUWRPROT_LS4 = 0; //0 =允许 CPU 写入、1 =阻止 CPU 写入 MemCfgRegs.LSxACCROT1.bit.FETCHPROT_LS4 = 0; //0 =允许 CPU 取指令、1 =阻止 CPU 取指令 MemCfgRegs.LSxACCROT1.bit.CPUWRPROT_LS5 = 0; //0 =允许 CPU 写入、1 =阻止 CPU 写入 MemCfgRegs.LSxACCROT1.bit.FETCHPROT_LS5 = 0; //0 =允许 CPU 取指令、1 =阻止 CPU 取指令 //为所有 CLA 任务分配地址向量 Cla1Regs.MVECT1 =(uint16_t)(&Cla1Task1); //计算和分配任务1的地址矢量 Cla1Regs.MVECT2 =(uint16_t)(&Cla1Task2); //计算和分配任务2的地址矢量 Cla1Regs.MVECT3 =(uint16_t)(&Cla1Task3); //计算和分配 Task3的地址矢量 Cla1Regs.MVECT4 =(uint16_t)(&Cla1Task4); //计算和分配 Task4的地址矢量 Cla1Regs.MVECT5 =(uint16_t)(&Cla1Task5); //计算和分配 Task5的地址矢量 Cla1Regs.MVECT6 =(uint16_t)(&Cla1Task6); //计算和分配 Task6的地址矢量 Cla1Regs.MVECT7 =(uint16_t)(&Cla1Task7); //计算和分配 Task7的地址矢量 Cla1Regs.MVECT8 =(uint16_t)(&Cla1Task8); //计算和分配 Task8的地址矢量 //--选择任务中断源 /***** 每个任务的触发源(保留未列出的数字)**** / DmaClaSrcSelRegs.CLA1TASSKSRCSEL1.bit.task1 = 0;// 0 =无 8=ADCBINT3 16=ADCDINT1 32=XINT4 42=EPWM7INT 70=TINT2 78=ECAP4INT 95=SD1INT 114=SPIRXINTC DmaClaSrcSelRegs.CLA1TASKSRCSEL1.bit.task2 = 0;// 1=ADCAINT1 9=ADCBINT4 17=ADCDINT2 33=XINT5 43=EPWM8INT 71=MXEVTA 79=ECAP5INT 96=SD2INT DmaClaSrcSelRegs.CLA1TASKSRCSEL1.bit.TASK3 = 0;// 2=ADCAINT2 10=ADCBEVT 18=ADCDINT3 36=EPWM1INT 44=EPWM9INT 72=MREVTA 80=ECAP6INT 107=UPP1INT DmaClaSrcSelRegs.CLA1TASKSRCSEL1.bit.TASK4 = 0;// 3=ADCAINT3 11=ADCCINT1 19=ADCDINT4 37=EPWM2INT 45=EPWM10INT 73=MXEVTB 83=EQEP1INT 109=SPITXINTA DmaClaSrcSelRegs.CLA1TASSKSRCSEL2.bit.TASK5 = 0;// 4=ADCAINT4 12=ADCCINT2 20=ADCDEVT 38=EPWM3INT 46=EPWM11INT 74=MREVTB 84=EQEP2INT 110=SPIRXINTA DmaClaSrcSelRegs.CLA1TASKSRCSEL2.bit.TASK6 = 0;// 5=ADCAEVT 13=ADCCINT3 29=XINT1 39=EPWM4INT 47=EPWM12INT 75=ECAP1INT 85=EQEP3INT 111=SPITXINTB DmaClaSrcSelRegs.CLA1TASKSRCSEL2.bit.TASK7 = 0;// 6=ADCBINT1 14=ADCCINT4 30=XINT2 40=EPWM5INT 48=TINT0 76=ECAP2INT 87=HRCAP1INT 112=SPIRXINTB DmaClaSrcSelRegs.CLA1TASKSRCSEL2.bit.TASK8 = 0;// 7=ADCBINT2 15=ADCCEVT 31=XINT3 41=EPWM6INT 69=TINT1 77=ECAP3INT 88=HRCAP2INT 113=SPITXINTC //-- CLA1TASKSRCSELx 寄存器锁定控制 DmaClaSrcSelRegs.CLA1TASSKSRCSELLOCK.bit.CLA1TASSKSRCSEL1=0; //写入1以锁定(设置后无法清除) DmaClaSrcSelRegs.CLA1TASSKSRCSELLOCK.bit.CLA1TASSKSRCSEL2 = 0; //写入1以锁定(设置后无法清除) Cla1Regs.MCTL.bit.IACKE = 1; //允许软件强制触发 CLA 任务(除了上述设置的中断源之外) Cla1Regs.MIER。ALL = 0x00FF;//为全部8个任务启用中断 PieCtrlRegs.PIEIER11.all = 0xFFFF;//在 PIE 中启用 CLA 中断组 IER |= M_INT11; //允许 CLA 中断组继续到 CPU PieCtrlRegs.PIEACX.ALL = 0xFFFF; //确认所有 PIE 位从新鲜开始 EDIS; PieVectTable.CLA1_1_INT = cla1_Task1_ISR; // CLA 任务1中断的函数指针(任务完成时发回中断) PieVectTable.CLA1_2_INT = cla1_task2_ISR; // CLA 任务2中断的函数指针(任务完成时发回中断) PieVectTable.CLA1_3_INT = cla1_task3_ISR; // CLA 任务3中断的函数指针(任务完成时发回中断) PieVectTable.CLA1_4_INT = cla1_task4_isr; // CLA 任务4中断的函数指针(任务完成时发回中断) PieVectTable.CLA1_5_INT = cla1_Task5_ISR; // CLA 任务5中断的函数指针(任务完成时发回中断) PieVectTable.CLA1_6_INT = cla1_task6_isr; // CLA 任务6中断的函数指针(任务完成时发回中断) PieVectTable.CLA1_7_INT = cla1_task7_ISR; // CLA 任务7中断的函数指针(任务完成时发回中断) PieVectTable.CLA1_8_INT = cla1_task8_ISR; // CLA Task8中断的函数指针(任务完成时发回中断) }