把DSP TMSFXXX的程序段从flash复制到ram中运行_第1页
把DSP TMSFXXX的程序段从flash复制到ram中运行_第2页
把DSP TMSFXXX的程序段从flash复制到ram中运行_第3页
把DSP TMSFXXX的程序段从flash复制到ram中运行_第4页
把DSP TMSFXXX的程序段从flash复制到ram中运行_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、把DSP TMS320F28XXX的程序段从flash复制到ram中运行翻译自TI应用手册SPRAAU8摘要这个应用报告和相关的代码提供了一种把编译后的程序段从TMS320F28xxx的flash复制到ram的功能,这样可以提高代码的运行速度。这个解决方案在直接启动之后,进入c_int00 C语言代码运行之前实现此功能。本应用报告中所讨论的项目内容和源代码可以从以下网址下载:http1.引言:在许多应用中,代码的执行速度是至关重要的。例如在医疗,监控,电机控制等等一些对时间有严格要求的终端设备。许多应用使用TMS320F28xxx DSCs是因为它的内置flash储存器。内置flash是TMS

2、320F28xxx的一个优势,因为它使得设计者不需要外接flash来储存代码。使用内部flash缺点是访问Flash需要等待状态,这使得程序的运行变慢。在大多数应用中,这不是一个问题。其他一些应用中可能会为了获得最高的运行速度要求无等待状态。内部RAM存储器具有零等待状态,它是易失性存储器。所以,引导的初始化代码段不可以存储在此存储器中。现在提供的解决方案,使得设计者能够在运行时把被编译器初始化的代码段从flash复制到ram里,获得最大的运行速度。这使代码执行从多达15个等待状态的提升到0等待状态。另一种解决方案是只将某些函数从Flash复制到RAM。详见:Running an Applic

3、ation from Internal Flash Memory on the TMS320F28xx DSP(SPRA958)。这种方法应该使用在大多数使用C2000 DSC的应用上,其他要求严格的时序和连续的零等待状态的应用程序应采用这里提出的解决方案。编写汇编程序来完成代码从Flash到RAM的复制。该汇编代码在复位向量后调用c_int00之前执行。这保证了在c_int00调用mian()之前完成复制。有一些工程比较小,可以把所有初始化了的段都复制到ram。然而,其他一些工程的初始化了的段比所有的内部ram还要大。这些工程可能不可以把所有的初始化了的段都复制到ram,但是用这种方法复制其

4、中一部分段。2.编译的代码段:编译器生成的包含代码和数据的多个部分,称为段。这下段被分为两个不同的组:初始化了的和没被初始化的,初始化的部分是由所有的代码,常量和初始化表组成的。下表列出了由编译器产生的初始化段。初始化段段名内容限制.cinit显式初始化的全局变量和静态变量表代码.const显式初始化的全局和静态的const变量和字符串常量不超过64K长度.econst长调用的常量数据中的任何地方.pinit全局对象的构造函数表代码.switchswitch语句产生的表代码或者数据.text可执行代码和常数代码没初始化的段是由未初始化的变量,堆栈和malloc产生的内存。下表列出了由编译器产生

5、的没初始化段。没初始化段段名内容限制.bss全局和静态变量不超过64K长度.ebss长调用的全局或静态变量数据中的任何地方.stack堆栈空间不超过64K长度.sysmemmalloc函数产生的内存不超过64K长度.esysmemfar_malloc函数产生的内存数据中的任何地方一旦编译器生成的这些段,连接器会从各个源文件中取出这些段,并结合它们来创建一个输出文件。连接器命令文件(.cmd)就是用来告诉连接器去哪里找这些段的。初始化段必须分配到非易失性存储器,如flash/ ROM,当电源被撤除时,程序不会消失。未初始化的段可以被分配到RAM中,因为它们是在代码执行期间被初始化的。关于更多编译

6、段和连接的信息,请参见:TMS320C28x Assembly LanguageTools Users Guide (SPRU513) 和 the TMS320C28x Optimizing C/C+ Compiler Users Guide(SPRU514)。德州仪器(TI)提供了多个例子显示如何使用链接器命令文件分配编译段。其中一个就是Running an Application from Internal Flash Memory on the TMS320F28xx DSP (SPRA958)。此应用文档提供的例子,演示了使用基于RAM和Flash的项目的链接器命令文件。3.软件:本应

7、用文档相关的代码文件,包括修改后的版本的CodeStartBranch.asm文件和非DSP/BIOS项目用的文件DSP28xxx_SectionCopy_nonBIOS.asm,由the C/C+ Header Files and Peripheral Examples提供。每个TMS320F28xxx处理器都提供了现成的连接器命令文件。提供的示例项目演示了如何使用这些文件。本应用文档以TMS320F2808为例。该软件独立存放于F28xxx_Flash_to_Ram文件夹中。代码使用的来自the C/C+ Header Files and Peripheral Examples的几个文件,

8、经过了Code Composer Studio 3.3和F28xxx代码生成工具B3版本的测试。3.描述:一般的程序流程是这样子的:code_start->wd_disable->copy_sections->c_int00->mian()。这个软件流程比标准的软件流程仅仅多了调用复制代码段函数。标准的软件流程:code_start->wd_disable->c_int00->mian()。程序开始和关闭看门狗:code_start 和wd_disable 的运行代码由DSP28xxx_CodeStartBranch.asm文件提供。上电后,code_

9、start正常执行,因为它被分配给Flash的引导地址的0x3F7FF6。详见:Running an Application from Internal Flash Memory on the TMS320F28xx DSP(SPRA958)plain view plaincopyprint?1. WD_DISABLE .set 1 ;set to 1 to disable WD, else set to 0 2. .ref copy_sections 3. .global code_start 4. * 5. * Function: codestart section 6. * 7. * D

10、escription: Branch to code starting point 8. * 9. .sect "codestart" 10. code_start: 11. .if WD_DISABLE = 1 12. LB wd_disable ;Branch to watchdog disable code 13. .else 14. LB copy_sections ;Branch to copy_sections 15. .endif WD_DISABLE .set 1 ;set to 1 to disable WD, else set to 0 .ref cop

11、y_sections .global code_start* Function: codestart section* Description: Branch to code starting point* .sect "codestart"code_start: .if WD_DISABLE = 1 LB wd_disable ;Branch to watchdog disable code .else LB copy_sections ;Branch to copy_sections .endif这个函数从the C/C+ Header Files and Periph

12、eral Examples提供的CodeStartBranch.asm文件修改而来,只是第二个调用用copy_sections代替了_c_int00。这个调用仅仅在WD_DISABLE为0时执行。 上面的代码,WD_DISABLE 被设置为1。这使得wd_disable运行。wd_disable的代码如下:plain view plaincopyprint?1. * 2. * Function: wd_disable 3. * 4. * Description: Disables the watchdog timer 5. * 6. .if WD_DISABLE = 1 7. .sect &q

13、uot;wddisable" 8. wd_disable: 9. SETC OBJMODE ;Set OBJMODE for 28x object code 10. EALLOW ;Enable EALLOW protected register access 11. MOVZ DP, #7029h>>6 ;Set data page for WDCR register 12. MOV 7029h, #0068h ;Set WDDIS bit in WDCR to disable WD 13. EDIS ;Disable EALLOW protected register

14、 access 14. LB copy_sections ;Branch to copy_sections 15. .endif * Function: wd_disable* Description: Disables the watchdog timer* .if WD_DISABLE = 1 .sect "wddisable"wd_disable: SETC OBJMODE ;Set OBJMODE for 28x object code EALLOW ;Enable EALLOW protected register access MOVZ DP, #7029h&g

15、t;>6 ;Set data page for WDCR register MOV 7029h, #0068h ;Set WDDIS bit in WDCR to disable WD EDIS ;Disable EALLOW protected register access LB copy_sections ;Branch to copy_sections .endif这要求看门狗在copy_sections和c_int00函数运行期间被除能,否则,看门狗可能会在进入main()之前超时。这个函数也是从the C/C+ Header Files and Peripheral Exam

16、ples提供的CodeStartBranch.asm文件修改而来,只是用copy_sections代替了_c_int00。Copy_sections:DSP28xxx_SectionCopy_nonBIOS.asm文件提供了copy_sections的代码,第一次运行到这里,看门狗是关闭的,段已经准备好被复制,段大小被存放在累加器,装载地址放在XAR6中,执行地址放在XAR7中,这个功能例子如下:plain view plaincopyprint?1. MOVL XAR5,#_text_size ; Store Section Size in XAR5 2. MOVL ACC,XAR5 ; M

17、ove Section Size to ACC 3. MOVL XAR6,#_text_loadstart ; Store Load Starting Address in XAR6 4. MOVL XAR7,#_text_runstart ; Store Run Address in XAR7 5. LCR copy ; Branch to Copy MOVL XAR5,#_text_size ; Store Section Size in XAR5 MOVL ACC,XAR5 ; Move Section Size to ACC MOVL XAR6,#_text_loadstart ; S

18、tore Load Starting Address in XAR6 MOVL XAR7,#_text_runstart ; Store Run Address in XAR7 LCR copy ; Branch to Copy段的大小,装载开始标志,执行开始标志都由连接器产生,这是在内存分配 -链接器命令文件一节讨论。在地址和段长度都被存放好之后,copy程序被调用来确定段是否被编译器产生,这由检测累加器是否为0来确定。plain view plaincopyprint?1. copy: 2. B return,EQ ; Return if ACC is Zero (No section t

19、o copy) 3. RPT AL ; Copy Section From Load Address to 4. | PWRITE *XAR7, *XAR6+ ; Run Address 5. return: 6. LRETR ; Return copy: B return,EQ ; Return if ACC is Zero (No section to copy) RPT AL ; Copy Section From Load Address to | PWRITE *XAR7, *XAR6+ ; Run Addressreturn: LRETR ; Return如果累加器为0,程序会返回

20、到调用前的地址,如果累加器不为0,有段需要被复制。这用上面所示的PWRITE指令来实现,PWRITE复制XAR6指向的存储器的内容到XAR7指向的内容。在这里,就是复制装载代码的地址的内容到运行代码的地址。这样,一直到累加器为0,完成整个段的复制,当所有段都被复制完,程序就会跳到c_int00,如下:plain view plaincopyprint?1. LB _c_int00 ; Branch to start of boot.asm in RTS library LB _c_int00 ; Branch to start of boot.asm in RTS library到这里,C语言

21、环境被建立,main()是可进去的。完整的copy_sections程序请参见相关文件夹中的DSP28xxx_SectionCopy_nonBIOS.asm。内存分配 - 连接命令文件(.cmd):如第二节所述,连接命令文件(.cmd)是用来告诉连接器怎么分配编译器产生的段的。The C/C+ Header Files and Peripheral Examples提供了标准的连接命令文件(.cmd)。相关代码文件中提供了三个链接器命令文件用于配置内存分配。· F280xx_nonBIOS_flash.cmd· F281x_nonBIOS_flash.cmd· F

22、2833x_nonBIOS_flash.cmd每个文件一般都用相同的方法编写,只是在存储器方面有很小的一些差异(特殊设备)。连接命令文件(.cmd)的Memory部分是根据设备的内存空间来连接编译好的段的。详情参见具体控制器的数据手册。下表展示TMS320F2808的存储器映射:TMS320F28xxx系列控制器内置RAM,可以被分配为一个单独的段,或者更多的段,因为它是连续的存储器映射。如上图所示,F2808有映射到存储器空间的L0,L1和H0 SARAMs,允许生成一个大的内存块,这个块可以被CMD文件的MEMORY部分如下定义:plain view plaincopyprint?1. R

23、AM_H0L0L1 : origin = 0x008000, length = 0x004000 /* on-chip RAM */ RAM_H0L0L1 : origin = 0x008000, length = 0x004000 /* on-chip RAM */其余的也可以定义在MEMORY部分,完整的内存分配,请参见相关文件中的CMD文件。链接器命令文件的第二部分是SECTIONS。这是实际编译器把段连接到的存储区。所有DSP28xxx_CodeStartBranch.asm 和 DSP28xxx_SectionCopy_nonBIOS.asm的段都被装载到flash中运行,这部分如下

24、所示分配:plain view plaincopyprint?1. codestart : > BEGIN_FLASH, PAGE = 0 /* Used by file CodeStartBranch.asm */ 2. wddisable : > FLASH_AB, PAGE = 0 /* Used by file CodeStartBranch.asm */ 3. copysections : > FLASH_AB, PAGE = 0 /* Used by file SectionCopy.asm */ codestart : > BEGIN_FLASH, PAG

25、E = 0 /* Used by file CodeStartBranch.asm */wddisable : > FLASH_AB, PAGE = 0 /* Used by file CodeStartBranch.asm */copysections : > FLASH_AB, PAGE = 0 /* Used by file SectionCopy.asm */其他被初始化的段被下载到flash,但是在ram中运行。这是通过load和run指令来实现。下面展示一个例子:plain view plaincopyprint?1. .text : LOAD = FLASH_AB,

26、PAGE = 0 /* Load section to Flash */ 2. RUN = RAM_H0L0L1,PAGE = 0 /* Run section from RAM */ 3. LOAD_START(_text_loadstart), 4. RUN_START(_text_runstart), 5. SIZE(_text_size) .text : LOAD = FLASH_AB, PAGE = 0 /* Load section to Flash */ RUN = RAM_H0L0L1,PAGE = 0 /* Run section from RAM */ LOAD_START

27、(_text_loadstart), RUN_START(_text_runstart), SIZE(_text_size)为了获得与一个段相关联的特定地址,如上所示,使用了LOAD_START, RUN_START, 和SIZE指令。这些指令的地址和大小在DSP28xxx_SectionCopy_nonBIOS.asm文件使用到,用以在复制过程中指向正确的地址。DSP28xxx_SectionCopy_nonBIOS.asm把这些值创建为全局变量,如下图所示plain view plaincopyprint?1. .global _cinit_loadstart, _cinit_runsta

28、rt, _cinit_size 2. .global _const_loadstart, _const_runstart, _const_size 3. .global _econst_loadstart, _econst_runstart, _econst_size 4. .global _pinit_loadstart, _pinit_runstart, _pinit_size 5. .global _switch_loadstart, _switch_runstart, _switch_size 6. .global _text_loadstart, _text_runstart, _t

29、ext_size .global _cinit_loadstart, _cinit_runstart, _cinit_size.global _const_loadstart, _const_runstart, _const_size.global _econst_loadstart, _econst_runstart, _econst_size.global _pinit_loadstart, _pinit_runstart, _pinit_size.global _switch_loadstart, _switch_runstart, _switch_size.global _text_l

30、oadstart, _text_runstart, _text_size测试例子:提供的示例在TMS320F2812,TMS320F2808,TMS320F28335eZdsp开发板上进行了测试。板子上LED的闪烁可以从视觉上证实程序是否正确运行。下面的程序是基于F2808eZdsp评估板设计和测试的。同样的,这种方法可以用于其他eZdsp开发板。Code Composer Studio环境:1.使用USB线连接F2808eZdsp开发板到PC,接上电源线给板子供电。2.打开Code Composer Studio,设置F2808 eZdsp 仿真器。3.打开和编译Example_280xx_

31、Flash_to_RAM_nonBIOS.pjt。4.下载.out文件到芯片的flash中。5.调试程序(debug)。6.运行程序(run)。在eZdsp电路板上的LED应闪烁,表示程序正在运行。应用:现有的Flash应用程序可以很容易地通过移植相关代码文件来实现此功能。基本的移植步骤如下:1.用DSP28xxx_CodeStartBranch.asm替换CodeStartBranch.asm。2.在工程中添加DSP28xxx_SectionCopy_nonBIOS.asm文件。3.用特殊生成的CMD文件代替现有的CMD文件。这个基本步骤不适用于一些特殊情况,比如用户自己定义的段,等应用例子

32、:为了演示的应用程序集成的过程,在C280x,C2801xC / C +头文件和外设示例的Example_2808_Flash.pjt中使用下列步骤移植。1.下载安装C280x, C2801x C/C+ Header Files and Peripheral Examples。2.如上所述连接板,打开项目文件。3.删除项目中的DSP280x_CodeStartBranch.asm文件,在项目中添加DSP28xxx_CodeStartBranch.asm文件。4.在项目中添加DSP28xxx_SectionCopy_nonBIOS.asm文件。5.删除项目中的cmd文件,在项目中添加F280xx

33、_nonBIOS_flash.cmd文件。6.把DSP280x_usDelay.asm中的.sect “ramfuncs”改为.text,使DSP28x_usDelay在被分配在.test段中。7.删除DSP280x_SysCtrl.c文件中的#pragma CODE_SECTION(InitFlash, “ramfuncs”);。使得InitFlash( )函数被分配到.test而不是ramfuncs。8.删除Example_280xFlash.c文件中的#pragma CODE_SECTION(epwm1_timer_isr, “ramfuncs”);和#pragma CODE_SECTION(epwm2_timer_isr, “ramfuncs”);。使得中断服务函数被分配到.test而不是ramfuncs。9.删除Example_280xFlash.c文件中的MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);和InitFlash( );。由于代码已经被复制到RAM,这些是不需要的了。10.如上所述,编译连接程序,把程序下到芯片里运行。在eZd

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论