1.存储器映射
存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程称为存储器映射,如果再分配一个地址就叫重映射.
存储器映射图:
F28335 是采用多级流水线的增强的哈佛总线结构,能够并行访问程序和数据存储空间。在F28335芯片内部集成了大量的不同的存储介质,F28335片上有256K ×16 位的 FLASH,34K×16 位的 SARAM,8K×16 位的 BOOT ROM,2K×16 位的 OPT ROM,采用统一寻址方式(程序、数据和 I/O 统一寻址),从而提高了存储空间的利用率,方便程序的开发。除此之外,F28335 还提供了外部并行扩展接口 XINTF,可进一步外扩存储空间。
代码安全模块 CSM
代码安全模块 CSM 是 F28335 上程序安全性的主要手段,它禁止未授权的用 户访问片内存储器,禁止私有代码的复制或者逆向操作。
1)功能说明
安全模块限制 CPU 去访问片内存储器。实际上,对各种存储器的读/写访 问都是通过 JTAG 端口或外设来进行的,而 CSM 模块所谓的代码安全性主要是 针对片内存储器的访问来定义的,用来禁止未经授权去复制私人代码或数据。 当 CPU 访问片内存储器受到限制的时候,器件即处于保密、“安全”的状态。 当处于保密状态时,根据程序计数器当前指针的位置,可能有两种保护类型。如果当前代码正运行在受保护的内部安全存储器模块上时,仅仅是 JTAG(即仿真器)的访问被阻断,而受安全保护的代码是可以访问受安全保护的数据的,相反,如果代码运行在不受保护的非安全区时,所有对受保护的安全区的访问都被阻 断。用户的代码可以动态地跳进或者跳出受保护的安全区,因此允许程序从不受保护的非安全区域调用函数,类似地,中断服务程序放在了安全受保护区域,而主程序运行在不受保护的非安全区域。因为程序中总是有部分受到保护的。通过 一个 128 位的密码(相当于 8 个 16 位的字)来对安全区来进行加密或解密。这
段密码保存在 FLASH 的最后 8 个字中(0X33FFF8-OX33FFFF),也就是密码区中 (
PWL) ,通过密码匹配( PMF ) , 可以解锁器件。 如果密码保护区中的 128 位数都是同一个数,这个器件不受保护,全是同一个数有两种可能,一种全为 O ,另一种全为 1 ,一个新的 FLASH 或 FLASH 被擦除后,就变为全 1 了,这样只要读一下密码区就能破解,还一种情况就是全为 O ,这时候器件是被加密了,但是不管密钥寄存器的内容是什么,器件都处在加密状态,即该器件无法解锁,这时候芯片就被完全锁住了,因此不要用全 O 作为密码。如果在擦除 FLASH 的期间,芯片复位了,那这个芯片的密码就不确定了,也不能解锁。芯片不能解锁(用全零作为密码、 FLASH 擦除期间复位、忘记密码),这时候芯片就完全锁住了,只能用来调试,而无法重新烧写程序。 用户用来解锁的寄存器为密钥寄存器,在存储空间映射地址为 0x0000 OAEO
-0x0000 0AE7 ,该区域受 EALLOW 保护。当这个 128 位的密钥为全 l 时,密钥寄存器不需要与之匹配。当一开始调试 FLASH 区加密的芯片时,仿真器取得普中 DSP28335 开发攻略 CPU 的控制权需要一定的时间,在此期间, CPU 正在开始运行,并且会执行保护加密区的操作,这个操作会引起仿真器断开连接,有两个方法可以解决这个问题。
1 采用 wait-in-Reset 仿真模式,这种方法是让芯片保持在复位状态直到仿真器得到控制,这种方法要求仿真器要能支持这种模式。
2
采用 Branch to check boot mode 引导。这个方法会持续不停地让引导模式选择引脚。可以选择这种引导模式,一旦仿真器通过重新映射 PC 到另外的地址或者改变引导模式选择引脚以进人引导而进行连接。
总结:通过一个128位的密码(相当于8个16位的字)来对安全区来进行加密或解密。这段密码保存在FLASH的最后8个字中(0X33FFF8-OX33FFFF),也就是密码区中(PWL) ,通过密码匹配( PMF ) , 可以解锁器件。先一般不要动FLASH 的最后 8 个字中(0X33FFF8-OX33FFFF)中内容,防止芯片锁死。需要芯片加密再学习相关代码吧。
2.什么是寄存器和寄存器映射
通过#pragma预处理命令和DATA_SECTION将定义的寄存器指定到相应的存储单元内,并根据功能给存储单元取名,然后即可通过C语言和查阅数据开发手册来操作这些寄存器。 比方说我们找到0x007010这个单元地址,那么可以通过查阅芯片数据手册了解到此单元是系统控制寄存器功能。因此为了更好区分此单元的功能和方便后续的程序开发,可以给这个单元取一个别名SysCtrlRegs,那么这个SysCtrlRegs就是寄存器,并且这个寄存器地址就是0x007010。这个过程就是寄存器映射。
3.如何访问F28335寄存器内容
根据#pragma和DATA_SECTION(这些是CCS软件内特定的)的特点,可以使用#pragma和DATA_SECTION将定义的寄存器与实际的存储单元对应起来,然后再使用C语言操作定义的寄存器,比如使用结构体等。
假如我们要让F28335的GPIOC的第68管脚输出低电平,我们怎么使用 C 语言来处理?
(1)首先要知道GPIO外设每类寄存器所对应存储单元的首地址是哪个,比如GPIO控制寄存器,通过查询数据手册可知其首地址是0x006F80,然后使用#pragma和DATA_SECTION将定义的寄存器与实际的存储单元对应起来。
#pragma DATA_SECTION(GpioCtrlRegs,"GpioCtrlRegsFile");
该定义可在DSP2833x_GlobalVariableDefs.c文件中查找到
volatile struct GPIO_CTRL_REGS GpioCtrlRegs;
GpioCtrlRegsFile是SECTIONS内定义的,该定义可在DSP2833x_Headers_nonBIOS.cmd文件中查找到。
union GPACTRL_REG
{
Uint32 all;
struct GPACTRL_BITS bit;
};
// GPIO A control register bit definitions */
struct GPACTRL_BITS
{ // bits description
Uint16 QUALPRD0:8; // 7:0 Qual period
Uint16 QUALPRD1:8; // 15:8 Qual period
Uint16 QUALPRD2:8; // 23:16 Qual period
Uint16 QUALPRD3:8; // 31:24 Qual period
所以要让GPIO68输出一个低电平可使用C语言调用结构体内成员,如下:
GpioDataRegs.GPCCLEAR.bit.GPIO68=1;//设置GPIO输出低电平信号