|
2.3性能最优化
常数是那些用C语言的const类型关键词声明的数据结构。编译器把所有的常数放置在.econst段中(假定为大存储模式)。当前TMS320F28xx 器件上的特殊管道(special pipelining)提高Flash上运行代码的性能时.每次访问位于片上Flash中的数据常数会占用许多周期。特别是在150 MHz TMS320F281x DSP上Flash等待状态要达到5个周期.100 MHz TMS320F280x DSP达到3个周期。所以,访问片上RAM中的常数与常数表则成为沉重的负担。然而,分立式嵌入式系统要求所有的初始化数据(如常数)最初都是位于非易失性存储器中,所以,必须为想访问的RAM中的常数建立独立的装载和运行地址.在运行时把这些常数从片上Flash中拷贝到RAM中。这里介绍两种不同的实现方法。
方法一:在RAM中运行所有的常数阵列。
这种方法是为整个.econst段指定独立的装载和运行地址。其好处是容易使用,而坏处是RAM的使用量非常大(可能只有少量常数需要快速访问,但是用这种方法所有的常数都位于RAM)。
在用户连接命令文件中简单地为整个.econst段指定独立的装载和运行地址,然后在运行时通过拷贝整个.econst段的方式往工程中添加代码。例如:
- //User's linker command file
- SECTIONS
- {
- .econst: LOAD=Flash, PAGE=0
- RUN=RAM,PAGE=1
- RUN_STAR(_econst_runstart),
- LOAD_START(_econst_loadstart),
- LOAD_END(_econst_loadend)
- }
- //User's 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-&econst_loadstart();
- }
复制代码
方法二:在RAM中运行特定的常数阵列。
这种方法是在运行时有选择性地从Flash拷贝常数到RAM。与方法一相似,这个流程能够完成预期功能,不同点是只有在命名段中被选择了的常数才会被拷贝到RAM中(而不是把所有的常数都拷贝到RAM中)。
假定想创建在RAM中运行的5个字的常数阵列,并命名为table[]。DATA_SECTION指令用来把table[]放置在名为ramconsts的用户自定义段中。相应的C源程序如下所示:
- #pragma DATA_SECTION(table,"ramconsts")
- const int table[5]={1,2,3,4,5};
- void main()
- {
- }
复制代码
使用用户连接命令文件连接ramconsts段,装载到Flash而从RAM中运行,生成全局符号来帮助存储器拷贝。用户连接命令文件如下所示:
-
-
- SECTIONS
- {
- ramconsts: LOAD=Flash, PAGE=0;
- RUN=RAM,PAGE=1
- LOAD_START{_ramconsts_loadstart},
- LOAD_END{_ramconsts_loadend},
- RUN_START(_ramconsts_runstart)
- }
-
复制代码
最后,在运行时必须把table[]从装载地址拷贝到运行地址:
-
-
- #include
- extern unsigned int ramconsts_loadstart;
- extern unsigned 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配置寄存器同样被保护)。当器件被保护的时候,只有从被保护的存储空间运行的代码可以访问(读或写)其他被保护存储空间中的数据。从非保护的存储空间运行的代码不可以访问被保护存储空间中的数据。
CSM使用128-bit密码组成8个单独的16-bit字。在当前的 TMS320F28xx器件上,这些密码被存储在Flash的最高8个字中(如地址:Ox3F7FF8-Ox3F7FFF)。在开发过程中,建议在密码位置放入假密码0xFFFF。使用假密码时,对CSM解保护只需假读密码位置。把假密码放在密码位置是很容易的.因为在Flash编程过程中.Flash被清除后这些位置的状态将会是0xFFFF。用户只需要在自己的代码工程中避免连接任何段到密码地址,密码将保持为OxFFFF。
在开发完成以后.可能想把真正的密码放在密码位置中。另外,为了正确地保护CSM模块,当前TMS320F28xx器件上的CSM模块需要编写值Ox0000到 Flash的地址0x3F7F80-Ox3F7FF5。完成这两个任务的最简单的方法是用少量汇编语言进行编程。下面是一个汇编代码例子,这个例子指定了想要的密码值,并且把它们放在一个名为pass-words的初始化段中。另外创建了一个名为csm_rsvd的初始化段,这个段的值全部是 0x0000.并且这个段有适当的长度以适合地址Ox3F7F80-0x3F7FF5。注意,这个例子显示的是假密码值0xFFFF.用户可以用自己的密码代替这些假密码。
- **File: 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 passwords.asm
复制代码 |
|