《电子技术应用》
您所在的位置:首页 > 嵌入式技术 > 业界动态 > TMS320C54x DSP在线烧写FLASH存储器并实现自举引导的方法

TMS320C54x DSP在线烧写FLASH存储器并实现自举引导的方法

2008-08-27
作者:奉华成, 白 净

  摘 要: 通过一个完整的实例,详细阐述了TMS320C54x系列DSP芯片在线烧写" title="烧写">烧写FLASH存储器,并实现自举" title="自举">自举引导的方法。给出了硬件连接方案和完整的C语言烧写程序。
  关键词: TMS320C54x FLASH 烧写 自举引导


  在DSP系统中通常用贴片式FLASH存储器保存程序,并且在上电或复位时再将存储在FLASH中的程序搬移到DSP片内或者片外的RAM中全速运行。这个“程序搬移”的过程叫做自举加载" title="加载">加载。
  本文以TMS320C5416 DSP对MBM29LV400BC存储器的操作为例,详细阐述了在线烧写" title="在线烧写">在线烧写FLASH并实现自举加载的方法。该方法适合于大多数C54x系列DSP对符合JEDEC标准的FLASH的操作。为便于读者使用,本文的程序全部采用C语言编写。
1 TMS320C5416与MBM29LV400BC的硬件接口
  MBM29LV400BC与TMS320C5416的接口很方便,前者只需作为后者的外部数据存储器与其进行连接,而中间的逻辑电路采用CPLD实现即可。这里使用16位数据宽度,所以BYTE引脚通过一个上拉电阻接到3.3V电源。连接电路原理图如图1所示。相应的VHDL语言程序为:
  FLASH_CE<=DSP_DS;
  FLASH_OE<=(NOT DSP_R_W) OR DSP_MSTRB;
  FLASH_WE<=DSP_R_W OR DSP_MSTRB;
2 TMS320C5416自举引导过程
  当MP/MC=0时,TMS320C5416被置于微计算机模式。上电或复位时,程序指针指向片内ROM区的FF80H单元,该单元放置了一条跳转指令,使程序跳转到F800H单元。而F800H就是自举加载器(Bootloader)引导程序的起始单元。
  Bootloader的任务就是将存放在外部FLASH中的程序“搬运”到DSP内部或外部的RAM区,“搬运”完后跳转到程序入口处执行。存放在外部FLASH中的用户程序与一些必要的引导信息组合在一起,称为Boot表(自举表)。16位模式下通用的Boot表结构如表1所示。


  TMS320C5416提供了多种自举加载的方法。在此使用并行加载模式,因此令INT2=1和INT3=1。在并行模式下,自举表放在外部数据存储器的32K高端地址区间:8000H~0FFFFH。自举表首地址放在数据空间的0FFFFH单元。加载时,Bootloader读取数据空间的0FFFFH单元中的内容,将其作为首地址,从该地址开始复制数据到内部的程序空间。复制完毕后,Bootloader便跳转到指定的程序入口地址,开始执行用户程序。
3 MBM29LV400BC的操作命令字及其C语言程序
  MBM29LV400BC是FUJITSU公司的FLASH产品,容量为4M,其外部引脚和控制命令字都符合JEDEC标准,内部存储区分成11扇区。
  对FLASH的读取可以直接进行。但对FLASH的写入和擦除等操作却是通过命令字进行的。考虑到FLASH的起始单元是8000H,加上命令字所提供的偏移地址,可以得到如下几个常用的操作命令字:
  读/复位命令:往FLASH任意一个单元写入数据0F0H,都可导致FLASH复位,从而使其处于“读”模式。
  编程命令:需要四个总线周期。在字模式(16位数据宽度)下,如表2所示。
  擦除命令:有片擦除和扇区擦除两种方式,需六个总线周期。在字模式下,如表3所示。


  在向FLASH写入上述命令的时候,当最后一个总线周期完成时,FLASH便会启动内部算法,实现自动擦除、编程等内部操作。
  对FLASH的正确操作顺序是:先复位,再擦除(片擦除或者扇区擦除),最后编程。
  FLASH进行内部操作需要一定的时间,在这个过程中,FLASH会提供一些标志信号,通知用户内部操作过程是否已经结束。为简单起见,在对FLASH操作时不查询任何标志,而是采取延时的方法,等待FLASH内部操作结束,再进行下一步。延时的时间应该足够长,以保证FLASH擦除或编程成功。具体的延时时间应根据不同的系统确定。
  根据上述FLASH的操作原理,编写了如下几个主要的C语言操作子程序" title="子程序">子程序:
  typedef   unsigned char BYTE;
  void ResetFlash()      // FLASH复位子程序
  {
  BYTE *pa;
  pa=(BYTE *)0x8000;
  *pa=0x0F0;
  }
  void EraseFlash()      // FLASH片擦除子程序
  {
  BYTE *pa;
  pa=(BYTE *)0x8555;
  *pa=0x0AA;
  pa=(BYTE *)0x82AA;
  *pa=0x055;
  pa=(BYTE *)0x8555;
  *pa=0x080;  
  pa=(BYTE *)0x8555;
  *pa=0x0AA;    
  pa=(BYTE *)0x82AA;
  *pa=0x055;
  pa=(BYTE *)0x8555;
  *pa=0x010;  
  delay_10s();      //延时10s
  }
  void WriteFlash(BYTE *pa,int pd)  //写FLASH某个单元的子程序
  {
  BYTE *tmp;  
  tmp=(BYTE *)0x8555;
  *tmp=0x0AA;  
  tmp=(BYTE *)0x82AA;
  *tmp=0x055;    
  tmp=(BYTE *)0x8555;
  *tmp=0x0A0;  
  *pa=pd;  
  delay_200ms();  //延时200ms
  }
  延时子程序可用简单的加法计数实现,例如延时10s的子程序示例如下:
  delay_10s()
  {
  int i;
  int j;
  for(i=0;i<0x100;i++)
  {
  for(j=0;j<0x01000;j++);
  }
  }
  具体的延时时间需要根据系统的时钟设置,应重新调整延时子程序中的i和j的值来确定,直到能够成功地操作FLASH为止(可以通过CCS集成开发环境的“View→Memory...”菜单命令来查看被操作的FLASH单元是否成功擦除或写入)。
4 TMS320C5416在线烧写MBM29LV400BC的C语言程序
  利用CCS编译并链接得到的目标文件(*.out文件)是二进制的COFF格式文件,需要利用Hex转换工具将其转换为大多数编程器能够接收的格式之一(如ASCII码十六进制格式、Intel格式等),然后利用专门的烧写工具烧写FLASH,这个方法在一般的用户系统上不便于实现。但是根据前面所述DSP的Boot原理,则可以写一段很简单的烧写程序,按照Boot表格式,将目标代码在线烧写进FLASH。
  现在用一个实际的例子来说明在线烧写的过程。具体过程如下:
  建立两个独立的工程文件:MyProject.pjt和FlashBurn.pjt。前者生成的目标文件就是要烧入到FLASH中的用户程序,后者则用来实现烧入过程。MyProject.pjt有两个程序段:第一段是“.text”段,位于0x1000开始的单元,长度为0x2e。它用中断的方法实现LED灯的闪烁;第二段为“.VECTORS”段,位于0x0080开始的单元,长度为0x0078。它实现中断向量表的重新映射。程序执行入口地址也在0x1000单元。烧写时只需烧写用户程序的已初始化段(代码或数据表)。用户程序各段的起始单元及其长度可以参考该工程编译链接后所生成的.map文件(如本例的MyProject.map),这是编写烧写程序的依据。
  烧写工程文件FlashBurn.pjt只有一个程序段,定位在0x7000开始的存储区(注意不要与MyProject.pjt所占的程序空间有重叠),并将其_c_int00直接定位到该区域。
  用户程序拟烧写到外部FLASH的0x8000开始的存储区。
  两个工程建立并且编译完毕后,在CCS中先打开MyProject.pjt工程文件,用“File→Load Program...”菜单命令下载用户程序目标代码MyProject.out;再打开FlashBurn.pjt工程文件,下载FlashBurn.out,运行FlashBurn.out,即可将MyProject.out代码及其Boot引导信息写入到FLASH中。
  脱离仿真器,令MP/MC=0,上电复位,即可实现自举加载并自动运行。
  本例的烧写工程文件FlashBurn.pjt的C语言主程序如下:
  typedef unsigned char BYTE;
  void main()
  {
  BYTE *FlashPtr;    //指向FLASH的指针
  int FlashData;      //写往FLASH的数据
  int i;
  BYTE *OriMem;    //代码在片内RAM的源地址
  int iDatalen;      //代码段长度
  ResetFlash();      //复位FLASH    
  EraseFlash();      //整片擦除FLASH    
  //开始烧写FLASH,下面为Boot表引导信息      
  FlashPtr=(BYTE *)0x8000;
  FlashData=0x10AA;   //16位存储器格式
  WriteFlash(FlashPtr++,FlashData);    
  FlashData=0x7FFF;    //置SWWSR初始化值
  WriteFlash(FlashPtr++,FlashData);    
  FlashData=0x0F800;  //置BSCR初始化值
  WriteFlash(FlashPtr++,FlashData);    
  FlashData=0x0000;    //程序执行入口偏移地址XPC
  WriteFlash(FlashPtr++,FlashData);        
  FlashData=0x1000;    //程序执行入口地址PC
  WriteFlash(FlashPtr++,FlashData);      
  FlashData=0x002e;    //第一个程序段的长度
  WriteFlash(FlashPtr++,FlashData);              FlashData=0x0000;    //第一个程序段要装入的内部
            RAM区偏移地址
  WriteFlash(FlashPtr++,FlashData);          
  FlashData=0x1000;    //第一个程序段要装入的内部
            RAM区地址
  WriteFlash(FlashPtr++,FlashData);      
  //开始烧写第一段程序    
  OriMem=(BYTE *)0x1000;    //第一段程序首地址
  iDatalen=0x002e;        //第一段程序长度
  for(i=0;i<iDatalen;i++)
  {
    FlashData=*OriMem++;
    WriteFlash(FlashPtr++,FlashData);
  }    
  //第二段程序(中断向量表)Boot引导信息    
  FlashData=0x0078;       //第二个程序段的长度
  WriteFlash(FlashPtr++,FlashData);          
  FlashData=0x0000;       //第二个程序段要装入的
               内部RAM区偏移地址
  WriteFlash(FlashPtr++,FlashData);    
  FlashData=0x0080;      //第二个程序段要装入的
              内部RAM区地址
  WriteFlash(FlashPtr++,FlashData);      
  //开始烧写第二段程序(中断向量表)    
  OriMem=(BYTE *)0x080;  //第二段程序首地址
  iDatalen=0x0078;      //第二段程序长度
  for(i=0;i<iDatalen;i++)
  {
    FlashData=*OriMem++;
    WriteFlash(FlashPtr++,FlashData);
  }                
  //程序烧写结束,写入Boot表结束标志
  FlashData=0x0000;      //引导表结束标志
  WriteFlash(FlashPtr,FlashData);  
  //在数据空间0xFFFF写入引导表起始地址    
  FlashPtr=(BYTE *)0x0FFFF;
  FlashData=0x8000;
  WriteFlash(FlashPtr,FlashData);
  for(;;);          //FLASH烧写完毕  
}
本文所叙述的方法简单方便,无需考虑FLASH的存储格式。如果要烧写其它用户程序,只需修改FlashBurn.pjt中有关用户程序的起始地址、代码段长度等参数即可,因此通用性较好。文中所提供的程序已全部经过调试,能够成功运行。
参考文献
1 TMS320C54x DSP Reference Set Volume 4:Application Guide(SPRU173).Texas Instruments Incorporated, October,1996
2 Application Report:SPRA602E.Texas Instruments Incorporated,April,2004
3 MBM29LV400BC Flash Memory DataSheet. JAPAN:Fujitsu Limited, 1998
4 张 勇.C/C++语言硬件程序设计-基于TMS320C5000系列DSP(第一版). 西安:西安电子科技大学出版社,2003
5 唐 冰. TMS320C5410烧写FLASH实现并行自举引导.单片机与嵌入式系统应用,2003(4)

本站内容除特别声明的原创文章之外,转载内容只为传递更多信息,并不代表本网站赞同其观点。转载的所有的文章、图片、音/视频文件等资料的版权归版权所有权人所有。本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如涉及作品内容、版权和其它问题,请及时通过电子邮件或电话通知我们,以便迅速采取适当措施,避免给双方造成不必要的经济损失。联系电话:010-82306118;邮箱:aet@chinaaet.com。