从JTAG接口对DSP外部Flash的编程方法不只一种。本文以TMS320C6711-150 DSK板为例,介绍“在线仿真状态下”对Flash的编程。
1 Flash存储器的擦除
Flash编程之前,应对Flash进行擦除,使其每个数据位都恢复为1状态,即全FF状态。对Flash的擦除 *** 作需要6个总线周期,总线时序如图1。
从图1可知,各总线周期的 *** 作为:
第一总线周期——向郑喊2AAAH地址的存储单元写入数据55H;
第二总线周期——向2AAAH地址的存储单元写入数据55H;
第三总线周期——向5555H地址的存储单元写入数据80H;
第四总线周期——向5555H地址的存储单元写入数据AAH;
第五总线周期——向2AAAH地址的存储单元写入数据55H;
第六总线周期——向5555H地址的存储单元写入数据10H。
完成上述 *** 作后,Flash存储器被完全擦除,内部数据恢复为初始状态,全为FFH。
在TMS320C6711中,用C语言完成上述 *** 作为:
void erase_flash()
{
*(unsigned volatile char*)FLASH_ADR1=0x00aa
*(unsigned volatile char*)FLASH_ADR2=0x0055
*(unsigned volatile char*)FLASH_ADR1=0x0080
*(unsigned volatile char*)FLASH_ADR1=0x00aa
*(unsigned volatile char*)FLASH_ADR2=0x0055;
*(unsigned volatile char*)FLASH_ADR1=0x0010;
}
在TMS320C6711系统中,Flash所在地址段为CE1空间,其开始地址为0x90000000。这样,其中的FLASH_ADR1、FLASH_ADR2在头文件中被定义为:
#define FLASH_ADR1 0x90005555
#define FLASH_ADR2 0x90002AAA
需要说明的是,在对Flash进行擦除时,应对DSP及EMIF外存储器接口进行初始化,CE1空间定义为8位读写模式。
初始化函数如下:
void c6x11_dsk_init(){ /*DSP和EMIF初始化*/
CSR=0x100/*禁止所有中断*/
IER=1; /*禁止除NMI外的所饥皮有中断*/
ICR=0xffff/*清除所有未完成的中断*/
*(unsigned volatile int *)EMIF_GCR=0x3300
*(unsigned volatile int *)EMIF_CE0=0x30
*(unsigned volatile int*)EMIF_CE1=0xffffff03
*(unsigned volatile int*)EMIF_SDCTRL=0x07227000
*(unsigned volatile int*)EMIF_SDRP=0x61a
*(unsigned volatile int*)EMIF_SDEXT=0x54529
}
2 Flash存储器的编程
对Flash存储器进行字节编程之前,需要对它进行3个周期的编程指令 *** 作,总线时序如图2。
从图2可知,各总线周期的 *** 作如下:
第一总线周期——向5555H地址的存储单元写入数据AAH;
第二总线周期——向2AAAH地址的存储单元写入数据55H;
第三总线周期——向5555H地址的存储单元写入数据A0H;
第四总线周期——向地址的存储单元写入编程数据;
……
在TMS320C6711中,用C语言完成上述 *** 作为:
/*---------------------------------------------------------------------*/
/*入口参数:pattern[]:数组,用于存储编喊肢野程数据*/
*/ start_address:所要编程的起始地址指针*/
/* page_size:所要编程的Flash的页面尺寸*/
/*出口参数:无*/
/*---------------------------------------------------------------------*/
void flash_page_prog(unsigned char pattern[],unsigned volatile char *start_address,int page_size){
volatile int i
unsigned volatile char *flash_ptr=start_address
*(unsigned volatile char *)FLASH_ADR1=FLASH_KEY1
*(unsigned volatile char *)FLASH_ADR2=FLASH_KEY2
*(unsigned volatile char *)FLASH_ADR1=FLASH_KEY3
for(i=0i<PAGE_SIZEI++)<P>
*flash_ptr++=pattern[i]
}
其中,FLASH_KEY1、FLASH_KEY2、FLASH_KEY3的定义如下:
#define FLASH_KEY1 0xAA
#define FLASH_KEY2 0x55
#define FLASH_KEY3 0xA0
3 校验和的计算与编程原理
(1)校验和的计算
在程序中,应对Flash编程的正确性进行自动检查,把编程前数据的校验和编程后Flash中读出数据的校验和进行比较:如果相同,则编程成功;如果不相同,则编程失败。需要注意的是,在对Flash 进行编程的过程中,不能用CCS2.0中的“VIEW/MEMORY…”功能看Flash中的编程数据,这样会导致一会地址编程的失败。
其C语言程序如下:
/*----------------------------------------------------------------------*/
/*入口参数:start_address:所要校验的起始地址*/
/* size_in_byte:所要校验的Flash数据字节数*/
/*出口参数:lchecksum:校验和 */
/*----------------------------------------------------------------------*/
int flash_checksum(int start_address,int size_in_byte){
int i
int lchecksum
unsigned volatile char*flash_ptr=(unsigned volatile char*)
start_address
int temp
i=0
lchecksum=0
while(i<SIZE_IN_BYTE-4){<P>
temp=*flash_ptr++
temp&=0xff
lchecksum=lchecksum+temp
i++
}
return lchecksum
}
(2)编程原理
基本原理是:在仿真状态下,在PC机上运行DSP编程软件,由运行的DSP通过JTAG口从PC机上读入待编程的十六进制数据文件,由DSP将其写入到其外部Flash中,即完成用户数据文件的烧写工作。
4 编程数据的读入及编程
编程时,由DSP程序从终端仿真计算机上打开要编程的十六进制文件,从十六进制文件中依次读入编程数据,并由DSP将其写入到其外部Flash中,程序段如下:
while(data_flag=0){
display_count++
if(display_count==DISPLAY_SIZE){
display_count=0
/*printf(".")*/
}
for(i=0i<FLASH_WRITE_SIZEI++){<P>
j=fscanf(hex_fp,“%x”,&data)/*从文件中读入编程数据,每次取一个字节*/
if(j==EOF||j==0){
data_flag=1
break
}
host_buffer[i]=data
checksum+=data
flash_addr+=1
if(falsh_addr>0x90020001){
printf("ERROR:beyond valid flash address!")
}
}
//写入Flash
ptr=(unsigned volatile char *)(flash_addr-0x80)
if(data_flasg==0){
length=FLASH_WRITE_SIXZE
flash_page_prog(host_buffer,ptr,length)
printf("Programming address:%x",flash_addr-0x80)
}
}
注意:所采用的十六进制文件应使用“Hex6x.exe”命令,并在hex.cmd命令文件中使用“-a”参数生成的文件;指定的存储器长度必须能被128 整数(len参数能被128整除)。因为AT29LV010A以扇区为 *** 作单位,每个扇区为128字节,共1024个扇区,其格式如下:
…
-map hex.map
-a
-image
-zero
-memwidth 8
ROMS
{
FLASH:org=0x90000000,len=0x20000,romwidth=8,files={test.hex}
}
…
5 仿真运行
将上述程序组成一个完整的程序,经过编译、链接(Project/Build命令)后,使用“File/Load Program...”将编程代码Load到DSP中,运行程序,经过几分种后即编程完毕。
结语
对DSP外部Flash编程虽不是一项关键技术,但它在整个DSP嵌入式系统开发中却有着至关重要的作用。如果开发者在设计之初就掌握了这项技术,就会大大方便系统的调试,缩短开发时间。
京东年货节羊排每满599元减200,速戳!
京东
广告
dsp flash烧写工具
27下载·0评论
2015年7月13日
DSP学习第六篇——Flash 的使用
1.0W阅读·1评论·1点赞
2015年6月2日
JTAG 详解
2.9W阅读·3评论·17点赞
2009年4月21日
ADI DSP的JTAG设计规范(提供JTAG标准设计原理图)
152阅读·0评论·0点赞
2022年12月8日
把DSP TMS320F28XXX的程序段从flash复制到ram中运行
1646阅读·0评论·0点赞
2014年10月22日
DSP外部FLASH烧写的两种方法
77下载·3评论
2013年2月18日
提前备年货,京东超市,哈尔滨红肠年货礼盒,爆款直降,超值!
京东
广告
DSP与FPGA之EMIF接口的调试说明
4896阅读·0评论·7点赞
2021年6月9日
DSP外部Flash存储器在线编程的软硬件设计
2057阅读·0评论·1点赞
2012年6月14日
dsp2812外部FLASH数据读取与发送
52下载·3评论
2013年6月3日
C2000系列DSP生成hex/bin文件并使用串口下载程序的方法
1238阅读·0评论·0点赞
2022年3月17日
让DSP从FLASH启动——step bystep
6419阅读·2评论·1点赞
2013年5月26日
6713_EMIF *** 作外部flash
7728阅读·2评论·16点赞
2016年11月16日
使用JTAG是如何烧写SPI/BPI Flash的?
2711阅读·0评论·5点赞
2021年5月26日
浅谈单片机之JTAG
801阅读·0评论·2点赞
2022年5月26日
TI C2000系列DSP Flash烧写解决方案
53下载·2评论
2010年1月13日
去首页
看看更多热门内容
DSP和FPGA不一样,在DSP上运行的程序可能会会出现死机,也就是跑飞的情况,查死机基本是每个DSP或嵌入式工程师debug时都会经历过的。DSP死机可能是硬件造成的也可能是软件造成。先说一下硬件造成的可能原因,遇到过的就一下4类,
1、复位电路不稳定;2.电源不稳定;3、时钟不稳;4、总线不稳定。下面分别讲解一下。
1、复位电路不稳定
很好理解,就是运行中突然有复位信号过来,这时DSP复位自然就DSP程序跑飞了或者程序重新跑一遍的情况。如果是在线硬件仿真基本就是跑飞或死机(程序不跑了)。
出现复位不稳定的情况我遇到了两种情况:
第一种情况是复位电路设计时,复位的时间不够,即低电平保持的时间不够,这样上电加载时,有时能够正常加载,有时不行,有时加载运行一段时游中间就死机了。
第二种情况是复位电路加有watchdog电路,watchdog不光监测喂狗(WDI)信号,而且还监测DSP工作电压值,如果小于某个电压范围就产生复位信号。一般在常温的时候,不会出现工作电压值的变化,而当DSP工作环境的温度发生变化时,就可能出现频繁复位的情况。
2、电源不稳定
电源不稳定主要是内核电源不稳定的情况,在一块电悄肆路板上可能同时有DSP、FPGA等芯片,可能内核电压相同,而采用同一路电源供电,而在DSP芯片有大负荷工作量时,造成工作电路继续增大, 从而拉低内核电压,造成瞬时电压不足,从而可能造成DSP程序跑飞,而这种情况对于FPGA基本没有影响。
复位电路不正常的第二种情况也可以认为是电源不稳定的情况。
3、时钟不稳
时钟不稳造成DSP、ARM死机的情况遇到比较多,下面举几个例子。
时钟信号幅度较小能量较弱,在常温工作时正常,长时间工作也没有问题,而在低温时(-40度),这时时钟信号可启磨轿能会已经弱到不能持续的给DSP工作,从而DSP死机,被watchdog复位的情况。但是FPGA对于时钟基本不受影响,时钟有了继续工作。这种情况的解决办法是增加时钟的幅度,增加比较器将时钟幅度变大等办法解决。
DSP通过FPGA的锁相环(PLL)生成时钟(这样频率比较灵活)工作,但FPGA输出时钟的引脚不是专用时钟引脚时,可能在某些情况下会造成时钟不稳,从而造成DSP死机或跑飞。解决办法:更换FPGA上的其他时钟管脚输出时钟。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)