DSP

DSP TMS320FF28335程序从FLASH中拷贝到RAM中的两种方法及FLASH烧写方法

2019-07-13 16:42发布

DSP的程序下载执行方式有两种:一种是下载到RAM中在线执行,一种是下载到FLASH中执行。在RAM中执行时,具有执行速度快,可以无限次下载的特点,但是RAM的特点是掉电丢失数据。FLASH具有掉电不丢失数据的特点,但是同时存在执行速度慢和擦写次数有限的缺点。因此综合两者的特点,在DSP的开发过程中一般会结合使用两者。在前期程序调试过程,由于需要频繁的擦写,所以一般选择在RAM中进行。而程序调试完成后,由于需要脱离下载器而独立执行,因此需要烧写到掉电不丢失数据的FLASH中。下面将以利用CCS5.2TMS320F28335进行程序在FLASH中的烧写为例,介绍一下将程序烧写到FLASH中的操作过程。 程序从在RAM中执行改为下载到FLASH中需要对工程文件做一些修改。而程序烧写到FLASH中后,又根据程序执行时的存储区间的不同,分为程序部分拷贝到RAM中执行和程序整体拷贝到RAM中执行两种,两种执行需要对工程作不同的修改和设置。    一、程序部分拷贝到RAM中执行   一般当程序过大,大于DSPRAM空间或者对程序执行的速率要求不高时,一般将程序下载到FLASH中执行,并且上电后程序在FLASH中执行,仅仅将个别对时间要求比较高的程序拷贝到RAM中去执行。此时需要作如下修改 : 1首先删除掉工程文件中的28335_RAM_link.cmd文件,改为F28335.cmd文件。如果在自己原来的工程中有对28335_RAM_link.cmd的存储区有特殊修改,可以在F28335.cmd中作同样的修改(仅限于不包括FLASH存储区的部分)。 2、在工程文件中加入文件DSP2833x_MemCopy.c,该文件提供代码赋值的函数。 3、在SECTION中定义ramfuncs段如下所示。段中定义程序下载的区间LOAD(自己指定)、执行的区间RUN(自己指定)、下载开始地址、下载结束地址、执行开始地址(不用改)。                          ramfuncs            : LOAD = FLASHD,                                    RUN = RAML123,                                     LOAD_START(_RamfuncsLoadStart),                                       LOAD_END(_RamfuncsLoadEnd),                                        RUN_START(_RamfuncsRunStart),                                  PAGE = 0    该段定义的作用在于将需要从FLASH中拷贝到RAM的程序归入到该段中从而实现程序从下载地址到执行地址的拷贝。 4在主程序的main之前定义需要拷贝到RAM中的函数,定义语句如下所示            #pragma CODE_SECTION(cpu_timer1_isr,"ramfuncs");        #pragma CODE_SECTION(cpu_timer2_isr,"ramfuncs"); 其作用是将该子函数定义在ramfuncs段中。然后定义下载开始地址、下载结束地址、执行开始地址变量:        extern Uint16 RamfuncsLoadStart;        extern Uint16 RamfuncsLoadEnd;         extern Uint16 RamfuncsRunStart; 5main函数内还需要添加两行代码。添加的位置是在InitPieVectTable();之后,代码如下(不用修改)         MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);              InitFlash(); 6、最后需要将拨码开关调到1111的地方,然后编译烧写即可。 二、程序整体拷贝到RAM中执行 有些时候程序的执行对于速度要求很高,此时就需要将程序整体拷贝到RAM中去执行。程序整体拷贝同样需要进行特殊修改和设置。要想详细了解下面设置的原理,可以查找相关资料来详细了解程序启动的过程。 1、程序启动的过程一般为: code_start->wd_disable->c_int00->mian() 为了完成程序的拷贝,需要在C语言初始化之前插入一个程序拷贝的环节,修改之后的流程为:        code_start->wd_disable->copy_sections->c_int00->mian() 为此在DSP2833x_CodeStartBranch.asm中将所有的c_int00替换为copy_sections 2DSP2833x_CodeStartBranch.asm中将该文件中的wd_disable前的 .text改为 .sect "wddisable"从而将该段程序归入到段wddisable中,并在F28335.cmd文件中定义该段:         wddisable           : > FLASHA,     PAGE = 0 之所以这么定义,是因为.text段是需要拷贝到RAM执行的,而在程序拷贝之前首先需要关闭看门狗,从而避免出现错误。如果仍然将程序放在.text段中,则看门狗禁止程序无法执行,会出现错误,因此在FLASH中定义一个新的段,从而让看门狗关闭的程序在FLASH中提前执行, 3在工程中添加DSP28xxx_SectionCopy_nonBIOS.asm文件,该文件提供对各个段进行拷贝的程序,十分重要。这部分代码不需要修改,直接使用就行。 4、将文件DSP2833x_usDelay.asm中的.sect "ramfuncs"改为  .text。从而将该段代码归入到.text段中,随段拷贝到RAM中执行。 5、删除F28335_sysctrlinit.c文件中的代码: #pragma CODE_SECTION(InitFlash, "ramfuncs"); 从而将InitFlash代码归到.text段中。 6F28335.cmd文件中定义相应的段,代码如下。定义codestartwddisablecopysections 三段在FLASH中执行,定义初始化段的各段的下载区间LOAD、执行区间RUN(前两者存储区间自己选择)、下载开始地址、执行开始地址、段大小(后三者名字不可改变)。注意下面代码、格式以及标点符号必须严格不错。  codestart           : > BEGIN       PAGE = 0      wddisable           : > FLASHA,     PAGE = 0     copysections        : > FLASHA,     PAGE = 0    .cinit              : LOAD = FLASHD,    PAGE = 0                           RUN = RAML123,     PAGE = 0                           LOAD_START(_cinit_loadstart),                           RUN_START(_cinit_runstart),                           SIZE(_cinit_size)       .pinit              : LOAD = FLASHD,    PAGE = 0                            RUN = RAML123,     PAGE = 0                          LOAD_START(_pinit_loadstart),                             RUN_START(_pinit_runstart),                             SIZE(_pinit_size)       .text               : LOAD = FLASHD,    PAGE = 0                           RUN = RAML123,     PAGE = 0                           LOAD_START(_text_loadstart),                           RUN_START(_text_runstart),                           SIZE(_text_size)       .const              : LOAD = FLASHD,    PAGE = 0                              RUN = RAML123,     PAGE = 0                             LOAD_START(_const_loadstart),                             RUN_START(_const_runstart),                              SIZE(_const_size)       .econst             : LOAD = FLASHD,    PAGE = 0                                      RUN = RAML123,     PAGE = 0                             LOAD_START(_econst_loadstart),                             RUN_START(_econst_runstart),                             SIZE(_econst_size)       .switch             : LOAD = FLASHD,    PAGE = 0                              RUN = RAML123,     PAGE = 0                              LOAD_START(_switch_loadstart),                              RUN_START(_switch_runstart),                             SIZE(_switch_size) 7、最后需要将拨码开关调到1111的地方,然后编译烧写即可。 三、程序烧写到FLASH中方法 工程经过上面修改后可以进行编译,编译无错误后就可以烧写到FLASH中了。CCS5.2已经继承了烧写插件,所以无需再下载任何插件,极大的方便了程序的烧写。工程编译后还需要进行一些设置。在project——property——debug——F28335 Flash Settings里作如下图所示的设置:上部根据你所使用的时钟的真实情况设置晶振频率,分频系数和倍频系数。第二部分勾选不变,第三部分可以只勾选自己用到的存储区间,最下方不要更改,以免FLASH误锁后找不到密码。   上面设置完成后就可以直接点击debug按钮,则程序自动烧写到FLASH中,烧写完成后可以在线调试。也可以将下载器拔掉,重新上电,则程序会自动在FLASH中执行。 经过上面的处理,程序烧写到FLASH中就完成了。