基于EDMA的TMS320C6713片外Flash自举引导
扫描二维码
随时随地手机看文章
摘要:在基于DSP的系统设计中,为了保证掉电时程序不丢失,总是将程序保存在非易失性存储器中,以便系统在上电复位时可将其引导到DSP内部的RAM中执行。以TI公司的TMS320C6713浮点DSP和AMD公司的AM29LV040Flash存储器为例,通过JTAG加载来设计一个完整的自举引导方案。着重描述了引导引脚以及相关寄存器的设置,分析了采用EDMA传输方式将代码从Flash复制到DSP的过程,并对引导程序给出基于汇编语言的代码实现。工程实践证明,该设计方案是可行、有效的。
关键词:TMS320C6713;自举引导;Flash
引言
在许多基于DSP的系统设计中,程序代码总是保存在ROM、Flash或其他非易失存储器中,以保证掉电时代码仍存在,因此必须要解决引导装载的问题。自举引导(Bootload)是指系统上电时,DSP将一段存储在外部非易失性存储器的代码搬移到内部的高速存储器单元中执行(如片内RAM)。本文以TI 公司的TMS320C6713(以下简称为C6713)浮点DSP和AMD公司的AM29LV040Flash存储器为例,通过JTAG口加载来设计一个完整的引导装载方案。
TMS320C6713的引导配置
外部信号BOOTMODE[4:3]决定了C6713的引导配置,在RESET信号的上升沿BOOTMODE[4:3]信号被获取。C6713DSP只有2种引导方式:
(1)ROM/Flash引导。外部存储器的一部分通过EDMA控制器拷贝到DSP内部地址0处。尽管引导程序在器件从外部复位释放后才开始执行,但在 CPU被保持在内部复位时,这个拷贝就进行了。Flash宽度也通过BOOTMODE[4:3]选择。在Flash宽度小于32bit的情况下,DSP通过EMIF读取时,可以自动将相邻的8bit字节或16bit半字打包形成32bit的指令字,并且这些数值在外部存储器中可以通过设定HD8来确定 endian存储模式。
(2)主机引导。核心CPU停留在复位状态,器件其余部分保持正常状态。外部主机通过HPI或扩展总线初始化CPU的存储空间。在必要的初始化完成之后,主机在HPI控制寄存器的DSPINT位写1,这个写操作引起DSPINT信号的跳变,从而导致引导配置逻辑使CPU脱离复位状态,然后CPU从地址0处开始运行。
Flash引导模式的实现
硬件设计
C6713引导引脚说明如表1所列。
设计时将DSP主机口引脚HD[4:3]中的HD4通过下拉电阻接地,HD3通过上拉电阻接3.3V电源,即HD[4:3]=01B。C6713的 EMIF含有4个CE空间寄存器,由于Flash加载程序是从CE1空间搬入的,因此DSP的CE1与Flash(AM29LV040)的片选相连,这种连接将Flash的内部地址映射到DSP的0x90000000处,从而完成了基本的硬件设计。DSP与Flash接口的硬件连接如图1所示。
图1 DSP与Flash的引脚连接
引导程序的设计
Flash存储器的擦除
在对AM29LV040Flash进行读写操作之前,应对其进行擦除,擦除操作需要6个总线周期:
(1)向555H地址的存储单元写入数据AAH;
(2)向2AAH地址的存储单元写入数据55H;
(3)向555H地址的存储单元写入数据80H;
(4)向555H地址的存储单元写入数据AAH;
(5)向2AAH地址的存储单元写入数据55H;
(6)向555H地址的存储单元写入数据10H;
完成上述操作后,Flash存储器完全擦除。
在CCS环境下,用C语言编写上述操作如下:
voidFlash_Erase()
{
*(char*)FLASH_ADR1=0xAA;
*(char*)FLASH_ADR2=0x55;
*(char*)FLASH_ADR1=0x80;
*(char*)FLASH_ADR1=0xAA;
*(char*)FLASH_ADR2=0x55;
*(char*)FLASH_ADR1=0x10;
}
根据前面的设计,Flash的内部地址已经映射到C6713的CE1空间,其开始地址为0x90000000。因此FLASH_ADR1,FLASH_ADR2的定义如下:
#define FLASH_ADR1 0x90000555
#define FLASH_ADR2 0x900002AA
汇编源代码文件
对于C6713而言,DSP上电复位后,EDMA自动从CE1空间拷贝1KB数据(引导代码应定位与此)到地址0处,然后从0地址处开始执行引导代码指令。本引导代码的主要功能是将用户程序段从Flash复制到DSP内部RAM中,然后再跳转到程序的入口处开始执行主程序。在引导程序内复制程序段要使用 EDMA,以快速、灵活地实现DSP存储空间内数据的搬移。数据搬移的源/目的可以是片内存储器、片内外设或外部器件。而此时需要对EDMA的源、目的地址、搬移长度以及基本的传输方式进行相关的设置,如表2所示,然后运用汇编语言编程加入到引导程序即可。
核心引导程序如下:
.sect“.BootCode” ;将引导代码分配到BootCode段中
.global myBootCode
.ref_c_int00 ;C程序的入口地址
MVKL .S1EDMA0_OPT ,A5
MVKL . S10x50010001 ,B4 ;低16bit写入寄存器
MVKH .S1EDMA0_OPT ,A5
MVKH .S10x50010001 ,B4 ;高16bit写入寄存器
STW .D1B4,*A5 ;装载EDMA的OPT参数
MVKL .S1EDMA0_SRA ,A5
MVKL .S10x90001000 ,B4 ;低16bit写入寄存器
MVKH .S1EDMA0_SRA ,A5
MVKH .S10x90001000 ,B4 ;高16bit写入寄存器
STW.D1B4,*A5 ;装载EDMA的SRC参数
....
....
接下来启动EDMA复制主程序段:CPU可以通过写事件置位寄存器(ESR)启动一个EDMA通道。 ESR中某一位写1时,将强行触发对应的事件。程序如下:
MVKL .S10x00000001, B4
MVKL .S1EDMA_ESR, A5 ;低16bit写入寄存器
MVKH .S1EDMA_ESR, A5
MVKH .S10x00000001, B4 ;高16bit写入寄存器
STW .D1 B4, *A5 ;将ESR第一位置1
NOP5
传输结束后,跳转到C程序的入口地址 _c_int00处,开始执行主程序:
MVKL .S2_c_int00, B0
MVKH .S2_c_int00, B0
B.S2B0
NOP5
链接命令文件
链接命令文件是DSP开发过程中生成可执行文件(.out)必不可少的一个环节。它对段的功能有2 个,一是将由汇编器产生的COFF格式的OBJ文件作为输入块,当有多个文件进行链接时,将相应的段结合在一起生成可执行输出模块;二是重新定位,将输出的段分配到存储器中的指定地址。
编写命令文件时,有时希望将代码装入存储器的一个地方,而在另一个地方运行。例如:一些关键的执行代码必须装在系统的ROM中,但希望在较快的RAM中运行。链接器提供了一个处理该问题的简单方法。利用SECTIONS伪指令选项可让链接器定位2次。第一次使用装载关键字load设置装入地址,再使用运行关键字run设置它的运行地址。装载地址确定段的原始数据或代码装入的地方,而任何对段的引用则参考它的运行地址。在应用中必须将该段从装载地址复制到运行地址,本引导程序便使用EDMA方式完成这一复制过程。链接命令文件(boot.cmd)如下:
MEMORY
{
VEC:ORG=0x00000000,LEN=0x00001000
PMEM:ORG=0x00001000,LEN=0x00004000
CEVEC:ORG=0x90000000,LEN=0x00001000
CEPMEM:ORG=0x90001000,LEN=0x00004000
}
以上设置是将整个存储器分成具有不同名称的存储区域。VEC,PMEM代表内部RAM的两块存储空间,而CEVEC,CEPMEM代表Flash内的两块存储空间。对目标文件中各段的加载地址和运行地址在SECTIONS段实现。
SECTIONS
{
.BootCode:load=CEVEC;用户的引导代码段定位在Flash的最开始。
.text:load=CEPMEM,run=PMEM;用户程序段装载于
Flash空间,而运行在C6713内部RAM中。
}
通过JTAG口的Flash在线烧写
用汇编语言编写一个搬移程序,内容仅是Flash的擦除过程,以及对EDMA的多次操作构成的由片内RAM到片外Flash的写入过程。把该搬移程序直接嵌入主程序中,这样程序代码长度很短,不会占用过多的主程序空间。在主机引导方式下,通过JTAG口load后,手工更改PC值使其指向这段代码,控制其运行结束,完成自举程序的在线烧写。而在此之后,这段短小的搬移程序不会被主程序中任何一段代码所调用。
结束语
工程实际应用表明该方法是切实可行的,与以往Flash引导程序编写方法相比避免了目标代码的格式转换,利用EDMA直接搬移,无需编程器,Flash也不需频繁拆卸,利于工程上的快速开发。