ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:25.51KB ,
资源ID:5901799      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5901799.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(DSP中内部Flash的应用研究.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

DSP中内部Flash的应用研究.docx

1、DSP中内部Flash的应用研究1前言TMS320F28xx DSP片内有128 K16 bit字的Flash、两块4 K x16bit字的单周期访问RAM(SARAM)LO和L1、一块8 Kxl6 bit字的单周期访问RAM(SARAM)HO、两块1 Kxl6 bit字的单周期访问RAM(SARAM)M0和M1。由于存储器种类多、容量大,所以从系统的高度来配置各个存储器必须有合适的方法,而这些方法一般都与片内Flash有关。另外,TMS320F28xx DSP片内有看门狗定时器模块(WDT)、引导ROM(ROM bootloader)模块、代码安全模块(CSM),要合理地使用这些模块为整个系

2、统服务,必定也要用到Flash。由此可以看出,Flash的地位和作用比较显著所以本文就Flash的几种用法作了研究。2从Flash拷贝段到RAM21拷贝中断向量在TMS320F28xx器件中,外设扩展中断(PIE)模块管理中断请求。上电时,所有中断向量必须位于非易失性存储器(如Flash)中,但是要把中断向量拷贝到PIEVECT RAM中,这是用户代码中器件初始化程序的一部分。PIEVECT RAM是一个特定的RAM块,它在当前TMS320F28xx器件中是一个25616的块在数据空间中的起始地址为Ox000D00。把中断向量连接到Flash,然后在运行时把中断向量拷贝到PIEVECT RAM

3、中,有许多方法可以实现。一个方法是创建包含函数指针的常量C结构体,该结构体包括128个32-bit向量。如果使用DSP281x或者 DSP280x外设的结构体这个结构体叫做PieVectTableInit,它已经在DSP281x_PieVectc或者 DSP280x_PieVect.c创建(参看TI提供的例程)。因为这个结构体使用const类型关键词,所以它将会被编译器放置在.econst段中。运行时只需要把这个结构体拷贝到PIEVECT RAM中。C编译器运行时支持库包含名为memcpy的存储器拷贝函数,该函数可以被用来完成拷贝任务,其用法如下所示: #includevoid main()/

4、Initialize the pie_ram PieCtrlRegs.PIECTRL.bit.ENPIE=0;/disable the PIE asm( EALLOW); /enable the eallow protected register access memcpy(void*)0x00D00,&ieVectTableInit,256); asm(EDIS); /disable the eallow protected register access以上这个例子为PIE RAM起始地址使用的硬编码地址(hard coded address),明确指定为0x000D00。但是硬编码地址并

5、不是较好的编程方式,用户可以使用DATA_SECTION指令创建一个非初始化的假变量(dummy variable),并把这个变量连接到PIE RAM然后用这个假变量的名字来代替硬编码地址。例如,当使用DSP281x或者DSP280x外设结构体时,创建一个名为PieVectTable的非初始化结构体,并把该结构体连接到PIEVECT RAM。前面例子中的memcpy()函数可以被替换为:memcpy(&ieVectTable,&ieVectTableInit,256);注意拷贝长度是256个16-bit字对应为128个32-bit字。22初始化Flash控制寄存器Flash控制寄存器FOPT、

6、FPWR、:FSTDBY-WAIT、FACTIVEWAIT、 FBANKWAIT、FOTPWAIT的初始化代码不能从Flash存储器当中运行否则就会有不可预料的结果出现。所以,Flash控制寄存器的初始化函数在运行时必须从Flash(它的装载地址)拷贝到RAM(它的运行地址)。Flash控制寄存器由Code Security Module(CSM)保护。如果CSM被保护起来了,那么必须从被保护的RAM(例如:L0或者L1 SARAM)运行Flash控制寄存器的初始化代码,否则Flash控制寄存器的初始化代码无法访问Flash控制寄存器。要注意的是,当器件复位的时候 CSM一般都是被保护起来的,

7、虽然使用假密码0xFFFF时ROM BOOTLOAD-ER会把它解锁。C编译器的 CODE_SECTION指令可以用来为Flash控制寄存器的初始化函数创建独立的可连接段。例如:假定Flash控制寄存器的配置在C函数 InitFlash()中实现,并且想把这个函数放置在名为secureRamFuncs的可连接段当中。下列的C代码例程显示了 CODE_SECTION命令在Flash存储器配置中的正确用法:#pragma CODE_SECTION(InitFlash,”secureRamFuncs)void InitFlash(void)asm(EALLOW);/Enable EALLOW pro

8、tected register asscessFlashRegs.FPWR.bit.PWR=3;/Flash set to active modeFlashRegs.FSTATUS.bit.V3STAT=1;/Clear the 3VSTAT bitFlashRegs.FSTDBYWAIT.bit.STDYYWAIT=0x01FF;/Sleep to standy cyclesFlashRegs.FACTIVEWAIT.bit.ACITIVEWAIT=0x01FF;/Standby to active cyclesFlashRegs.FBANKWAIT.bit.RANDWAIT=3;/F280

9、x Random access wait statesFlashRegs.FBANKWAIT.bit.PAGEWAIT=3;/F280x Paged access wait statesFlashRegs.FOTPWAIT.bit.OTPWAIT=5;/F280x OTP wait statesFlashRegs.FOTP.bit.ENPIPE=1;/Enable the Flash pipelineasm(EDIS);/Disable EALLOW protected register accessasm(RTP #6 | NOP);/end of InitFlash()secureRamF

10、uncs段可以使用用户连接命令文件(.cmd)进行连接。这个段需要独立的装载和运行地址。另外,还想让连接器生成一些全局符号,这些全局符号可以用来决定装载地址、运行地址、段长度。在实现把这个段从装载地址拷贝到它的运行地址时需要这些信息。用户连接命令文件如下所示: *Users linker command fileSETIONSsecureRamFuncsOAD=FLASH,PAGE=0RUN=SECURE_RAM,PAGE=0RUN_START(_secureRamFuncs_runstart),LOAD_START(_secureRamFuncs_loadstart),LOAD_END(_s

11、ecureRamFuncs_loadend)在这个例子中,假定存储器Flash和SECURE_RAM都已经在用户连接命令文件中的MEMORY段中定义。这些存储器的PAGE标识符要与它们的存储器定义相匹配。在上面的例程中假定两个存储空间都已经在PAGE 0(程序存储空间)中声明过了。RUN_START、LOAD_START、LOAD_END指令将生成全局符号,这些全局符号有特定的名称,对应着相应的地址。最后,这个段必须在运行时从Flash拷贝到RAM,可以用到编译器运行支持库里面的函数memcpy()。*Users C_source file#includeextern unsigned int

12、 secureRamFuncs_loadstart;extern unsigned int secureRamFuncs_loadend;extern unsigned int secureRamFuncs_runstart;void main(void) memcpy(&secureRamFuncs_runstart&secureRamFuncs_lo adstart&secureRamFuncs_loadend-&secureRamFuncs_loadstart); InitFlash(); 23性能最优化常数是那些用C语言的const类型关键词声明的数据结构。编译器把所有的常数放置在.e

13、const段中(假定为大存储模式)。当前TMS320F28xx 器件上的特殊管道(special pipelining)提高Flash上运行代码的性能时每次访问位于片上Flash中的数据常数会占用许多周期。特别是在150 MHz TMS320F281x DSP上Flash等待状态要达到5个周期100 MHz TMS320F280x DSP达到3个周期。所以,访问片上RAM中的常数与常数表则成为沉重的负担。然而,分立式嵌入式系统要求所有的初始化数据(如常数)最初都是位于非易失性存储器中,所以,必须为想访问的RAM中的常数建立独立的装载和运行地址在运行时把这些常数从片上Flash中拷贝到RAM中。

14、这里介绍两种不同的实现方法。方法一:在RAM中运行所有的常数阵列。这种方法是为整个.econst段指定独立的装载和运行地址。其好处是容易使用,而坏处是RAM的使用量非常大(可能只有少量常数需要快速访问,但是用这种方法所有的常数都位于RAM)。在用户连接命令文件中简单地为整个.econst段指定独立的装载和运行地址,然后在运行时通过拷贝整个.econst段的方式往工程中添加代码。例如: /Users linker command fileSECTIONS .econst: LOAD=Flash, PAGE=0 RUN=RAM,PAGE=1 RUN_STAR(_econst_runstart),

15、LOAD_START(_econst_loadstart), LOAD_END(_econst_loadend) /Users C-source file#include extern unsigned int secureRamFuncs_loadstart;extern unsigned int secureRamFuncs_loadend;extern unsigned int secureRamFuncs_runstart;void main(void) memcpy(&econst_runstart, &econst_loadstart, &econst_loadend-&econs

16、t_loadstart(); 方法二:在RAM中运行特定的常数阵列。 这种方法是在运行时有选择性地从Flash拷贝常数到RAM。与方法一相似,这个流程能够完成预期功能,不同点是只有在命名段中被选择了的常数才会被拷贝到RAM中(而不是把所有的常数都拷贝到RAM中)。假定想创建在RAM中运行的5个字的常数阵列,并命名为table。DATA_SECTION指令用来把table放置在名为ramconsts的用户自定义段中。相应的C源程序如下所示:#pragma DATA_SECTION(table,ramconsts)const int table5=1,2,3,4,5;void main() 使用用

17、户连接命令文件连接ramconsts段,装载到Flash而从RAM中运行,生成全局符号来帮助存储器拷贝。用户连接命令文件如下所示: SECTIONSramconsts: LOAD=Flash, PAGE=0;RUN=RAM,PAGE=1LOAD_START_ramconsts_loadstart,LOAD_END_ramconsts_loadend,RUN_START(_ramconsts_runstart) 最后,在运行时必须把table从装载地址拷贝到运行地址: #include extern unsigned int ramconsts_loadstart;extern unsigned

18、 int ramconsts_loadend;extern unsigned int ramconsts_runstart;void main(void) memcpy(&ramconsts_runstart, &ramconsts_loadstart, &ramconsts_loadend-&ramconsts_loadstart); 3 CSM密码的编程TMS320F28xx 器件上的代码安全模块CSM提供了保护,防止非法的程序拷贝。在当前的TMS320F28xx器件中,整个Flash、OTP存储器,LO和L1都被 CSM保护(Flash配置寄存器同样被保护)。当器件被保护的时候,只有从被

19、保护的存储空间运行的代码可以访问(读或写)其他被保护存储空间中的数据。从非保护的存储空间运行的代码不可以访问被保护存储空间中的数据。CSM使用128-bit密码组成8个单独的16-bit字。在当前的 TMS320F28xx器件上,这些密码被存储在Flash的最高8个字中(如地址:Ox3F7FF8-Ox3F7FFF)。在开发过程中,建议在密码位置放入假密码0xFFFF。使用假密码时,对CSM解保护只需假读密码位置。把假密码放在密码位置是很容易的因为在Flash编程过程中Flash被清除后这些位置的状态将会是0xFFFF。用户只需要在自己的代码工程中避免连接任何段到密码地址,密码将保持为OxFFF

20、F。在开发完成以后可能想把真正的密码放在密码位置中。另外,为了正确地保护CSM模块,当前TMS320F28xx器件上的CSM模块需要编写值Ox0000到 Flash的地址0x3F7F80-Ox3F7FF5。完成这两个任务的最简单的方法是用少量汇编语言进行编程。下面是一个汇编代码例子,这个例子指定了想要的密码值,并且把它们放在一个名为pass-words的初始化段中。另外创建了一个名为csm_rsvd的初始化段,这个段的值全部是 0x0000并且这个段有适当的长度以适合地址Ox3F7F80-0x3F7FF5。注意,这个例子显示的是假密码值0xFFFF用户可以用自己的密码代替这些假密码。 *Fil

21、e: passwords.asm.sect passwords.int 0xFFFF ; PWL0(LSW of 128-bit password).int 0xFFFF ; PWL1.int 0xFFFF ; PWL2.int 0xFFFF ; PWL3.int 0xFFFF ; PWL4.int 0xFFFF ; PWL5.int 0xFFFF ; PWL6.int 0xFFFF ; PWL7(MSW of 128-bit password).sect csm_rsvd.loop(3F7FF5h-3F7F80h+1).int 0x0000.endloop.end ;end of file

22、passwords.asm在这里必须警告用户:不要把8个密码的值全部设为Ox0000,这样做会永久地锁定CSM模块!passwords和CSB_rsvd段要由用户连接命令文件放置在存储器中。下面的例子适用于当前TMS320F28xx器件(对于其他器件,请参考器件数据手册以确定密码和CSM保留位置的地址)。MEMORYPAGE 0;/*Program Memory*/CSM_RSVD; origin=0x3F7F80, length=0x000076PASSWORDS: origin=0x3F7FF8, length=0x000008PAGE 1:/*Data Memory*/SECTIONSp

23、asswords:ASSWORKS, PAGE=0csm_rsvd:CSM_RSVD,PAGE=0 4 在DSP复位以后从Flash运行代码TMS320F28xx 具有引导ROM(ROM bootloader),器件复位以后ROM bootloader能把代码运行转到Flash中。当引导模式选择引脚被配置为跳转到Flash时ROM bootloader将跳转到Flash中位于地址Ox3F7FF6处的指令。用户需要在这个地址上安排一条指令,这条指令跳转到用户代码。由于CSM密码从地址Ox3F7FF8开始,所以刚好有2个字可用于存放这个跳转指令。并非巧合的是,长跳转指令(在汇编代码中为LB)刚好占

24、用2个字。一般情况下,跳转指令将会跳转到C编译器运行支持库中C环境初始化程序的起始位置。这个程序的人口标号是_c_int00。在这个程序没有运行的时候C代码就不能运行。同样地,有时候在开始运行用户的C应用程序之前需要执行少量的汇编代码(例如:禁止看门狗时钟外设)。这样,跳转指令需要跳转到用户汇编代码的起始位置,需要在Flash中正确定位跳转指令。能达到这个目的的最简单的方法是使用汇编代码。在下面的例子中创建了一个名为Codestart的已命名初始化段这个段包含了一个长跳转可以跳转到C环境初始化程序。需要用用户连接命令文件把codestart段放置在存储器中。 *CodeStartBranch.

25、asm .ref_c_int00 .sect codestart LB_c_int00;branch to start of code .end ; end of file CodeStartBranch.asm用户须在用户连接命令文件MEMORY部分的PAGE 0上定义一个名为BEGIN_Flash的存储器块。Codestart段将被连接到这个存储器块。下面的例子针对当前TMS320F28xx器件对于其他的器件,参考相应的数据手册以确认Flash目标地址的引导。 MEMORYPAGE 0:/*Progrm Memory*/BEGIN_Flash: origin=0x3F7FF6, lengt

26、h=0x000002PAGE 1:/*Data Memory*/SECTIONS/*Jump to Flash boot mode entry point*/codestart:BEGIN_Flash, PAGE=05 C环境引导时禁止看门狗计时C编译器运行时支持库中的C环境初始化函数是_c_int00,它完成全局和静态变量的初始化。包括为每个初始化全局变量把数据从.cinit段(位于片上Flash存储器)拷贝到.ebss段(位于RAM)。例如,当一个全局变量在源代码中声明为: int x=5;5被放置在初始化段.cinit,而符号x被放置在ebss段。然后,_c_int00程序在运行时把 5

27、拷贝到x的位置。当软件中有初始化全局和静态变量的大量数值时。在C环境引导程序完成并且调用main()(这里看门狗可以被配置或被禁止)函数之前看门狗定时器会超时。在代码开发的过程中,这个问题可能不会在RAM中显现出来,因为从cinit段拷贝的数据被连接到RAM后会非常快速地运行。然而,当cinit段连接到内部Flash时。拷贝每个数据将会耗费大量的周期。因为内部Flash存储器缺省为最大等待状态(等待状态仅在用户代码运行到main()后才会被配置)。另外。代码从Flash中实现数据拷贝这又会增加完成数据拷贝需要的时间(代码取指和数据读肯定会访问 Flash)。看门狗超时周期缺省到尽可能的最小值结

28、合这么一个事实,看门狗超时变成真实的可能性。有一个简单的方法使用CCS来检测看门狗超时,步骤如下:(1)为已经写入Flash的代码装载符号(单击FileLoad SymbolsLoad Symbols Only)(2)复位DSP(单击DebugReset CPU)。(3)重新开始DSP(单击DebugRestart)。如果bootloader被设置为Jump to Flash那么无需进行这一步。(4)运行到main()(单击DebugGo_Main)。如果没有到达main(),那么在C环境初始化程序完成之前看门狗很有可能已经溢出。解决看门狗超时问题最简单的办法就是在开始C环境初始化程序之前禁止

29、看门狗。在main()到达之后重新使能看门狗,并且开始正常的代码执行流程。通过将 WDCR寄存器中的WDDIS位设置为1来禁止看门狗。必须使用汇编代码(因为C环境还没有建立)。在上文中,Codestart汇编代码段实现了能跳转到C环境初始化程序_c_int00的跳转指令。为了禁止看门狗,这个跳转要变为跳转到看门狗禁止代码。此看门狗代码然后又跳转到_c_int00的程序。下面的代码例子实现了这些功能:MEMORYPAGE 0:/*Progrm Memory*/BEGIN_Flash: origin=0x3F7FF6, length=0x000002PAGE 1:/*Data Memory*/SE

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1