TMS320F28377D库函数操作(CLA程序移植及使用)
目录
0.写在前面
1.CLA介绍
2.CLA使用前提
3. 初始化程序
4.内存管理
4.1 RAM运行
4.2 FLASH运行
5. 运行程序
5.库文件
6.最后移植完成后的文件
7. 最后效果
0.写在前面
CLA的整个移植过程非常复杂,如果对于初学者可以从下往上看,先能移植起来再看原理
1.CLA介绍
CLA是什么呢?网上有很多说法,什么什么规律加速器,一堆名词着实头疼。其实很简单,在使用DSP的时候,总会有大量的计算,从简单的加减乘除,到正弦,到快速傅里叶,滤波器等都会要计算。此时,如果用CPU就不能操控其他外设了,在这种情况下就可以用CLA了。CLA你可以理解成DSP中专门用于计算的模块,正因如此,CLA不能初始化模块,配置模块,相反在计算是CLA的专场。如果读者用过cortex-M4内核的芯片就知道M4内核的芯片有对DSP库的支持,在DSP里CLA就如同MCU中DSP的作用,是专门用于计算的模块。
2.CLA使用前提
首先在开始前你要对TI的CMD的文件,如果读者是首次接触或是像我一样是STM32开发者转DSP的话,要有一个准备去写CMD文件,那么什么是CMD文件呢?假设芯片内的存储是一个仓库,那么你就是仓库管理员,你需要对仓库的每一部分都很熟悉,哪些地方是可以堆放“危险品”的,哪些地方可以堆放“长期滞留”品的,在STM32中几乎很少会考虑到这些内容,但是在使用DSP的东西是难以避免的。
上图是F28377D的内部存储器映射
可以看到有些区域是CLA可以访问,有些区域是DMA访问的所以在这种情况下你要对这些内存区域熟悉,并能合理的管理每一块区域。通过编写CMD文件合理地管理每一块区域。在CLA的使用中随时都需要你关注内存的情况。
3. 初始化程序
/** CLA_init.c** Created on: 2023年5月1日* Author: 18752*/#include "CLA_init.h"#pragma DATA_SECTION(fVal,"CpuToCla1MsgRAM");
float fVal;
#pragma DATA_SECTION(fResult,"Cla1ToCpuMsgRAM");
float fResult;#pragma DATA_SECTION(IOBuffer,"IOBuffer")
float IOBuffer[(256+1)*2] = {#include "ffttest.h"
};//
// CLA_runTest - Execute CLA task tests for specified vectors
//
void CLA_runTest(unsigned char RTest)
{switch(RTest){case 1: CLA_forceTasks(CLA1_BASE,CLA_TASKFLAG_1); break;case 2: CLA_forceTasks(CLA1_BASE,CLA_TASKFLAG_2); break;}WAITSTEP;
}void CLA_init()
{EALLOW;CLA_DSP_initEpie();CLA_DSP_configClaMemory();CLA_DSP_initCpu1Cla1();EDIS;
}void CLA_DSP_initEpie()
{Interrupt_initModule();Interrupt_initVectorTable();
}void CLA_DSP_configClaMemory(void)
{extern uint32_t Cla1ProgRunStart, Cla1ProgLoadStart, Cla1ProgLoadSize;extern uint32_t CLA1fftTablesRunStart, CLA1fftTablesLoadStart, CLA1fftTablesLoadSize;EALLOW;#ifdef _FLASH// Copy over code and tables from FLASH to RAMmemcpy((uint32_t *)&Cla1ProgRunStart, (uint32_t *)&Cla1ProgLoadStart,(uint32_t)&Cla1ProgLoadSize);memcpy((uint32_t *)&CLA1fftTablesRunStart, (uint32_t *)&CLA1fftTablesLoadStart,(uint32_t)&CLA1fftTablesLoadSize);
#endif //_FLASH// Initialize and wait for CLA1ToCPUMsgRAMMemCfg_initSections(MEMCFG_SECT_MSGCLA1TOCPU);while (!MemCfg_getInitStatus(MEMCFG_SECT_MSGCLA1TOCPU)){};// Initialize and wait for CPUToCLA1MsgRAMMemCfg_initSections(MEMCFG_SECT_MSGCPUTOCLA1);while (!MemCfg_getInitStatus(MEMCFG_SECT_MSGCPUTOCLA1)){};// Select LS0-LS1RAM to be the programming space for the CLA// First configure the CLA to be the master for LS0 and then// set the space to be a program blockMemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS0,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS0,MEMCFG_CLA_MEM_PROGRAM);MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS1,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS1,MEMCFG_CLA_MEM_PROGRAM);//Next configure LS2-LS5RAM as data spaces for the CLA// First configure the CLA to be the master for LSx and then// set the spaces to be code blocksMemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS2,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS2, MEMCFG_CLA_MEM_DATA);MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS3,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS3, MEMCFG_CLA_MEM_DATA);MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS4,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS4, MEMCFG_CLA_MEM_DATA);MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS5,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS5, MEMCFG_CLA_MEM_DATA);}void CLA_DSP_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//
// Suppressing #770-D conversion from pointer to smaller integer
// The CLA address range is 16 bits so the addresses passed to the MVECT
// registers will be in the lower 64KW address space. Turn the warning
// back on after the MVECTs are assigned addresses
//
#pragma diag_suppress=770CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_1,(uint16_t)&Cla1Task1);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_2,(uint16_t)&Cla1Task2);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_3,(uint16_t)&Cla1Task3);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_4,(uint16_t)&Cla1Task4);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_5,(uint16_t)&Cla1Task5);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_6,(uint16_t)&Cla1Task6);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_7,(uint16_t)&Cla1Task7);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_8,(uint16_t)&Cla1Task8);#pragma diag_warning=770// Enable IACK instruction to start a task on CLA in software// for all 8 CLA tasksCLA_enableIACK(CLA1_BASE);CLA_enableTasks(CLA1_BASE, CLA_TASKFLAG_ALL);// Configure the vectors for the end-of-task interrupt for all// 8 tasksInterrupt_register(INT_CLA1_1, &cla1Isr1);Interrupt_register(INT_CLA1_2, &cla1Isr2);Interrupt_register(INT_CLA1_3, &cla1Isr3);Interrupt_register(INT_CLA1_4, &cla1Isr4);Interrupt_register(INT_CLA1_5, &cla1Isr5);Interrupt_register(INT_CLA1_6, &cla1Isr6);Interrupt_register(INT_CLA1_7, &cla1Isr7);Interrupt_register(INT_CLA1_8, &cla1Isr8);
}
这是CLA的存储分配,没错程序里也要有。这是初始化部分,它管理着你内存是如何分配的,没有这部分CLA无法完成初始化。
void CLA_DSP_initEpie()
{Interrupt_initModule();Interrupt_initVectorTable();
}void CLA_DSP_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//
// Suppressing #770-D conversion from pointer to smaller integer
// The CLA address range is 16 bits so the addresses passed to the MVECT
// registers will be in the lower 64KW address space. Turn the warning
// back on after the MVECTs are assigned addresses
//
#pragma diag_suppress=770CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_1,(uint16_t)&Cla1Task1);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_2,(uint16_t)&Cla1Task2);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_3,(uint16_t)&Cla1Task3);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_4,(uint16_t)&Cla1Task4);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_5,(uint16_t)&Cla1Task5);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_6,(uint16_t)&Cla1Task6);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_7,(uint16_t)&Cla1Task7);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_8,(uint16_t)&Cla1Task8);#pragma diag_warning=770// Enable IACK instruction to start a task on CLA in software// for all 8 CLA tasksCLA_enableIACK(CLA1_BASE);CLA_enableTasks(CLA1_BASE, CLA_TASKFLAG_ALL);// Configure the vectors for the end-of-task interrupt for all// 8 tasksInterrupt_register(INT_CLA1_1, &cla1Isr1);Interrupt_register(INT_CLA1_2, &cla1Isr2);Interrupt_register(INT_CLA1_3, &cla1Isr3);Interrupt_register(INT_CLA1_4, &cla1Isr4);Interrupt_register(INT_CLA1_5, &cla1Isr5);Interrupt_register(INT_CLA1_6, &cla1Isr6);Interrupt_register(INT_CLA1_7, &cla1Isr7);Interrupt_register(INT_CLA1_8, &cla1Isr8);
}
这是官方的程序,是对CLA中断之类的初始化
void CLA_init()
{EALLOW;CLA_DSP_initEpie();CLA_DSP_configClaMemory();CLA_DSP_initCpu1Cla1();EDIS;
}
总初始化
void CLA_runTest(unsigned char RTest)
{switch(RTest){case 1: CLA_forceTasks(CLA1_BASE,CLA_TASKFLAG_1); break;case 2: CLA_forceTasks(CLA1_BASE,CLA_TASKFLAG_2); break;}WAITSTEP;
}
这是运行CLA程序,有点类似ADC软件触发一样
上述部分在官方的例程中都有,基本上只要无脑搬基本也没什么问题。
4.内存管理
关于CLA的内存分配问题上,我们主要关注点是LSx RAM内存区域,因为这个区域是CLA运行区域。
可以看到从LS0-LS5的区域CLA是可以存取的所有的CLA程序,运行中所产生的内容都会在这部分区域。除此之外还有一部分就是MSGRAM1和2就是第四行和第五行的内容,这部分内容是CPU与CLA的通信的“桥梁”,通过两个区域,CPU的数据可以转移到CLA内,同时CLA的内容也可以转移到CPU内。
4.1 RAM运行
CLA_SCRATCHPAD_SIZE = 0x100;
--undef_sym=__cla_scratchpad_end
--undef_sym=__cla_scratchpad_startMEMORY
{
//一般用于存放代码
PAGE 0 :BEGIN : origin = 0x000000, length = 0x000002RAMGS0 : origin = 0x00C000, length = 0x001000RAMGS1 : origin = 0x00D000, length = 0x001000RAMGS2 : origin = 0x00E000, length = 0x001000RAMGS3 : origin = 0x00F000, length = 0x001000RAMGS4 : origin = 0x010000, length = 0x001000RAMGS5 : origin = 0x011000, length = 0x001000RESET : origin = 0x3FFFC0, length = 0x000002IQTABLES : origin = 0x3FE000, length = 0x000B50 /* IQ Math Tables in Boot ROM */IQTABLES2 : origin = 0x3FEB50, length = 0x00008CIQTABLES3 : origin = 0x3FEBDC, length = 0x0000AAFLASHA : origin = 0x080002, length = 0x001FFE /* on-chip Flash */FLASHB : origin = 0x082000, length = 0x002000 /* on-chip Flash */FLASHC : origin = 0x084000, length = 0x002000 /* on-chip Flash */FLASHD : origin = 0x086000, length = 0x002000 /* on-chip Flash */FLASHE : origin = 0x088000, length = 0x008000 /* on-chip Flash */FLASHF : origin = 0x090000, length = 0x008000 /* on-chip Flash */FLASHG : origin = 0x098000, length = 0x008000 /* on-chip Flash *///一般用于存放数据
PAGE 1 :BOOT_RSVD : origin = 0x000002, length = 0x00004E /* Part of M0, BOOT rom will use this for stack */RAMM0 : origin = 0x000050, length = 0x0003B0RAMM1 : origin = 0x000400, length = 0x000400RAMD0 : origin = 0x00B000, length = 0x000800RAMD1 : origin = 0x00B800, length = 0x000800RAMGS6 : origin = 0x012000, length = 0x001000RAMGS7 : origin = 0x013000, length = 0x001000RAMGS8 : origin = 0x014000, length = 0x001000RAMGS9 : origin = 0x015000, length = 0x001000RAMGS10 : origin = 0x016000, length = 0x001000RAMGS11 : origin = 0x017000, length = 0x001000RAMGS12 : origin = 0x018000, length = 0x001000RAMGS13 : origin = 0x019000, length = 0x001000RAMGS14 : origin = 0x01A000, length = 0x001000RAMGS15 : origin = 0x01B000, length = 0x001000RAMLS0_1 : origin = 0x008000, length = 0x002000RAMLS2_3 : origin = 0x00A000, length = 0x000A00RAMLS4_5 : origin = 0x00AA00, length = 0x000600CLA1_MSGRAMLOW : origin = 0x001480, length = 0x000080CLA1_MSGRAMHIGH : origin = 0x001500, length = 0x000080CPU2TOCPU1RAM : origin = 0x03F800, length = 0x000400CPU1TOCPU2RAM : origin = 0x03FC00, length = 0x000400FLASHH : origin = 0x0A0000, length = 0x008000 /* on-chip Flash */FLASHI : origin = 0x0A8000, length = 0x008000 /* on-chip Flash */FLASHJ : origin = 0x0B0000, length = 0x008000 /* on-chip Flash */FLASHK : origin = 0x0B8000, length = 0x002000 /* on-chip Flash */FLASHL : origin = 0x0BA000, length = 0x002000 /* on-chip Flash */FLASHM : origin = 0x0BC000, length = 0x002000 /* on-chip Flash */FLASHN : origin = 0x0BE000, length = 0x002000 /* on-chip Flash */
}SECTIONS
{codestart : > BEGIN, PAGE = 0//可存储在flash的字段.text :>> RAMGS0 | RAMGS1 | RAMGS2, PAGE = 0 //程序段.cinit : > RAMGS4, PAGE = 0 //初始化数据.const : > RAMGS4, PAGE = 0 //在EABI mode下与cinit一致,初始化段上电后会复制到bss.bss : > RAMGS4, PAGE = 0 //全局变量和静态变量.bss:output : > RAMGS4, PAGE = 0//重要字段ramfuncs : > RAMM0, PAGE = 1.TI.ramfunc : > RAMM0, PAGE = 1.switch : > RAMM0, PAGE = 1 //switch字段.init_array : > RAMM0, PAGE = 1 //启动时调用的 C++ 构造函数的表.stack : > RAMM1, PAGE = 1 //堆栈,最低至少需要64k.data : > RAMGS7, PAGE = 1 //程序运行中所产生的数据//非重要内存字段.econst : > RAMGS11, PAGE = 1.ebss : > RAMGS11, PAGE = 1 //为使用大寄存器模式时的全局变量和静态变量预留的空间,在程序上电时//cinit空间中的数据复制出来并存储在.ebss中.pinit : > RAMGS11, PAGE = 1 //启动时要调用的构造函数表.cio : > RAMGS11, PAGE = 1 //printf等输入输出函数使用的缓冲区所在的段.sysmem : > RAMGS11, PAGE = 1 //maclloc所用的段//CLA字段IOBuffer : > RAMLS2_3, PAGE = 1Cla1Prog : > RAMLS0_1, PAGE = 1Cla1Prog:cla_dsp_fft : > RAMLS0_1, HIGH PAGE = 1ramfuncs : LOAD = FLASHL,RUN = RAMD0,RUN_START(RamfuncsRunStart),LOAD_START(RamfuncsLoadStart),LOAD_SIZE(RamfuncsLoadSize),PAGE = 1CLA1fftTables : LOAD = FLASHM,RUN = RAMLS4_5,RUN_START(CLA1fftTablesRunStart),LOAD_START(CLA1fftTablesLoadStart),LOAD_SIZE(CLA1fftTablesLoadSize),PAGE = 1Cla1Prog : LOAD = FLASHM,RUN = RAMLS0_1,RUN_START(Cla1ProgRunStart),LOAD_START(Cla1ProgLoadStart),LOAD_SIZE(Cla1ProgLoadSize),PAGE = 1Cla1ToCpuMsgRAM : > CLA1_MSGRAMLOW, PAGE = 1CpuToCla1MsgRAM : > CLA1_MSGRAMHIGH, PAGE = 1/* CLA C compiler sections *///// Must be allocated to memory the CLA has write access to//// CLAscratch is the legacy code model scratch pad. use// .scratchpad in the new modelCLAscratch :{ *.obj(CLAscratch). += CLA_SCRATCHPAD_SIZE;*.obj(CLAscratch_end) }> RAMLS4_5, PAGE = 1.scratchpad : > RAMLS4_5, PAGE = 1.bss_cla : > RAMLS4_5, PAGE = 1.const_cla : > RAMLS4_5, PAGE = 1//自定义字段ramgs0 : > RAMGS14, PAGE = 1MSGRAM_CPU1_TO_CPU2 : > CPU1TOCPU2RAM PAGE = 1MSGRAM_CPU2_TO_CPU1 : > CPU2TOCPU1RAM PAGE = 1.reset : > RESET, PAGE = 0, TYPE = DSECT //未用到
}
4.2 FLASH运行
CLA_SCRATCHPAD_SIZE = 0x100;MEMORY
{
PAGE 0 :BEGIN : origin = 0x080000, length = 0x000002RAMGS0 : origin = 0x00C000, length = 0x001000RAMGS1 : origin = 0x00D000, length = 0x001000RAMGS2 : origin = 0x00E000, length = 0x001000FLASHA : origin = 0x080002, length = 0x001FFE /* on-chip Flash */FLASHB : origin = 0x082000, length = 0x002000 /* on-chip Flash */FLASHC : origin = 0x084000, length = 0x002000 /* on-chip Flash */FLASHD : origin = 0x086000, length = 0x002000 /* on-chip Flash */FLASHE : origin = 0x088000, length = 0x008000 /* on-chip Flash */FLASHF : origin = 0x090000, length = 0x008000 /* on-chip Flash */FLASHG : origin = 0x098000, length = 0x008000 /* on-chip Flash */FLASHH : origin = 0x0A0000, length = 0x008000 /* on-chip Flash */FLASHI : origin = 0x0A8000, length = 0x008000 /* on-chip Flash */RESET : origin = 0x3FFFC0, length = 0x000002PAGE 1 : /* Data Memory *//* Memory (RAM/FLASH) blocks can be moved to PAGE0 for program allocation */BOOT_RSVD : origin = 0x000002, length = 0x00004E /* Part of M0, BOOT rom will use this for stack */RAMM0 : origin = 0x000050, length = 0x0003B0RAMM1 : origin = 0x000400, length = 0x000400RAMD0 : origin = 0x00B000, length = 0x000800RAMD1 : origin = 0x00B800, length = 0x000800RAMGS3 : origin = 0x00F000, length = 0x001000RAMGS4 : origin = 0x010000, length = 0x001000RAMGS5 : origin = 0x011000, length = 0x001000RAMGS6 : origin = 0x012000, length = 0x001000RAMGS7 : origin = 0x013000, length = 0x001000RAMGS8 : origin = 0x014000, length = 0x001000RAMGS9 : origin = 0x015000, length = 0x001000RAMGS10 : origin = 0x016000, length = 0x001000RAMGS11 : origin = 0x017000, length = 0x001000RAMGS12 : origin = 0x018000, length = 0x001000RAMGS13 : origin = 0x019000, length = 0x001000RAMGS14 : origin = 0x01A000, length = 0x001000RAMGS15 : origin = 0x01B000, length = 0x001000RAMLS0_1 : origin = 0x008000, length = 0x002000RAMLS2_3 : origin = 0x00A000, length = 0x000A00RAMLS4_5 : origin = 0x00AA00, length = 0x000600FLASHJ : origin = 0x0B0000, length = 0x008000 /* on-chip Flash */FLASHK : origin = 0x0B8000, length = 0x002000 /* on-chip Flash */FLASHL : origin = 0x0BA000, length = 0x002000 /* on-chip Flash */FLASHM : origin = 0x0BC000, length = 0x002000 /* on-chip Flash */FLASHN : origin = 0x0BE000, length = 0x001FF0 /* on-chip Flash */CPU2TOCPU1RAM : origin = 0x03F800, length = 0x000400CPU1TOCPU2RAM : origin = 0x03FC00, length = 0x000400CLA1_MSGRAMLOW : origin = 0x001480, length = 0x000080CLA1_MSGRAMHIGH : origin = 0x001500, length = 0x000080
}SECTIONS
{codestart : > BEGIN PAGE = 0, ALIGN(8).text : >>FLASHB | FLASHC | FLASHD | FLASHE PAGE = 0, ALIGN(8).cinit : > FLASHG PAGE = 0, ALIGN(8).const : > FLASHG PAGE = 0, ALIGN(8).switch : > FLASHH PAGE = 0, ALIGN(8).init_array : > FLASHH PAGE = 0, ALIGN(8).stack : > RAMM1 PAGE = 1.bss : > RAMGS14, PAGE = 1.bss:output : > RAMGS14, PAGE = 1.bss:cio : > RAMGS14, PAGE = 1.data : > RAMGS14, PAGE = 1.sysmem : > RAMGS14, PAGE = 1.TI.ramfunc : {} LOAD = FLASHJ,RUN = RAMGS15,LOAD_START(RamfuncsLoadStart),LOAD_SIZE(RamfuncsLoadSize),LOAD_END(RamfuncsLoadEnd),RUN_START(RamfuncsRunStart),RUN_SIZE(RamfuncsRunSize),RUN_END(RamfuncsRunEnd),PAGE = 1, ALIGN(8)Cla1Prog:cla_dsp_fft : > RAMLS0_1, HIGH PAGE = 1CLA1fftTables : LOAD = FLASHB,RUN = RAMLS4_5,RUN_START(CLA1fftTablesRunStart),LOAD_START(CLA1fftTablesLoadStart),LOAD_SIZE(CLA1fftTablesLoadSize),PAGE = 1Cla1Prog : LOAD = FLASHK,RUN = RAMLS0_1,RUN_START(Cla1ProgRunStart),LOAD_START(Cla1ProgLoadStart),LOAD_SIZE(Cla1ProgLoadSize),PAGE = 1CLAscratch :{ *.obj(CLAscratch). += CLA_SCRATCHPAD_SIZE;*.obj(CLAscratch_end) } > RAMLS4_5, PAGE = 1Cla1ToCpuMsgRAM : > CLA1_MSGRAMLOW, PAGE = 1CpuToCla1MsgRAM : > CLA1_MSGRAMHIGH, PAGE = 1.scratchpad : > RAMLS4_5, PAGE = 1.bss_cla : > RAMLS4_5, PAGE = 1.const_cla : > RAMLS4_5, PAGE = 1IOBuffer : > RAMLS2_3, PAGE = 1ramgs0 : > RAMGS13, PAGE = 1Filter_RegsFile : > RAMGS15, PAGE = 1Filter1_RegsFile : > RAMGS15, PAGE = 1, fill=0x1111Filter2_RegsFile : > RAMGS15, PAGE = 1, fill=0x2222Filter3_RegsFile : > RAMGS15, PAGE = 1, fill=0x3333Filter4_RegsFile : > RAMGS15, PAGE = 1, fill=0x4444Difference_RegsFile : > RAMGS15, PAGE = 1, fill=0x3333MSGRAM_CPU1_TO_CPU2 : > CPU1TOCPU2RAM PAGE = 1MSGRAM_CPU2_TO_CPU1 : > CPU2TOCPU1RAM PAGE = 1GROUP : > CPU1TOCPU2RAM, PAGE = 1{PUTBUFFERPUTWRITEIDXGETREADIDX}GROUP : > CPU2TOCPU1RAM, PAGE = 1{GETBUFFER : TYPE = DSECTGETWRITEIDX : TYPE = DSECTPUTREADIDX : TYPE = DSECT}.reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */
}
上述程序我就不解释了,如果需要我可以再更新,大家可以留言
5. 运行程序
初始化后,我们如何使用CLA呢?在TI的管理中有一个文件后缀为 xxx.CLA,我们在里面写CLA的运行程序,但是它不同于其他C文件,因为它不允许定义变量,不允许被include,只能写函数和include其他文件。
//
// Included Files
//
#include "CLA_share.h"
#include "cla_cfft.h"
#include "CLAmath.h"extern float fVal; //Holds the input argument to the task
extern float fResult; //The arsine of the input argument__interrupt void Cla1Task1 ( void )
{__mdebugstop();CLA_CFFT_run256Pt();fResult=CLAsin(4.2);
}interrupt void Cla1Task2 ( void )
{fResult=CLAsin(0.5)*4096;
}interrupt void Cla1Task3 ( void )
{}interrupt void Cla1Task4 ( void )
{}interrupt void Cla1Task5 ( void )
{}interrupt void Cla1Task6 ( void )
{}interrupt void Cla1Task7 ( void )
{}interrupt void Cla1Task8 ( void )
{}
这里我就用Task1来介绍了,大家可以先将CLA_CFFT_run256Pt();注释,这是256点的FFT程序。我们先使用CLAsin来做。其作用与math中的sin一致给一个数程序算出sin值,它是用弧度值来计算。
除了上述的CLA文件还有配套的C文件非常重要。所有的中断,
/** CLA_interrupt.c** Created on: 2023年5月1日* Author: 18752*/#include "CLA_interrupt.h"//
// cla1Isr1 - CLA1 ISR 1
//__interrupt void cla1Isr1 ()
{//// Acknowledge the end-of-task interrupt for task 1//Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP11);//// Uncomment to halt debugger and stop here//// asm(" ESTOP0");
}//
// cla1Isr2 - CLA1 ISR 2
//
__interrupt void cla1Isr2 ()
{asm(" ESTOP0");
}//
// cla1Isr3 - CLA1 ISR 3
//
__interrupt void cla1Isr3 ()
{asm(" ESTOP0");
}//
// cla1Isr4 - CLA1 ISR 4
//
__interrupt void cla1Isr4 ()
{asm(" ESTOP0");
}//
// cla1Isr5 - CLA1 ISR 5
//
__interrupt void cla1Isr5 ()
{asm(" ESTOP0");
}//
// cla1Isr6 - CLA1 ISR 6
//
__interrupt void cla1Isr6 ()
{asm(" ESTOP0");
}//
// cla1Isr7 - CLA1 ISR 7
//
__interrupt void cla1Isr7 ()
{asm(" ESTOP0");
}//
// cla1Isr8 - CLA1 ISR 8
//
__interrupt void cla1Isr8 ()
{//// Acknowledge the end-of-task interrupt for task 8//Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP11);//// Uncomment to halt debugger and stop here//
// asm(" ESTOP0");
}
这是CLA的中断文件,我就过多介绍了,抄就完了。
在上述内容之外你还需要找一个C文件定义你的变量,如果想让cla使用则必须先对区域定义,相信大家看到就知道是怎么用的了。
#pragma DATA_SECTION(fVal,"CpuToCla1MsgRAM");
float fVal;
#pragma DATA_SECTION(fResult,"Cla1ToCpuMsgRAM");
float fResult;
CPUtoCLA即CPU的变量放到CLA中,另一个就是CLAtoCPU了。
5.库文件
对于CLA还要依赖的lib文件,其路径是两个。
C2000Ware_4_03_00_00\libraries\boot_rom\f2837xd\rev0\rom_symbol_libs
C2000Ware_4_03_00_00\libraries\math\CLAmath\c28\lib
如果你使用的是elf文件就和我一样配置,如果是legacy可以看文件的后缀开启你用的文件
6.最后移植完成后的文件
下图是文件结构
CLA.init
/** CLA_init.c** Created on: 2023年5月1日* Author: 18752*/#include "CLA_init.h"#pragma DATA_SECTION(fVal,"CpuToCla1MsgRAM");
float fVal;
#pragma DATA_SECTION(fResult,"Cla1ToCpuMsgRAM");
float fResult;#pragma DATA_SECTION(IOBuffer,"IOBuffer")
float IOBuffer[(256+1)*2] = {#include "ffttest.h"
};//
// CLA_runTest - Execute CLA task tests for specified vectors
//
void CLA_runTest(unsigned char RTest)
{switch(RTest){case 1: CLA_forceTasks(CLA1_BASE,CLA_TASKFLAG_1); break;case 2: CLA_forceTasks(CLA1_BASE,CLA_TASKFLAG_2); break;}WAITSTEP;
}void CLA_init()
{EALLOW;CLA_DSP_initEpie();CLA_DSP_configClaMemory();CLA_DSP_initCpu1Cla1();EDIS;
}void CLA_DSP_initEpie()
{Interrupt_initModule();Interrupt_initVectorTable();
}void CLA_DSP_configClaMemory(void)
{extern uint32_t Cla1ProgRunStart, Cla1ProgLoadStart, Cla1ProgLoadSize;extern uint32_t CLA1fftTablesRunStart, CLA1fftTablesLoadStart, CLA1fftTablesLoadSize;EALLOW;#ifdef _FLASH// Copy over code and tables from FLASH to RAMmemcpy((uint32_t *)&Cla1ProgRunStart, (uint32_t *)&Cla1ProgLoadStart,(uint32_t)&Cla1ProgLoadSize);memcpy((uint32_t *)&CLA1fftTablesRunStart, (uint32_t *)&CLA1fftTablesLoadStart,(uint32_t)&CLA1fftTablesLoadSize);
#endif //_FLASH// Initialize and wait for CLA1ToCPUMsgRAMMemCfg_initSections(MEMCFG_SECT_MSGCLA1TOCPU);while (!MemCfg_getInitStatus(MEMCFG_SECT_MSGCLA1TOCPU)){};// Initialize and wait for CPUToCLA1MsgRAMMemCfg_initSections(MEMCFG_SECT_MSGCPUTOCLA1);while (!MemCfg_getInitStatus(MEMCFG_SECT_MSGCPUTOCLA1)){};// Select LS0-LS1RAM to be the programming space for the CLA// First configure the CLA to be the master for LS0 and then// set the space to be a program blockMemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS0,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS0,MEMCFG_CLA_MEM_PROGRAM);MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS1,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS1,MEMCFG_CLA_MEM_PROGRAM);//Next configure LS2-LS5RAM as data spaces for the CLA// First configure the CLA to be the master for LSx and then// set the spaces to be code blocksMemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS2,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS2, MEMCFG_CLA_MEM_DATA);MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS3,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS3, MEMCFG_CLA_MEM_DATA);MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS4,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS4, MEMCFG_CLA_MEM_DATA);MemCfg_setLSRAMMasterSel(MEMCFG_SECT_LS5,MEMCFG_LSRAMMASTER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS5, MEMCFG_CLA_MEM_DATA);}void CLA_DSP_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//
// Suppressing #770-D conversion from pointer to smaller integer
// The CLA address range is 16 bits so the addresses passed to the MVECT
// registers will be in the lower 64KW address space. Turn the warning
// back on after the MVECTs are assigned addresses
//
#pragma diag_suppress=770CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_1,(uint16_t)&Cla1Task1);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_2,(uint16_t)&Cla1Task2);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_3,(uint16_t)&Cla1Task3);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_4,(uint16_t)&Cla1Task4);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_5,(uint16_t)&Cla1Task5);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_6,(uint16_t)&Cla1Task6);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_7,(uint16_t)&Cla1Task7);CLA_mapTaskVector(CLA1_BASE,CLA_MVECT_8,(uint16_t)&Cla1Task8);#pragma diag_warning=770// Enable IACK instruction to start a task on CLA in software// for all 8 CLA tasksCLA_enableIACK(CLA1_BASE);CLA_enableTasks(CLA1_BASE, CLA_TASKFLAG_ALL);// Configure the vectors for the end-of-task interrupt for all// 8 tasksInterrupt_register(INT_CLA1_1, &cla1Isr1);Interrupt_register(INT_CLA1_2, &cla1Isr2);Interrupt_register(INT_CLA1_3, &cla1Isr3);Interrupt_register(INT_CLA1_4, &cla1Isr4);Interrupt_register(INT_CLA1_5, &cla1Isr5);Interrupt_register(INT_CLA1_6, &cla1Isr6);Interrupt_register(INT_CLA1_7, &cla1Isr7);Interrupt_register(INT_CLA1_8, &cla1Isr8);
}
CLA_init.h
/** CLA_init.h** Created on: 2023年5月1日* Author: 18752*/#ifndef CLA_CLA_INIT_H_
#define CLA_CLA_INIT_H_//
// Included Files
//#include "driverlib.h"
#include "device.h"#define FFTLENGTH 256//*****************************************************************************
//
// CLA Configurations
//
//*****************************************************************************
#define myCLA0_BASE CLA1_BASE//
// 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.
//
__attribute__((interrupt)) void Cla1Task1();
__attribute__((interrupt)) void Cla1Task2();
__attribute__((interrupt)) void Cla1Task3();
__attribute__((interrupt)) void Cla1Task4();
__attribute__((interrupt)) void Cla1Task5();
__attribute__((interrupt)) void Cla1Task6();
__attribute__((interrupt)) void Cla1Task7();
__attribute__((interrupt)) void Cla1Task8();
void myCLA0_init();//*****************************************************************************
//
// INTERRUPT Configurations
//
//*****************************************************************************// Interrupt Settings for INT_myCLA01
#define INT_myCLA01 INT_CLA1_1
#define INT_myCLA01_INTERRUPT_ACK_GROUP INTERRUPT_ACK_GROUP11
extern __interrupt void cla1Isr1(void);// Interrupt Settings for INT_myCLA02
#define INT_myCLA02 INT_CLA1_2
#define INT_myCLA02_INTERRUPT_ACK_GROUP INTERRUPT_ACK_GROUP11
extern __interrupt void cla1Isr2(void);// Interrupt Settings for INT_myCLA03
#define INT_myCLA03 INT_CLA1_3
#define INT_myCLA03_INTERRUPT_ACK_GROUP INTERRUPT_ACK_GROUP11
extern __interrupt void cla1Isr3(void);// Interrupt Settings for INT_myCLA04
#define INT_myCLA04 INT_CLA1_4
#define INT_myCLA04_INTERRUPT_ACK_GROUP INTERRUPT_ACK_GROUP11
extern __interrupt void cla1Isr4(void);// Interrupt Settings for INT_myCLA05
#define INT_myCLA05 INT_CLA1_5
#define INT_myCLA05_INTERRUPT_ACK_GROUP INTERRUPT_ACK_GROUP11
extern __interrupt void cla1Isr5(void);// Interrupt Settings for INT_myCLA06
#define INT_myCLA06 INT_CLA1_6
#define INT_myCLA06_INTERRUPT_ACK_GROUP INTERRUPT_ACK_GROUP11
extern __interrupt void cla1Isr6(void);// Interrupt Settings for INT_myCLA07
#define INT_myCLA07 INT_CLA1_7
#define INT_myCLA07_INTERRUPT_ACK_GROUP INTERRUPT_ACK_GROUP11
extern __interrupt void cla1Isr7(void);// Interrupt Settings for INT_myCLA08
#define INT_myCLA08 INT_CLA1_8
#define INT_myCLA08_INTERRUPT_ACK_GROUP INTERRUPT_ACK_GROUP11
extern __interrupt void cla1Isr8(void);//*****************************************************************************
//
// MEMCFG Configurations
//
//*****************************************************************************void CLA_init();
// \brief Initialize system clocks
//
void CLA_DSP_initSystemClocks(void);// \brief Initialize Enhanced PIE
//
void CLA_DSP_initEpie(void);// \brief Configure CLA memory space
//
void CLA_DSP_configClaMemory(void);// \brief Intialize the MVECT registers for the CLA
//
void CLA_DSP_initCpu1Cla1(void);
void CLA_runTest(unsigned char RTest);#define WAITSTEP asm(" RPT #255 || NOP")#endif /* CLA_CLA_INIT_H_ */
CLA_initerrupt.c
/** CLA_interrupt.c** Created on: 2023年5月1日* Author: 18752*/#include "CLA_interrupt.h"//
// cla1Isr1 - CLA1 ISR 1
//__interrupt void cla1Isr1 ()
{//// Acknowledge the end-of-task interrupt for task 1//Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP11);//// Uncomment to halt debugger and stop here//// asm(" ESTOP0");
}//
// cla1Isr2 - CLA1 ISR 2
//
__interrupt void cla1Isr2 ()
{asm(" ESTOP0");
}//
// cla1Isr3 - CLA1 ISR 3
//
__interrupt void cla1Isr3 ()
{asm(" ESTOP0");
}//
// cla1Isr4 - CLA1 ISR 4
//
__interrupt void cla1Isr4 ()
{asm(" ESTOP0");
}//
// cla1Isr5 - CLA1 ISR 5
//
__interrupt void cla1Isr5 ()
{asm(" ESTOP0");
}//
// cla1Isr6 - CLA1 ISR 6
//
__interrupt void cla1Isr6 ()
{asm(" ESTOP0");
}//
// cla1Isr7 - CLA1 ISR 7
//
__interrupt void cla1Isr7 ()
{asm(" ESTOP0");
}//
// cla1Isr8 - CLA1 ISR 8
//
__interrupt void cla1Isr8 ()
{//// Acknowledge the end-of-task interrupt for task 8//Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP11);//// Uncomment to halt debugger and stop here//
// asm(" ESTOP0");
}
CLA_initerrupt.h
/** CLA_interrupt.h** Created on: 2023年5月1日* Author: 18752*/#ifndef CLA_CLA_INTERRUPT_H_
#define CLA_CLA_INTERRUPT_H_#include "interrupt.h"#endif /* CLA_CLA_INTERRUPT_H_ */
CLA_share.h
/** CLA_share.h** Created on: 2023年5月1日* Author: 18752*/#ifndef CLA_CLA_SHARE_H_
#define CLA_CLA_SHARE_H_#include <stdint.h>//
// Defines
//
#define PI 3.141592653589extern float fVal;
extern float fResult;__interrupt void Cla1Task1();
__interrupt void Cla1Task2();
__interrupt void Cla1Task3();
__interrupt void Cla1Task4();
__interrupt void Cla1Task5();
__interrupt void Cla1Task6();
__interrupt void Cla1Task7();
__interrupt void Cla1Task8();#endif /* CLA_CLA_SHARE_H_ */
MyCLA.cla
//
// Included Files
//
#include "CLA_share.h"
#include "cla_cfft.h"
#include "CLAmath.h"extern float fVal; //Holds the input argument to the task
extern float fResult; //The arsine of the input argument__interrupt void Cla1Task1 ( void )
{__mdebugstop();CLA_CFFT_run256Pt();fResult=CLAsin(4.2);
}interrupt void Cla1Task2 ( void )
{fResult=CLAsin(0.5)*4096;
}interrupt void Cla1Task3 ( void )
{}interrupt void Cla1Task4 ( void )
{}interrupt void Cla1Task5 ( void )
{}interrupt void Cla1Task6 ( void )
{}interrupt void Cla1Task7 ( void )
{}interrupt void Cla1Task8 ( void )
{}
7. 最后效果
可以看到cla初始化后fresult是0
cla运行完成后是0.707与计算器算的是一样的
TMS320F28377D库函数操作(CLA程序移植及使用)相关推荐
- java aix 移植linux,[转]程序的可移植性:window,linux,aix,solaris下程序移植体会
程序的可移植性:window,linux,aix,solaris下程序移植体会 - [工作学习] 1.类型 我们知道,在Windows平台中,系统定义了很多诸如BOOL,CHAR,ULONG,HAND ...
- 【转】将 Linux 应用程序移植到 64 位系统上
原文网址:http://www.ibm.com/developerworks/cn/linux/l-port64.html 随着 64 位体系结构的普及,针对 64 位系统准备好您的 Linux® 软 ...
- 小程序 移植 云开发_使用Kubernetes探索跨云的应用程序可移植性
小程序 移植 云开发 本文与Lindsey Tulloch共同撰写. 在一个快速迁移到云的世界中,投资者,客户和开发人员正在屏息地注视着"云战争". 随着云巨头的崛起以及新型基础架 ...
- C语言之字符串探究(三):字符串库函数操作——strlen、strcat、strcpy、strcmp
相关博文:C++之char和string字符串类探究 相关博文:C语言之数组探究(一):定义.大小.初始化.访问和三要素 相关博文:C语言之字符串探究(一):字符串与字符数组 相关博文:C语言之字符串 ...
- 怎样把电脑换linux系统软件,如何将OS/2应用程序移植到Linux操作系统 -电脑资料...
当从 OS/2 移植到 Linux 时,关键的编程问题是什么? 在转换到 Linux 之前注意一下,提早发现陷阱, 本文是 LAN Distributed Platform(LANDP)for Lin ...
- 移植笔记——【MCU程序移植注意事项】
前言:关于MCU之间的程序移植有很多细节需要关注,以下是做一些记录,后续想到了注意点再来更. 移植处理总体来说可以分成两类:第一类是非程序代码操作的更改,主要是针对不同的MCU设备文件和Flash ...
- nRF52832学习记录(十一、TWI总线的应用 SHT21程序移植)
目录 1.nRF52xx TWI介绍 TWI总线基础介绍 TWI总线寄存器 TWI 库函数介绍 TWI初始化函数 TWI使能函数 TWI 主机发送数据给从机 函数 TWI 主机从从机读取 函数 2.n ...
- STM32F103ZET6程序移植为C8T6+C8T6下载程序flash timeout的解决方案
文章目录 一.程序移植 :程序移植还是蛮简单的 二.程序下载 : 会出现问题 (一)BOOT0和BOOT1 (二)程序下载 1.代码通用 2.状况不断 3.解决办法 (三)STM32F103C8T6下 ...
- 瑞萨芯片程序移植到华大芯片,运行过程中出现HardFault
记录一下遇见的大坑还没找到原因 如果有大佬遇见过同样问题可以唠唠T T 将原瑞萨芯片R5F100FG的程序移植到华大芯片HC32L176MATA上就移植底层的硬件初始化. 应用层逻辑不动,这样就不用自 ...
最新文章
- itx机箱尺寸_乔思伯发布ITX机箱V8,采用独特抽拉式结构
- 苹果手机微信声音小怎么调大声_成都市苹果手机维修服务网点查询
- Nginx could not build the server
- mysql 开发进阶篇系列 22 磁盘I/O问题(从linux操作系统上优化)
- CSP认证201809-4	再卖菜[C++题解]:差分约束、前缀和
- 李开复:AI能在15年内取代40%~50%岗位
- 文件管理系统_Python学习第170节--Linux文件管理系统实际操作和具体介绍
- jQuery省市联动
- mysql primary unique_MySQL中的INDEX,PRIMARY,UNIQUE,FULLTEXT之间的区别?
- 监视器(monitor)
- 粗看ES6之JSON
- win10 object type
- linux 安全狗 乱码,打狗棒法之:Cknife(C刀)自定义模式秒过安全狗
- 太阳系八大行星直径、质量、与太阳距离参数
- 自媒体账号如何注册申请
- 第 5 章 数据结构
- H3C CAS 5.0 虚拟机备份与还原
- Java · 认识 String 类(上)· 创建字符串 · 字符串比较相等 · 字符串常量池 · 字符串不可变 · 字符字节与字符串
- 前端实现录音功能 语音录入 弹框录入
- 200人 500人规模园区网设计(中小企业网络)
热门文章
- STM32F103C8T6制作舵机测试仪详细图文教程 | 定时器触发ADC | DMA传输 | PWM输出 | RTC实时时钟 | USART串口输出 | OLED IIC显示
- 没有买卖就没有杀害!大数据可视化技术解密全球象牙贸易黑幕
- 京城雪场吃住玩全攻略
- 【转】VBO,nbsp;PBO与FBO
- lamda 表达式的一些运用
- 天池龙珠计划训练营——python3
- UnityShader——流光效果
- 【AD】关于蛇形布线和等长处理
- 封装微信微博QQ分享lib快速使用
- 更改eclipse默认在C盘下生成的.p2和.m2的文件方法