TMS320VC33实现对Flash存储器的擦写设计
【摘要】本文以具体的项目为实例,介绍在CC3000开发环境下,数字信号处理器(DSP)对AM29LV400B Flash存储器的烧写、擦除等操作的实现,并介绍在开发系统下打开文件,将文件数据烧写到Flash存储器的方法。
【关键词】AMD公司;AM29LV400B;Flash;DSP;扇区
1.引言
Flash是一种可在线进行电擦写,掉电后数据不丢失的EEPROM存储器。它具有功耗低、容量大、烧写和擦除速度快等优点,并且内部嵌入算法完成对芯片的操作,简化了软件的工作量,因而在数字信号处理系统中得到了广泛的应用。DSP是一种高速数字信号处理器。它具有高稳定性、可重复性、可大规模集成,特别是易编程性和易于实现自处理等特点,使得信号处理手段更灵活、功能更复杂、运算速度更快,在数字信号处理领域得到广泛地应用。本文通过完整的实例,介绍以TMS320VC33(简称VC33)为嵌入式系统对AM29LV400B Flash存储器进行烧写和擦除的实现方法。
2.AMD公司AM29LV400B Flash存储器
AM29LV400B是AMD公司推出的Flash存储器,它是4兆位(8×512K/16×256K位)的CMOS工艺扇区擦除、字节编程的电可擦除只读存储器EEPROM。它的主要特点包括如下几个方面:3.3V单电压供电;内部嵌入编程、擦除操作算法,只需向命令寄存器写入标准的微处理器指令,并且可通过查询特定的引脚或数据线来监控操作是否完成;对任一扇区进行烧写擦除操作时不影响其它的扇区数据;可进行100000次的烧写擦除操作,数据保存10年以上。
本文中Flash的数据映射到DSP的0x0400000空间,Flash的一个字节对应一个DSP的低8位数据,高24位为无效数据,可以直接按字节进行读写操作。
3.Flash存储器的基本操作命令以及程序设计流程
Flash存储器AM29LV400B的基地址为0x400000,每个偏移地址乘以4是因为Flash字节仅占用DSP空间低8位,而DSP的地址是字节地址,所以地址增量为4。
3.1 Flash存储器的操作结束检测
Flash AM29LV400B内部的编程或擦除算法可自动完成相应操作,但必须了解其内部的操作检测机制,以便知道操作是否完成或正确。常用的检测方法有两种:跳变位(DQ6 )检测法、数据检测位(DQ7)检测法。本文中用的是第1种方法,即检测跳变位DQ6。DQ6指的是当前操作地址的D6位,在Flash写操作过程中,对相应地址的连续读均引起DQ6的“0”、“1”跳变,只有当写操作结束的时候,DQ6才会停止跳变,此时说明Flash内部操作成功结束,程序代码如下:
int Toggle_Bit_Check(unsigned int *addr)
{int flag = 1;
unsigned int toggle_data,read_data,timeout=0;
toggle_data = *addr & 0x40;
while((timeout<0x7fffff)&&(flag))
{read_data = *addr & 0x40;
if(read_data == toggle_data)
flag=0;
toggle_data = read_data;
timeout++;
}
return flag;
}
对读回的DQ6的数值做0x7fffff次比较,如果在所有的比较里该位都产生跳变,则说明Flash内部操作失败;如果DQ6停止跳变,flag标志写1,跳出while循环,Flash操作成功结束。
3.2 Flash存储器擦写操作命令
Flash存储器的擦写操作命令通常是启动Flash设备的存储器操作函数,由内嵌的算法完成具体的编程和擦除操作,所以向Flash的特定地址写入操作命令和数据,就可以对Flash存储器进行编程和擦除。表1介绍了Flash擦写命令的具体操作地址和命令代码。
在CC3000开发系统下,实现Flash擦写操作命令的C代码如下所示:
/******************** Flash 整片擦除操作 ********************/
dst = (unsigned int *)0x0400000;
//操作地址为整个Flash的首地址
*(dst + 0xAAA) = 0xAA;
*(dst + 0x555) = 0x55;
*(dst + 0xAAA) = 0x80;
*(dst + 0xAAA) = 0xAA;
*(dst + 0x555) = 0x55;
*(dst + 0xAAA) = 0x10;
Toggle_Bit_Check(Dst);
//检测结束标志
/********************Flash 扇区擦除操作 ********************/
*(dst + 0xAAA) = 0xAA;
*(dst + 0x555) = 0x55;
*(dst + 0xAAA) = 0x80;
*(dst + 0xAAA) = 0xAA;
*(dst + 0x555) = 0x55;
*(dst + 0xAAA) = 0x30;
/* 擦除扇区 */
Toggle_Bit_Check(Dst);
//检测结束标志
/******************** Flash字节编程操作 ********************/
unsigned int *CommandDest;
//操作地址为要执行写操作的Flash字节地址
*(CommandDest + 0xAAA) = 0xAA;
*(CommandDest + 0x555) = 0x55;
*(CommandDest + 0xAAA) = 0xA0;
* CommandDest = * DATA;
Toggle_Bit_Check(CommandDest);
//检测结束标志
执行写上述操作时,应注意以下事项:计算要擦除扇区的开始地址时,默认为Flash的开始地址(第一个扇区)。由于编程指令不能使“0”写成“1”,只能使“1”写成“0”,而擦除指令可使“0”写成“1”,所以写数据之前要先擦除完成后再编程烧写。
4.烧写Flash存储器
一般情况下,Flash是通过编程器把以文件形式存储的数据(比如生成的DSP引导程序代码bin二进制文件)烧写到Flash中,但这种方法烧写速度慢,并且需要把Flash芯片放到编程器上,调试过程中频繁的插拔Flash芯片会降低芯片寿命,因此选择在开发系统下通过JTAG接口和仿真器将比较大的数据文件烧写到Flash的指定存储区域中。下面具体介绍在CC3000开发系统下实现软件打开文件并将文件数据烧写到Flash中的实现过程。
5.开发系统CC3000以及编译链接环境的设置
选用TI的CC3000作为DSP的集成开发工具,它支持标准C和C++语言,并且能够嵌入汇编语言。编译程序之前,应先对CC3000的编译链接选项进行设置,并编写命令链接文件(.cmd文件),为程序和数据分配存储空间。
5.1 命令链接文件(.cmd文件)的编写
命令链接文件定义了DSP存储空间分配情况,用于在程序链接加载过程中将编译生成的各个代码段定位到DSP程序和数据存储区上,以本文的项目为例,cmd文件如下:
MEMORY
/* 存储空间分配部分 */
{ROM: origin = 0x0 len = 0x1000
EXT0: origin = 0x200000 len = 0x020000
FLASH: origin = 0x400000 len = 0x080000
/* Flash存储器 */
RAM2: origin = 0x800000 len = 0x3000
RAM3: origin = 0x803000 len = 0x5000
MMRS: origin = 0x808000 len = 0x1800
RAM0: origin = 0x809800 len = 0x400
RAM1: origin = 0x809C00 len = 0x3C1
VECTOR: origin = 0x809FC1 len = 0x3F
/* 中断向量表 */
}
SECTIONS
/* 各段在DSP存储空间上的定位 */
{
.vectors > VECTOR
.text > RAM2
.cinit > RAM2
.const > RAM2
.switch > RAM2
.bss > RAM2
.cio > RAM2
.stack > RAM0
.sysmem > RAM1
}
MEMORY命令完成DSP存储空间的分配。本文中将DSP的存储空间分成九部分:ROM区域表示4K的内部ROM区;EXT0区域表示外部存储区;Flash表示的是Flash存储区;VECTOR区域表示存放中断向量表的存储区。
SECTIONS命令说明编译生成的各个输出段如何定位到存储器。由于在CC3000开发系统下烧写文件到Flash涉及对文件的打开与读写操作与动态存储分配操作,所以应该在SECTIONS里定义.sysmem和.cio两个段,而一般情况下这两个段在编译过程中是不产生的。.sysmem段是提供动态存储分配空间的数据区,主要由malloc、calloc和realloc等动态分配函数所使用,这些函数封装在CC3000提供的系统库函数rts30.lib中。.cio是有关文件IO操作的段,程序中涉及到对文件的打开读写等操作的时候编译才会生成该段。这两个段都是作为程序的数据定义到RAM数据存储器里。
5.2 烧写文件数据到Flash的实现
在CC3000下打开文件,读取文件数据,并将数据通过VC33写到Flash。下面以小于64K文件的烧写为例,说明在CC3000下烧写Flash的过程,程序代码如下:
FILE *fp;
unsigned int *RamAddr,i;
RamAddr =(unsigned int *)0x0803000; //存放文件数据的临时缓冲区
flashaddr=(unsigned int *)0x0400000; //操作地址为整个Flash的首地址
block=FILE_LENGTH/(64*1024);
/* FILE_LENGTH为文件长度,block为64K数据块数 */
remain =FILE_LENGTH % (64*1024);
/* remain为最后一块小于64K文件数据的长度 */
DSP_init();
//VC33初始化
if((fp = fopen("TestFlash.bin","rb"))==NULL)
exit(0);
for(i=0;i //打开要写入Flash的文件 { fread(RamAddr,sizeof(char),64*1024,fp); //读文件数据到临时缓冲区 flash_write(flashaddr,64*1024,RamAddr); flash_addr+ = 64 * 1024; // Flash地址递增 } if(remain>0) { fread(RamAddr,sizeof(char), remain,fp); flash_write(flashaddr,remain,RamAddr); } fclose(fp); //关闭文件 在CC3000开发系统下,根据文件大小计算将文件数据分成多少个64K大小的块和最后一块小于64K块的长度,并对DSP进行初始化;然后以"rb"为参数调用fopen函数,即已只读的二进制文件格式打开制定的文件,如果fopen参数里没有写出文件的路径,系统默认为与CC3000生成的.out格式文件在同一个目录下,如果打开成功,获得文件句柄fp;按照块的顺序,依次以字节大小读取文件数据到0x0803000~0x0808000,并调用写Flash函数flash_write(),依次将数据写到Flash存储器(注意每次写操作结束后,Flash地址应该相应的增加);最后关闭文件,退出程序,操作完成。 6.结束语 用软件方式,在CC3000开发系统下,由VC33控制Flash写操作,从而实现了文件数据到Flash存储器的下载过程。与编程器写Flash的方式相比,其软件烧写Flash速度快,而且无需卸下Flash芯片放在编程器上,便于调试。通过上述方法可完成VC33对AM29LV400B的烧写。其他型号Flash芯片也可按此类方法烧写。 参考文献 [1]http:///AM29LV400B DataSheet.pdf. [2]http:///TMS320VC33.pdf. [3]http:///TMS320C3x User’s Guide.pdf. 作者简介: 范以训(1981—),男,工程师,现供职于陕西凌云电器集团有限公司设计所,主要从事数字电路设计方面的应用与开发。 岳超峰(1978—),男,工程师,现供职于陕西凌云电器集团有限公司设计所,主要从事复杂数字信号处理、接口控制方面的应用与开发。
推荐访问:擦写 存储器 设计 TMS320VC33 Flash
上一篇:Raid技术在数据存储中的应用