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

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

 从标题可以看出本文是一个系列博客,本文是第1篇,其余3篇的链接如下:

DSP_TMS320F28377D_算法加速方法2_添加浮点运算快速补充库rts2800_fpu32_fast_supplement.lib_28377 运算-CSDN博客DSP_TMS320F28377D_算法加速方法3_使用TMU库加速_28377 fpu-CSDN博客

DSP_TMS320F28377D_算法加速方法4_代码本身的优化___divf32函数-CSDN博客

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

目录

1 一行代码

2 一个预定义

3 测试方法

4 普通程序测试 

测试结果

5 中断程序测试

测试结果

注意


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"则功能可正常实现。

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

具体操作如下:

3 测试方法

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

4 普通程序测试 

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

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

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

main.c

#include <main.h>

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 <F28x_Project.h>
#include <runtime.h>

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

void testfunction(void);

测试结果

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

5 中断程序测试

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

main.c
#include <main.h>

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 <F28x_Project.h>
#include <runtime.h>

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算法加速的方法与大家探讨。感谢您的阅读,如果您有什么优化方法,欢迎留言分享、收藏点赞

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江湖上都叫我秋博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值