|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
基于S3C4510B的系统的Flash擦除与烧写问题(一)
最近看到很多朋友在设计基于S3C4510B的系统时,碰到了Flash不能正确烧写或擦除的问题,下面根据我的理解对这个问题的作一个说明,以期抛砖引玉:
不同于其他的ARM处理器(如44B0),S3C4510B的每一个bank的地址都是可以通过重映射改变的,因此,系统的存储器,无论是Flash还是SDRAM,其起始地址都不是固定的,而对Flash的擦除,必须知道它的起始地址,否则就不能正确操作,这就是为什么很多朋友不能正确擦除Flash的原因。
以一般的系统设计为例,Flash使用2M、4M或8M,16位数据宽度,对应到Flash/ROM/SRAM的Bank0,SDRAM采用两片16位宽度的器件,并联构成32位的SDRAM存储器系统,对应到SDRAM的Bank0,那么,在Flash的内容为空时,当系统上电或复位后,能直接访问到的只有特殊功能寄存器(SFR)对应的Bank(其首地址为0x3FF0000),和Flash/ROM/SRAM的Bank0(其首地址为0x0),而SDRAM此时是访问不到的。
此时,如果我们想对Flash进行编程或擦除操作,该怎么办呢?
显然,要对Flash进行编程或擦除操作,必须通过编程完成,而程序此时只能在SDRAM中运行(如果程序不太大,也可放在S3C4510B片内的SRAM中运行。),所以,我们要做的第一步,就是通过配置相应的特殊功能寄存器,将SDRAM映射出来,使其可以被访问到。
下面是我的一个特殊功能寄存器配置文件,名为:mymap.txt,放在C盘根目录下。
setmem 0x3ff0000,0xE7ffff90,32
setmem 0x3ff3010,0x00003002,32
setmem 0x3ff3014,0x02000060,32
setmem 0x3ff302c,0x14010380,32
setmem 0x3ff303c,0xce338360,32
我使用的硬件是2MB的Flash,16MB的SDRAM。在ADS中打开命令窗口,执行如下命令:
>obey c:\mymap.txt
此时,2MB的Flash存储器和16MB的SDRAM已分别映射到地址空间的0x0000,0000~(0x0020,0000-1)和0x0040,0000~(0x0140,0000-1)处。
编写一个Flash的擦除程序,由Init.s文件和Main.c文件构成。
Init.s文件的代码如下:
IMPORT Main
AREA Init,CODE,READONLY
ENTRY
BL Main
B .
END
Main.c文件的代码如下:
#define UINT16 unsigned short
#define AM_START_ADDR 0x0 //此处为Flash的起始地址,设为0
#define AM_ADDR_UNLOCK1 0x555
#define AM_ADDR_UNLOCK2 0x2aa
#define AM_DATA_UNLOCK1 0xaaaa
#define AM_DATA_UNLOCK2 0x5555
#define AM_SETUP_WRITE 0xa0a0
#define AM_SETUP_ERASE 0x8080
#define AM_CHIP_ERASE 0x1010
#define AM_SECTOR_ERASE 0x3030
#define AM_RESET 0xf0f0
int Main()
{
*((volatile UINT16 *)AM_START_ADDR+ AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1;
*((volatile UINT16 *)AM_START_ADDR+ AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
*((volatile UINT16 *)AM_START_ADDR+ AM_ADDR_UNLOCK1) = AM_SETUP_ERASE;
*((volatile UINT16 *)AM_START_ADDR+ AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1;
*((volatile UINT16 *)AM_START_ADDR+ AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
*((volatile UINT16 *)AM_START_ADDR+ AM_ADDR_UNLOCK1) = AM_CHIP_ERASE;
return(0);
}
注:系统使用的Flash为29LV160B,其他型号的Flash,命令字有一些区别。
系统使用的SDARM为HY57641620B
建立一个工程文件,包含以上两个文件。
由于要将该擦除程序放在SDRAM中运行,而根据前面的映射,SDRAM的起始地址为0x0040,0000,所以要修改连接器的选项,将代码的装入地址改为0x400000(默认为0x8000)。
编译生成可执行映象文件,装入系统的SDRAM(0x0040,0000处)运行,就可擦除Flash。
您瞧,Flash的擦除多么简单。
但是,当Flash中已有一个程序在运行时,情况就不太一样了。
当Flash中有程序运行时,一般都要将系统的存储器由初始化状态进行重映射,常用的方式是将SDARM映射到0x0处,而Flash则被映射到其他地方去了(如uClinux运行时,Flash被重映射到0x100,0000处),此时Flash的首地址也就不再是0x0了,再用以上的程序去擦除,显然就不能成功。
怎么办???
要原封不动的使用上面的程序,只有将Flash的首地址再映射回0x0。
打开ADS的命令窗口,执行如下命令:
>obey c:\mymap.txt
此时Flash被我们搬回了0x0处,SDRAM被搬回0x40,0000处,运行上述程序,Flash被擦除。
一点小注意:
有时,Flash中原来的程序初始化了很多中断,而我们的擦除程序为简洁,对中断未作处理,可能会出现当我们装入程序到SDRAM中运行时,一开始就跑飞,这是因为产生了中断。
在运行之前,先将0x3ff4008(中断屏蔽寄存器)的值改为0x3fffff,屏蔽所有的中断,然后运行,就好了。
以上是一个最简单的思路,有点班门弄斧,请大家跟贴指正。
下一部分讨论Flash的烧写。
|
|