DSP_TMS320F28377D_算法加速方法1_拷贝程序到RAM运行

TI C2000系列的DSP芯片算力有限,用于来控制有时候常会出现控制程序无法实现实时运行的情况,因此从本文开始,将陆续推出几篇DSP算法加速的方法

此方法只需要添加一行代码一个预定义,即可达到算法整体加速的目的。先声明本文是讲的是TMS320F28377D,其他C2000系列芯片操作类似。

1 一行代码

#pragma CODE_SECTION(testfunction,".TI.ramfunc");

或者

#pragma CODE_SECTION(testfunction,"ramfunc");

这行代码,我认为标准做法是放于 "声明testfunction的.h文件"中。这个testfunction就是你需要加速的算法函数。

那上述有两行代码,我到底应该选择哪一行呢? 它们的区别是".TI.ramfunc"和"ramfunc",用哪个其实主要取决于你的编译器版本。 我用的是CCS 7.4.0,这两行代码我都测试过,用"ramfunc"会进入错误异常中断。而用".TI.ramfunc"则功能可正常实现。

DSP_TMS320F28377D_算法加速方法1_拷贝程序到RAM运行_第1张图片

2 一个预定义

 另外需要注意的一点是项目文件需要预定义 _FLASH。 在InitSysCtrl函数中,只有你预定义了_FLASH,才会执行下面这行代码。而这行代码的执行对于我们需要的功能是至关重要的。

memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
void InitSysCtrl(void)
{
    //
    // Disable the watchdog
    //
    DisableDog();


    //
    // Copy time critical code and Flash setup code to RAM. This includes the
    // following functions: InitFlash()
    //
    // The  RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart
    // symbols are created by the linker. Refer to the device .cmd file.
    //
#ifdef _FLASH
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

    //
    // Call Flash Initialization to setup flash waitstates. This function must
    // reside in RAM.
    //
    InitFlash();
#endif

具体操作如下:

DSP_TMS320F28377D_算法加速方法1_拷贝程序到RAM运行_第2张图片

3 测试方法

测试方法很简单,就是对比优化前和优化后测试的功能模块的运行时间。如何获取代码块的运行时间我这里就不赘述了,我以前写过一个相关博客:DSP_TMS320F28377D_使用定时器实现<获取代码块运算时间>的功能_江湖上都叫我秋博的博客-CSDN博客。

4 普通程序测试 

我28377D的程序框架还是延用

DSP_基于TMS320F28377D双核芯片和CCS7.40的编程入门_ccs双核芯片下载_江湖上都叫我秋博的博客-CSDN博客

这篇博客的风格,下面我贴出和测试相关的部分。

main.c

#include 

void main(void)
{
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    InitGpio();
    IER     = 0x0000;
    IFR     = 0x0000;
    InitPieVectTable();
    InitCpuTimers();

    runtime_init();
    while(1){
        runtime_start();
        testfunction();
        runtime_stop();
    }

}

void testfunction(void){
    int i = 0;
    int sum = 0;
    for(i = 0; i < 1000; i++){
        sum = sum+i;
    }
}

main.h

#include 
#include 

#pragma CODE_SECTION(testfunction,".TI.ramfunc");

void testfunction(void);

测试结果

加速前 85us,加速后70us,约加速20%。

5 中断程序测试

除了上述测试以外,我还说测试了中断处理函数。我把testfunction放在中断里面执行。

main.c
#include 

void main(void)
{
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    InitGpio();
    IER     = 0x0000;
    IFR     = 0x0000;
    InitPieVectTable();
    InitCpuTimers();

    /* 定时器中断配置 */
    ConfigCpuTimer(&CpuTimer0, 200, 1000000/5000);
    CpuTimer0Regs.TCR.bit.TIE   = 1;                //  1: The CPU-Timer interrupt is enabled

    // TIMER0 INT1.7 [Page102: Table 3-2.PIE Channel Mapping]
    EALLOW;
    PieVectTable.TIMER0_INT = &CpuTimer0ISR;        //  Specify the interrupt service routine
    EDIS;
    IER |= M_INT1;                                  //  Enable CPU Level interrupt
    PieCtrlRegs.PIEIER1.bit.INTx7   = 1;            //  Enable PIE Level interrupt

    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;              // Enable the PIE block
    EINT;                                           //  Turn on the switch of system global interrupt
    ERTM;
    CpuTimer0Regs.TCR.bit.TSS = 0;                  //  Start CPU Timer 0



    runtime_init();
    while(1){
    }

}

interrupt void CpuTimer0ISR(void){
    runtime_start();
    testfunction();
    runtime_stop();
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

void testfunction(void){
    int i = 0;
    int sum = 0;
    for(i = 0; i < 1000; i++){
        sum = sum+i;
    }
}

main.h

#include 
#include 

interrupt void CpuTimer0ISR(void);
#pragma CODE_SECTION(testfunction,".TI.ramfunc");

void testfunction(void);

测试结果

加速前 90us,加速后70us。  同样的代码,放在中断里面运行还慢了点,这个有点匪夷所思,不过加速后的运算速度是一样的。

注意

这里需要提醒一下, 如果你在中断处理函数里面调用了其他的函数,比如CpuTimer0ISR调用testfunction

#pragma CODE_SECTION(CpuTimer0ISR,".TI.ramfunc");

这样写是无法加速的。

要想实现对中断程序整体的加速,你有三种选择

1 你还是加速testfunction

#pragma CODE_SECTION(testfunction,".TI.ramfunc");

2 你把testfunction函数实现的内容直接写到CpuTimer0ISR里面

#pragma CODE_SECTION(CpuTimer0ISR,".TI.ramfunc");

interrupt void CpuTimer0ISR(void){
    runtime_start();
    // testfunction();
    int i = 0;
    int sum = 0;
    for(i = 0; i < 1000; i++){
        sum = sum+i;
    }
    runtime_stop();
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

3 你把两个函数都搬到RAM里面运行,即

#pragma CODE_SECTION(CpuTimer0ISR,".TI.ramfunc");
#pragma CODE_SECTION(testfunction,".TI.ramfunc");

后续会再推出几篇DSP算法加速的方法与大家探讨。感谢您的阅读,如果您有什么优化方法,欢迎留言分享、收藏点赞

你可能感兴趣的:(DSP,dsp,算法加速)