标签:
1、NorFlash 简介
Nor flash 和 Nand flash 是现在市场上两种主要的非易失闪存技术,闪存是非易失存储器,可以对称为块的存储器单元块进行擦写和再编程。任何flash器件的写入操作只能在空或已擦除的单元内进行,所以大多数情况下,在进行写入操作之前必须先执行擦除。
Nor flash的特点是程序和数据可存放在同一片芯片上,拥有独立的数据总线和地址总线,能快速随机地读取,允许系统直接从Flash中读取代码执行,而无需先将代码下载至RAM中再执行。NOR的传输效率很高,在1~4MB的小容量时具有很高的成本效益,但是很低的写入和擦除速度大大影响了它的性能。
2、 代码
相对于操作NandFlash,操作NorFlash相对简单,因为基本不需要考虑坏块,NorFlash也没有OOB区域,也跟ECC没有关系。读写擦除相对容易,下面以保存授权文件到Norflash为例子吧。
#define NORFLASH_DEV "/dev/mtd4"
struct DeviceInfo
{
int fd;
char dir[20];
int mtdSize; // Total size of the MTD
int eraseSize;
} DevInfo;
static int __zm_norflash_init()
{
int fd;
memset(&DevInfo, 0, sizeof(DevInfo));
strcpy(DevInfo.dir, NORFLASH_DEV);
fd = open(DevInfo.dir, O_SYNC | O_RDWR);
if (fd < 0) {
printf("cannot open %s !!\r\n", DevInfo.dir);
return 0;
}
else
{
mtd_info_t mtdinfo;
if (ioctl(fd, MEMGETINFO, &mtdinfo) >= 0)
{
DevInfo.fd = fd;
DevInfo.mtdSize = mtdinfo.size;
DevInfo.eraseSize = mtdinfo.erasesize;
printf("(%s).fd : %d\r\n",DevInfo.dir, DevInfo.fd);
printf("(%s).size : 0x%x\r\n",DevInfo.dir,DevInfo.mtdSize);
printf("(%s).erasesize : 0x%x\r\n",DevInfo.dir,DevInfo.eraseSize);
}
else
{
printf("get erasesize fail!!\r\n");
}
}
}
要对NOR Flash进行写操作,就一定要先进性擦除操作。NOR Flash可以单字节或单字编程,但不能单字节擦除,必须以块(sector)为单位或对整片执行擦除操作,在对存储器进行编程之前需要对块或整片进行预编程和擦除操作。但是每一种型号的Flash的sector的大小不同,即使在同一片的Flash内,不同sector的大小也是不完全一样的。
static int __zm_norflash_erase(int begin, int end)
{
printf("%s(): begin=0x%x, end=0x%x\n", __func__, begin, end);
if (DevInfo.fd == -1 || begin > ZM_NORFLASH_ALL_SIZE || end > ZM_NORFLASH_ALL_SIZE) {
printf("%s: invalid parameters\n", __func__);
return 0;
}
erase_info_t erase_info;
erase_info.length = DevInfo.eraseSize;
for (erase_info.start = begin; erase_info.start < end; erase_info.start += DevInfo.eraseSize)
{
if (ioctl(DevInfo.fd, MEMERASE, &erase_info) < 0)
{
printf("%s: erase norflash failure (%s)\r\n", __func__, strerror(errno));
continue;
}
fsync(DevInfo.fd);
}
}
Norflash擦除操作的流程图如下:
Erase Operation
Norflash读写代码如下:
static int __zm_norflash_write(int addr, unsigned char *buf, int buf_size)
{
printf("%s(): addr=0x%x, buf_size=%d\n", __func__, addr, buf_size);
if (DevInfo.fd == -1 || !buf || addr + buf_size > ZM_NORFLASH_ALL_SIZE) {
printf("%s: invalid parameters\n", __func__);
return 0;
}
int iWriteTimes = 0;
while(iWriteTimes < 3)
{
++iWriteTimes;
if (lseek(DevInfo.fd, addr, SEEK_SET) == addr)
{
if(write(DevInfo.fd, buf, buf_size) == buf_size)
{
fsync(DevInfo.fd);
return buf_size;
}
else
{
printf("%s: write error(%s).\r\n", __func__, strerror(errno));
}
}
else
{
printf("%s: lseek error(%s).\r\n", __func__, strerror(errno));
return 0;
}
}
}
static int __zm_norflash_read(int addr, unsigned char *buf, int buf_size)
{
printf("%s(): addr=0x%x, buf_size=%d\n", __func__, addr, buf_size);
if (DevInfo.fd == -1 || !buf || addr + buf_size > ZM_NORFLASH_ALL_SIZE) {
printf("%s: invalid parameters\n", __func__);
return 0;
}
int iReadTimes = 0;
while(iReadTimes < 3)
{
++iReadTimes;
if(lseek(DevInfo.fd, addr, SEEK_SET) == addr)
{
if(read(DevInfo.fd, buf, buf_size) == buf_size)
{
return buf_size;
}
else
{
printf("%s: read error(%s).\r\n", __func__, strerror(errno));
}
}
else
{
printf("%s: lseek error(%s).\r\n", __func__, strerror(errno));
return 0;
}
}
}
3、总结
Norflash的编程主要有读取ID,扇区擦除(Sector Erase),然后进行读写操作。
标签:
原文地址:http://www.cnblogs.com/klcf0220/p/4538985.html