FLASH ERASE:CHIP、BLOCK、SECTOR

FLASH ERASE:CHIP、BLOCK、SECTOR 

           SPI FLASH 的ERASE、READ、WRITE,笔者都用ESL在博文中论述过。ERASE包括CHIP、BLOCK、SECTOR三方面的内容;READ可对指定地址的单个及连续读取数

据;WRITE也有单个及连续写入数据。相关内容可翻阅之前的博文,笔者要强调一下的是现阶段再次接触到的ERASE的内容,随时随地的记录: CHIP:整片FLASH ERASE,视

容量大小占耗时间,是最长的ERASE时间。 BLOCK:大部分的FLASH都以64K为单位空间ERASE,具体可有针对地参考资料查证,特别是FLASH的TOP或BOTTOM容易有差

别。每个BLOCK的ERASE时间较快。 SECTOR:比BLOCK更小的单位,ERASE时间最快。 这三方面的ERASE都带两个参数HIGH ADDRESS及LOW ADDRESS,或可通过寄

存器R0-R7来传递。使用时,可根据利用到的FLASH空间及ERASE时间长短对程序的影响来作出适当的选择。

下面是一个简单的SPI Flash设备驱动程序的例子代码,包括了SPI Flash的读写和擦除操作: ```c #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #define SPI_FLASH_CMD_WRSR 0x01 #define SPI_FLASH_CMD_WRITE 0x02 #define SPI_FLASH_CMD_READ 0x03 #define SPI_FLASH_CMD_WRDI 0x04 #define SPI_FLASH_CMD_RDSR 0x05 #define SPI_FLASH_CMD_WREN 0x06 #define SPI_FLASH_CMD_FAST_READ 0x0B #define SPI_FLASH_CMD_ERASE_SECTOR 0x20 #define SPI_FLASH_CMD_ERASE_BLOCK 0xD8 #define SPI_FLASH_CMD_ERASE_CHIP 0xC7 #define SPI_FLASH_SR_WIP 0x01 struct spi_flash { struct spi_device *spi; unsigned int size; }; static int spi_flash_read_sr(struct spi_flash *flash, u8 *sr) { int ret; u8 cmd = SPI_FLASH_CMD_RDSR; struct spi_transfer t = { .tx_buf = &cmd, .rx_buf = sr, .len = 2, }; struct spi_message m; spi_message_init(&m); spi_message_add_tail(&t, &m); ret = spi_sync(flash->spi, &m); if (ret) return ret; return 0; } static int spi_flash_wait_wip(struct spi_flash *flash) { int ret; u8 sr; do { ret = spi_flash_read_sr(flash, &sr); if (ret) return ret; } while (sr & SPI_FLASH_SR_WIP); return 0; } static int spi_flash_erase_sector(struct spi_flash *flash, unsigned int addr) { int ret; u8 cmd[4]; struct spi_message m; struct spi_transfer t[1]; cmd[0] = SPI_FLASH_CMD_ERASE_SECTOR; cmd[1] = (addr >> 16) & 0xff; cmd[2] = (addr >> 8) & 0xff; cmd[3] = addr & 0xff; spi_message_init(&m); t[0].tx_buf = cmd; t[0].len = sizeof(cmd); spi_message_add_tail(t, ARRAY_SIZE(t)); ret = spi_sync(flash->spi, &m); if (ret) return ret; return spi_flash_wait_wip(flash); } static int spi_flash_erase_block(struct spi_flash *flash, unsigned int addr) { int ret; u8 cmd[4]; struct spi_message m; struct spi_transfer t[1]; cmd[0] = SPI_FLASH_CMD_ERASE_BLOCK; cmd[1] = (addr >> 16) & 0xff; cmd[2] = (addr >> 8) & 0xff; cmd[3] = addr & 0xff; spi_message_init(&m); t[0].tx_buf = cmd; t[0].len = sizeof(cmd); spi_message_add_tail(t, ARRAY_SIZE(t)); ret = spi_sync(flash->spi, &m); if (ret) return ret; return spi_flash_wait_wip(flash); } static int spi_flash_erase_chip(struct spi_flash *flash) { int ret; u8 cmd = SPI_FLASH_CMD_ERASE_CHIP; struct spi_message m; struct spi_transfer t[1]; spi_message_init(&m); t[0].tx_buf = &cmd; t[0].len = sizeof(cmd); spi_message_add_tail(t, ARRAY_SIZE(t)); ret = spi_sync(flash->spi, &m); if (ret) return ret; return spi_flash_wait_wip(flash); } static int spi_flash_write(struct spi_flash *flash, unsigned int addr, unsigned int len, const u8 *buf) { int ret; u8 cmd[4]; struct spi_message m; struct spi_transfer t[2]; if (len > flash->size - addr) return -EINVAL; cmd[0] = SPI_FLASH_CMD_WREN; spi_message_init(&m); t[0].tx_buf = cmd; t[0].len = sizeof(cmd); spi_message_add_tail(t, ARRAY_SIZE(t)); ret = spi_sync(flash->spi, &m); if (ret) return ret; cmd[0] = SPI_FLASH_CMD_WRITE; cmd[1] = (addr >> 16) & 0xff; cmd[2] = (addr >> 8) & 0xff; cmd[3] = addr & 0xff; spi_message_init(&m); t[0].tx_buf = cmd; t[0].len = sizeof(cmd); t[1].tx_buf = buf; t[1].len = len; spi_message_add_tail(t, ARRAY_SIZE(t)); ret = spi_sync(flash->spi, &m); if (ret) return ret; return spi_flash_wait_wip(flash); } static int spi_flash_read(struct spi_flash *flash, unsigned int addr, unsigned int len, u8 *buf) { int ret; u8 cmd[4]; struct spi_message m; struct spi_transfer t[2]; if (len > flash->size - addr) return -EINVAL; cmd[0] = SPI_FLASH_CMD_READ; cmd[1] = (addr >> 16) & 0xff; cmd[2] = (addr >> 8) & 0xff; cmd[3] = addr & 0xff; spi_message_init(&m); t[0].tx_buf = cmd; t[0].len = sizeof(cmd); t[1].rx_buf = buf; t[1].len = len; spi_message_add_tail(t, ARRAY_SIZE(t)); ret = spi_sync(flash->spi, &m); if (ret) return ret; return 0; } static int spi_flash_probe(struct spi_device *spi) { struct spi_flash *flash; unsigned int id; // 读取SPI Flash的ID // ... // 根据ID初始化SPI Flash设备 // ... return 0; } static int spi_flash_remove(struct spi_device *spi) { // 释放SPI Flash设备资源 // ... return 0; } static struct spi_driver spi_flash_driver = { .driver = { .name = "spi_flash", .owner = THIS_MODULE, }, .probe = spi_flash_probe, .remove = spi_flash_remove, }; static int __init spi_flash_init(void) { return spi_register_driver(&spi_flash_driver); } static void __exit spi_flash_exit(void) { spi_unregister_driver(&spi_flash_driver); } module_init(spi_flash_init); module_exit(spi_flash_exit); MODULE_LICENSE("GPL"); ``` 在上面的代码,`spi_flash_probe()` 函数是SPI Flash设备驱动程序的入口函数,当系统检测到一个新的SPI Flash设备时,内核就会调用该函数来初始化该设备。在该函数,我们可以读取SPI Flash的ID,并根据ID来初始化该设备的参数。例如我们可以读取Flash的容量、页大小、扇区大小等信息,并保存到 `spi_flash` 结构体。最后,我们需要返回0表示初始化成功。 在 `spi_flash_remove()` 函数,我们需要释放与SPI Flash设备相关的资源,例如GPIO引脚、硬件资源等等。最后同样返回0表示卸载成功。 在 `spi_flash_erase_sector()`、`spi_flash_erase_block()`、`spi_flash_erase_chip()`、`spi_flash_write()` 和 `spi_flash_read()` 这些函数,我们根据SPI Flash的协议来实现了相应的擦除、写入和读取操作。需要注意的是,这里我们使用了 `spi_sync()` 函数来进行同步通信。这意味着当该函数返回时,数据已经被写入或者读取到了 `buf` 。 需要注意的是,上面的代码只是一个简单的例子,实际的SPI Flash驱动程序可能需要更多的功能和处理逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值