目录

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程序移植及使用)相关推荐

  1. java aix 移植linux,[转]程序的可移植性:window,linux,aix,solaris下程序移植体会

    程序的可移植性:window,linux,aix,solaris下程序移植体会 - [工作学习] 1.类型 我们知道,在Windows平台中,系统定义了很多诸如BOOL,CHAR,ULONG,HAND ...

  2. 【转】将 Linux 应用程序移植到 64 位系统上

    原文网址:http://www.ibm.com/developerworks/cn/linux/l-port64.html 随着 64 位体系结构的普及,针对 64 位系统准备好您的 Linux® 软 ...

  3. 小程序 移植 云开发_使用Kubernetes探索跨云的应用程序可移植性

    小程序 移植 云开发 本文与Lindsey Tulloch共同撰写. 在一个快速迁移到云的世界中,投资者,客户和开发人员正在屏息地注视着"云战争". 随着云巨头的崛起以及新型基础架 ...

  4. C语言之字符串探究(三):字符串库函数操作——strlen、strcat、strcpy、strcmp

    相关博文:C++之char和string字符串类探究 相关博文:C语言之数组探究(一):定义.大小.初始化.访问和三要素 相关博文:C语言之字符串探究(一):字符串与字符数组 相关博文:C语言之字符串 ...

  5. 怎样把电脑换linux系统软件,如何将OS/2应用程序移植到Linux操作系统 -电脑资料...

    当从 OS/2 移植到 Linux 时,关键的编程问题是什么? 在转换到 Linux 之前注意一下,提早发现陷阱, 本文是 LAN Distributed Platform(LANDP)for Lin ...

  6. 移植笔记——【MCU程序移植注意事项】

    前言:关于MCU之间的程序移植有很多细节需要关注,以下是做一些记录,后续想到了注意点再来更.   移植处理总体来说可以分成两类:第一类是非程序代码操作的更改,主要是针对不同的MCU设备文件和Flash ...

  7. nRF52832学习记录(十一、TWI总线的应用 SHT21程序移植)

    目录 1.nRF52xx TWI介绍 TWI总线基础介绍 TWI总线寄存器 TWI 库函数介绍 TWI初始化函数 TWI使能函数 TWI 主机发送数据给从机 函数 TWI 主机从从机读取 函数 2.n ...

  8. STM32F103ZET6程序移植为C8T6+C8T6下载程序flash timeout的解决方案

    文章目录 一.程序移植 :程序移植还是蛮简单的 二.程序下载 : 会出现问题 (一)BOOT0和BOOT1 (二)程序下载 1.代码通用 2.状况不断 3.解决办法 (三)STM32F103C8T6下 ...

  9. 瑞萨芯片程序移植到华大芯片,运行过程中出现HardFault

    记录一下遇见的大坑还没找到原因 如果有大佬遇见过同样问题可以唠唠T T 将原瑞萨芯片R5F100FG的程序移植到华大芯片HC32L176MATA上就移植底层的硬件初始化. 应用层逻辑不动,这样就不用自 ...

最新文章

  1. itx机箱尺寸_乔思伯发布ITX机箱V8,采用独特抽拉式结构
  2. 苹果手机微信声音小怎么调大声_成都市苹果手机维修服务网点查询
  3. Nginx could not build the server
  4. mysql 开发进阶篇系列 22 磁盘I/O问题(从linux操作系统上优化)
  5. CSP认证201809-4 再卖菜[C++题解]:差分约束、前缀和
  6. 李开复:AI能在15年内取代40%~50%岗位
  7. 文件管理系统_Python学习第170节--Linux文件管理系统实际操作和具体介绍
  8. jQuery省市联动
  9. mysql primary unique_MySQL中的INDEX,PRIMARY,UNIQUE,FULLTEXT之间的区别?
  10. 监视器(monitor)
  11. 粗看ES6之JSON
  12. win10 object type
  13. linux 安全狗 乱码,打狗棒法之:Cknife(C刀)自定义模式秒过安全狗
  14. 太阳系八大行星直径、质量、与太阳距离参数
  15. 自媒体账号如何注册申请
  16. 第 5 章 数据结构
  17. H3C CAS 5.0 虚拟机备份与还原
  18. Java · 认识 String 类(上)· 创建字符串 · 字符串比较相等 · 字符串常量池 · 字符串不可变 · 字符字节与字符串
  19. 前端实现录音功能 语音录入 弹框录入
  20. 200人 500人规模园区网设计(中小企业网络)

热门文章

  1. STM32F103C8T6制作舵机测试仪详细图文教程 | 定时器触发ADC | DMA传输 | PWM输出 | RTC实时时钟 | USART串口输出 | OLED IIC显示
  2. 没有买卖就没有杀害!大数据可视化技术解密全球象牙贸易黑幕
  3. 京城雪场吃住玩全攻略
  4. 【转】VBO,nbsp;PBO与FBO
  5. lamda 表达式的一些运用
  6. 天池龙珠计划训练营——python3
  7. UnityShader——流光效果
  8. 【AD】关于蛇形布线和等长处理
  9. 封装微信微博QQ分享lib快速使用
  10. 更改eclipse默认在C盘下生成的.p2和.m2的文件方法