Macronix MX25L25645G NOR Flash无法擦除问题分析

1. 问题现象描述

   处理器使用的 SAM9X60, 使用的内核版本是 5.10.80,在调试 Macronix MX25L25645G NOR Flash时,发现flash驱动加载成功后,使用 mtd_debug 工具 erase flash时,擦除一整片flash区域时,命令执行速度很快,而且命令执行完没有报错,但是最后发现flash并没有真正被擦除。

  • mtd_debug 擦写命令
mtd_debug erase /dev/mtd0 0 0x20000
 
mtd_debug write /dev/mtd0 0 0x20000 sample.bin
 
mtd_debug read /dev/mtd0 0 0x20000 bootstrap_2.bin
  • 也可以使用 flashcp 和 flash_erase 命令, flashcp 会先擦除 flash 然后再写入数据。
root@sam9x60ek:/tmp# flashcp -v sample.bin /dev/mtd3
Erasing blocks: 1/1 (100%)
Writing data: 1k/0k (100%)
Verifying data: 1k/0k (1%)File does not seem to match flash data. First mismatch at 0x00000000-0x00000400

2. 代码走读分析

2.1 探索 SPI erase 过程

   用户层的mtd_debug erase , flash_ease等命令到内核驱动层进行分析。

   查看 flashcp 的源代码,其采用的方式是通过 ioctl (dev_fd,MEMERASE,&erase) 方式来进行擦除操作;
   查看 flash_erase的源代码,其调用了libc库中的 mtd_erase API 进行擦除操作, mtd_erase API 最终会调用 ioctl (dev_fd,MEMERASE,&erase) 方式来进行擦除操作。
两者本质是一样的。

   基于5.10.80 内核版本

1)ioctl (dev_fd,MEMERASE,&erase)
  Path: /linux/drivers/mtd/mtdchar.c
static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg) 函数中
在这里插入图片描述
MEMERASE64 这个宏是为了操作 大于 4Gib大小的flash才会使用的。我们这里不考虑。

走到了内核中 mtd_erase

/linux/drivers/mtd/mtdcore.c
在这里插入图片描述
会调用 master->_erase(master, &adjinstr) 这个操作。这个函数的定义在

/linux/drivers/mtd/spi-nor/core.c

spi_nor_scan 中
在这里插入图片描述
在这里插入图片描述
对比SAM9X60 EK Demo板,发现走的是 spi_nor_has_uniform_erase 这个else 分支
使用的是 spi_nor_erase_sector 按扇区来擦除
在驱动中添加了打印信息,对于 MX25L25645G 这个NOR来说,驱动选用的擦除、写、读命令以及对应的地址分别是:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2. SPI 擦除失败的根本原因分析。

/linux/drivers/mtd/spi-nor/core.c
spi_nor_erase_sector
在这里插入图片描述
传入的 nor->addr_width = [4] ,擦除操作时,根据flash数据手册,op→addr.buswidth应该等于1,但是等于4了,导致数据帧组装错误,flash没有识别这个指令,从而没有擦除成功。

对代码进行了修改,代码中提交的修改记录:
在这里插入图片描述
详细分析下上面的代码:

op->addr.buswidth 是怎么来的呢?
在这里插入图片描述
在这里插入图片描述
我们这里设置的为0,但是下面这个函数也会对 buswidth 进行赋值。

spi_nor_spimem_setup_op(nor, &op, nor->write_proto);
在这里插入图片描述
在这里插入图片描述
加打印,看一下传入的 nor->write_proto 参数是多少,以及这个参数是在哪里初始化的?op.addr.buswidth 在 进入spi_nor_spimem_setup_op这个函数前后的值是多少?
在这里插入图片描述
nor→write_proto

spi_nor_scan
-> spi_nor_init_params
-> spi_nor_info_init_params
-> spi_nor_default_setup
-> spi_nor_select_pp

在这里插入图片描述
感觉初始化并不是这样定义的。
在这里插入图片描述
在这里插入图片描述
在调试过程中,使用了Microchip SAM9X60 EK 评估板作为对比。评估板使用的QSPI NOR Flash型号是 SST26VF064B.

在这里插入图片描述

++++++++++++ 擦除操作,将P4K和Demo版本进行对比传入的 nor->write_proto ++++++++++++++
在这里插入图片描述
在这里插入图片描述
整个流程:
发送写使能(指令 06) -》 发送擦除命令 (指令 dc, (4 Byte Address Command, BE4B (block erase 64KB) )
-》读取状态寄存器(指令05,WIP标志反映命令是否执行成功)-》关闭写使能(指令04)

nor->write_proto 被定义的地方如下:

/linux/drivers/mtd/spi-nor/core.c

最先开始初始时,spi_nor_scan 中定义的是 SNOR_PROTO_1_1_1
在这里插入图片描述
在这个地方被重新赋值:
spi_nor_select_pp
在这里插入图片描述
对比spi_nor_select_read 和 spi_nor_select_pp。
在这里插入图片描述
可以看到由于 shared_mask 不同造成后后面 best_match 选择不一样,Demo板选择的PP 模式是 1-1-1,我们的板子选择的PP 模式是 1-4-4

shared_mask
我们的板子: 0x5039b (0101 0000 0011 1001 1011)
Demo板: 0x1039b (0001 0000 0011 1001 1011)

这个对照下面:

https://elixir.bootlin.com/linux/v5.10.80/source/include/linux/mtd/spi-nor.h#L220

flash的读能力

在这里插入图片描述
flash的写能力
在这里插入图片描述
追 shared_mask
在这里插入图片描述
继续追 params->hwcaps.mask
spi_nor_info_init_params 函数中会对 hwcaps.mask 进行赋值
在这里插入图片描述
所以这就是内核的兼容性问题。得需要将 Write 和 erase 剥离出来。

3. 我们板子Linux内核启动过程中SPI Flash初始化Log

*** heat [atmel_qspi_exec_op] [419] 
*** heat [atmel_qspi_set_cfg] [328] op->addr.buswidth = [0]
*** heat [atmel_qspi_set_cfg] [329] op->addr.nbytes = [0]
*** heat [atmel_qspi_set_cfg] [408] iar = [0x0] icr = [0x9f] ifr = [0x90]    0x9f 命令是读取SPI Flash的Chip ID
******** heat func [macronix_default_init] enter 
*** heat [spi_nor_spimem_read_data] [199] nor->read_opcode = [5a]
*** heat [spi_nor_spimem_read_data] [200] nor->addr_width = [3]
*** heat [atmel_qspi_exec_op] [419] 
*** heat [atmel_qspi_set_cfg] [328] op->addr.buswidth = [1]
*** heat [atmel_qspi_set_cfg] [329] op->addr.nbytes = [3]
*** heat [atmel_qspi_set_cfg] [408] iar = [0x0] icr = [0x5a] ifr = [0x810b0]    0x5A 命令是读取 SFDP ( Serial Flash Discoverable Parameter (SFDP)) 能力集
*** heat [spi_nor_spimem_read_data] [199] nor->read_opcode = [5a]
*** heat [spi_nor_spimem_read_data] [200] nor->addr_width = [3]
*** heat [atmel_qspi_exec_op] [419] 
*** heat [atmel_qspi_set_cfg] [328] op->addr.buswidth = [1]
*** heat [atmel_qspi_set_cfg] [329] op->addr.nbytes = [3]
*** heat [atmel_qspi_set_cfg] [408] iar = [0x10] icr = [0x5a] ifr = [0x810b0]
*** heat [spi_nor_spimem_read_data] [199] nor->read_opcode = [5a]
*** heat [spi_nor_spimem_read_data] [200] nor->addr_width = [3]
*** heat [atmel_qspi_exec_op] [419] 
*** heat [atmel_qspi_set_cfg] [328] op->addr.buswidth = [1]
*** heat [atmel_qspi_set_cfg] [329] op->addr.nbytes = [3]
*** heat [atmel_qspi_set_cfg] [408] iar = [0x30] icr = [0x5a] ifr = [0x810b0]
*** heat [spi_nor_spimem_read_data] [199] nor->read_opcode = [5a]
*** heat [spi_nor_spimem_read_data] [200] nor->addr_width = [3]
*** heat [atmel_qspi_exec_op] [419] 
*** heat [atmel_qspi_set_cfg] [328] op->addr.buswidth = [1]
*** heat [atmel_qspi_set_cfg] [329] op->addr.nbytes = [3]
*** heat [atmel_qspi_set_cfg] [408] iar = [0xc0] icr = [0x5a] ifr = [0x810b0]
******** heat func [spi_nor_select_erase] [2450] wanted_size = 65536 
******** heat func [spi_nor_select_erase] [2469] erase->opcode = dc 
*** heat [atmel_qspi_exec_op] [419] 
*** heat [atmel_qspi_set_cfg] [328] op->addr.buswidth = [0]
*** heat [atmel_qspi_set_cfg] [329] op->addr.nbytes = [0]
*** heat [atmel_qspi_set_cfg] [408] iar = [0x0] icr = [0x5] ifr = [0x90]   0x5 命令是读取 Flash的 Status Reg
******** heat func [spi_nor_sr1_bit6_quad_enable] enter, ret = 0, bouncebuf = 64 
******** heat func [spi_nor_sr1_bit6_quad_enable] enter , line [1808]
******** heat func [macronix_set_4byte_addr_mode] enter 
*** heat [atmel_qspi_exec_op] [419] 
*** heat [atmel_qspi_set_cfg] [328] op->addr.buswidth = [0]
*** heat [atmel_qspi_set_cfg] [329] op->addr.nbytes = [0]
*** heat [atmel_qspi_set_cfg] [408] iar = [0x0] icr = [0x6] ifr = [0x10]  0x6 命令是 打开写使能
******** heat func [spi_nor_set_4byte_addr_mode] enter , enable=[1]
*** heat [atmel_qspi_exec_op] [419] 
*** heat [atmel_qspi_set_cfg] [328] op->addr.buswidth = [0]
*** heat [atmel_qspi_set_cfg] [329] op->addr.nbytes = [0]
*** heat [atmel_qspi_set_cfg] [408] iar = [0x0] icr = [0xb7] ifr = [0x10] 0xb7 命令是 使能4Byte address
*** heat [atmel_qspi_exec_op] [419] 
*** heat [atmel_qspi_set_cfg] [328] op->addr.buswidth = [0]
*** heat [atmel_qspi_set_cfg] [329] op->addr.nbytes = [0]
*** heat [atmel_qspi_set_cfg] [408] iar = [0x0] icr = [0x4] ifr = [0x10] 0x4 命令是 关闭写使能
spi-nor spi0.0: mx25l25635e (32768 Kbytes)
spi-nor spi0.0: mtd .name = spi0, .size = 0x2000000 (32MiB), .erasesize = 0x00010000 (64KiB) .numeraseregions = 0
5 fixed-partitions partitions found on MTD device spi0
Creating 5 MTD partitions on "spi0":
0x000000000000-0x000000020000 : "at91bootstrap"
0x000000020000-0x000000040000 : "env"
0x000000040000-0x000000100000 : "u-boot"
0x000000100000-0x000001000000 : "system"
0x000001000000-0x000002000000 : "data"
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SFUD (Serial Flash Universal Driver)  串行 Flash 万能驱动库 0、SFUD 是什么 SFUD 是一款开源的串行 SPI Flash 通用驱动库。由于现有市面的串行 Flash 种类居多,各个 Flash 的规格及命令存在差异, SFUD 就是为了解决这些 Flash 的差异现状而设计,让我们的产品能够支持不同品牌及规格的 Flash,提高了涉及到 Flash 功能的软件的可重用性及可扩展性,同时也可以规避 Flash 缺货或停产给产品所带来的风险。 主要特点:面向对象(同时支持多个 Flash 对象)、可灵活裁剪、扩展性强、支持 4 字节地址 资源占用 标准占用:RAM:0.2KB ROM:5.5KB 最小占用:RAM:0.1KB ROM:3.6KB 设计思路:这里要首先跟大家介绍一个标准: SFDP ,它是 JEDEC (固态技术协会)制定的串行 Flash 功能的参数表标准,最新版 V1.6B (点击这里查看)。该标准规定了,每个 Flash 中会存在一个参数表,该表中会存放 Flash 容量、写粗粒度、擦除命令、地址模式等 Flash 规格参数。目前,除了部分厂家旧款 Flash 型号会不支持该标准,其他绝大多数新出厂的 Flash 均已支持 SFDP 标准。所以该库在初始化时会优先读取 SFDP 表参数,如果该 Flash 不支持 SFDP,则查询配置文件 ( /sfud/inc/sfud_flash_def.h ) 中提供的 Flash 参数信息表 中是否支持该款 Flash。如果不支持,则可以在配置文件中添加该款 Flash 的参数信息(添加方法详细见 2.5 添加库目前不支持的 Flash)。获取到了 Flash 的规格参数后,就可以实现对 Flash 的全部操作。 1、为什么选择 SFUD 避免项目因 Flash 缺货、Flash 停产或产品扩容而带来的风险; 越来越多的项目将固件存储到串行 Flash 中,例如:ESP8266 的固件、主板中的 BIOS 及其他常见电子产品中的固件等等,但是各种 Flash 规格及命令不统一。使用 SFUD 即可避免,在相同功能的软件平台基础下,无法适配不同 Flash 种类的硬件平台的问题,提高软件的可重用性; 简化软件流程,降低开发难度。现在只需要配置好 SPI 通信,即可畅快的开始玩串行 Flash 了; 可以用来制作 Flash 编程器/烧写器 2、SFUD 如何使用 2.1 已支持 Flash 下表为所有在 Demo 平台上进行过真机测试的 Flash。目前 SFUD 提供的 Flash 参数信息表 只包括下表中 不支持 SFDP 标准的 Flash,其他不支持 SFDP 标准的 Flash 需要大家以后 共同来完善和维护 (Github|OSChina) 。如果觉得这个开源项目很赞,可以点击 项目主页 右上角的 Star ,同时把它推荐给更多有需要的朋友。 型号 制造商 容量 最高速度 SFDP 备注 W25Q40BV Winbond 4Mb 50Mhz 不支持 已停产 W25Q80DV Winbond 8Mb 104Mhz 支持 W25Q16CV Winbond 16Mb 104Mhz 支持 W25Q32BV
支持当前流行的八脚SPI Flash, 特别适用于主板BIOS的DIY,无需购买昂贵的专业的编程器.本人刚刚用它恢复了我的华硕本本的BIOS,感觉比较方便,特此分享.只需稍微懂一些电路知识,不要把引脚弄错,任何人都可以DIY,再也不用担心主板不启动.该编程器只需连接四只200-400欧姆的电阻(图中为150ohm,但是不是很稳定,我是用四只270ohm的电阻成功的),一个并口连接公头,电源直接用普通干电池,3.3V的Flash系列用两节1.5V的干电池串联即可省去原理图中的1000µF电容,5V系列3节电池即可,连接前测一下,保证电压没有超过datasheet中的允许值.连接时最好能够使用转DIP的卡座,这样会省很多时间,而且也容易接错引脚.终端程序使用打印机接口模拟SPI,可以识别并支持下列SPI芯片: Atmel: AT26DF041 (512kB) AT26DF081 (1MB) AT26DF081A (1MB) AT26DF161 (2MB) AT26DF161A (2MB) AT26DF321 (4MB) Intel: QB25F016S33B8 (2MB) QB25F032S33B8 (4MB) QB25F064S33B8 (8MB) Macronix: MX25L1005 (128kB) MX25L2005 (256kB) MX25L4005 (512kB) MX25L8005 (1MB) MX25L1605 (2MB) MX25L3205 (4MB) MX25L6405 (8MB) Spansion: S25FL004A (512kB) S25FL008A (1MB) S25FL016A (2MB) S25FL032A (4MB) S25FL064A (8MB) S25FL128P (16MB) SST: SST25VF010 (128kB) SST25VF020 (256kB) SST25VF040 (512kB) SST25VF040B (512kB) SST25VF080A (1MB) SST25VF080B (1MB) SST25VF016 (2MB) SST25VF032 (4MB) SST25VF064 (8MB) SST25VF128 (16MB) SST26VF016 (2MB) SST26VF032 (4MB) SST26VF064 (8MB) ST Microelectronic: M25P10 (128kB) M25P20 (256kB) M25P40 (512kB) M25P80 (1MB) M25P16 (2MB) M25P32 (4MB) M25P64 (8MB) M25P128 (16MB) Winbond: W25X10 (128kB) W25X20 (256kB) W25X40 (512kB) W25X80 (1MB) W25X16 (2MB) W25X32 (4MB) W25X64 (8MB) 但是终端程序运行于DOS模式或者W2K, XP, Vista下的模拟DOS环境. 几个重要的命令行输入示例(方便不懂DOS的)> 1. *** /i (如果芯片连接正确就会显示芯片的型号等信息,验证正确与否) 2. *** /d amibios.bin (自动备份SPI芯片中的内容到当前文件夹中的amibios.bin文件中,以备不时之需) 3. *** /e (清空芯片内容) 4. *** /p ami.bios (把名为ami.bios的文件写入SPI芯片中) 顺便罗嗦一句,操作时别忘了防静电,小心永久损坏芯片. 解压密码:spi
bios by 百度贴吧dsanke 本人闲鱼付费购买,不支持八代i5,仅支持八代奔腾i3 ; ; These settings are not part recommendations, nor are they an ; indication these parts are supported on Intel platforms. ; All parts on this list have NOT been validated, and it is the ; responsibility of the customer to validate the flash parts used ; on their platform. ; ; Flash parts may change opcodes and architectures so please refer ; to the respective flash datasheet and errata/application note and ; flash vendor to confirm. ; ;Description of fields: ; 1) Display name ; 2) Device ID (2 or 3 bytes) ; 3) Device Size (in bits) ; 4) Block Erase Size (in bytes - 256, 4K, 64K) ; 5) Block Erase Command ; 6) Write Granularity (1 or 64) ; 7) Enable Write Status Register Command (1- True, 0- False) ;winbond W25Q256FV, 0xEF4019, 0x10000000, 0x1000, 0x20, 64, 0 W25Q256JV, 0xEF4019, 0x10000000, 0x1000, 0x20, 64, 0 W25Q256JW,0xEF6019, 0x10000000, 0x1000, 0x20, 64, 0 W25Q128FV,0xEF4018, 0x8000000, 0x1000, 0x20, 64, 0 W25R128FV,0xEF4018, 0x8000000, 0x1000, 0x20, 64, 0 W25Q128JV, 0xEF4018, 0x8000000, 0x1000, 0x20, 64, 0 W25Q128FW,0xEF6018, 0x8000000, 0x1000, 0x20, 64, 0 W25Q64FV, 0xEF4017, 0x4000000, 0x1000, 0x20, 64, 0 W25R64FV, 0xEF4017, 0x4000000, 0x1000, 0x20, 64, 0 W25Q64JV, 0xEF4017, 0x4000000, 0x1000, 0x20, 64, 0 W25Q64FW, 0xEF6017, 0x4000000, 0x1000, 0x20, 64, 0 W25Q32FV, 0xEF4016, 0x2000000, 0x1000, 0x20, 64, 0 W25Q32JV, 0xEF4016, 0x2000000, 0x1000, 0x20, 64, 0 W25Q32FW, 0xEF6016, 0x2000000, 0x1000, 0x20, 64, 0 W25Q16DV, 0xEF4015, 0x1000000, 0x1000, 0x20, 64, 0 W25Q16JV, 0xEF4015, 0x1000000, 0x1000, 0x20, 64, 0 W25Q16CL, 0xEF4015, 0x1000000, 0x1000, 0x20, 64, 0 W25Q16DW, 0xEF6015, 0x1000000, 0x1000, 0x20, 64, 0 W25Q16FW, 0xEF6015, 0x1000000, 0x1000, 0x20, 64, 0 W25Q80DV, 0xEF4014, 0x800000, 0x1000, 0x20, 64, 0 W25Q80JV, 0xEF4014, 0x800000, 0x1000, 0x20, 64, 0 W25Q80BL, 0xEF4014, 0x800000, 0x1000, 0x20, 64, 0 W25Q80EW, 0xEF6014, 0x800000, 0x1000, 0x20, 64, 0 W25X40CL, 0xEF3013, 0x400000, 0x1000, 0x20, 64, 0 W25Q40CL, 0xEF4013, 0x400000, 0x1000, 0x20, 64, 0 W25Q40EW, 0xEF6013, 0x400000, 0x1000, 0x20, 64, 0 W25X20CL, 0xEF3012, 0x200000, 0x1000, 0x20, 64, 0 W25Q20CL, 0xEF4012, 0x200000, 0x1000, 0x20, 64, 0 W25Q20EW, 0xEF6012, 0x200000, 0x1000, 0x20, 64, 0 W25X10CL, 0xEF3011, 0x100000, 0x1000, 0x20, 64, 0 W25Q10EW, 0xEF6011, 0x100000, 0x1000, 0x20, 64, 0 W25X05CL, 0xEF3010, 0x8000, 0x1000, 0x20, 64, 0 W25Q128JVSIQ, Ef4018, 0x8000000, 0x1000, 0x20, 64, 0 W25Q80DL, EF4014, 0x800000, 0x1000, 0x20, 64, 0 W25Q16JL, EF4015, 0x1000000, 0x1000, 0x20, 64, 0 W25Q256FV, EF4019, 0x10000000, 0x1000, 0x20, 64, 0 W25R256FV, EF4019, 0x10000000, 0x1000, 0x20, 64, 0 ;macronix MX25L12875F, 0xC22018, 0x8000000, 0x1000, 0x20, 64, 0 MX25L12835F, 0xC22018, 0x8000000, 0x1000, 0x20, 64, 0 MX25L6473E, 0xC22017, 0x4000000, 0x1000, 0x20, 64, 0 MX25L3273E, 0xC22016, 0x2000000, 0x1000, 0x20, 64, 0 MX25L1673E, 0xC22415, 0x1000000, 0x1000, 0x20, 64, 0 MX25L8075E, 0xC22014, 0x800000, 0x1000, 0x20, 64, 0 MX25L12873F, 0xC22018, 0x8000000, 0x1000, 0x20, 64, 0 MX25L8073E, 0xC22014, 0x800000, 0x1000, 0x20, 64, 0 MX25L6450F, 0xC22017, 0x4000000, 0x1000, 0x20, 64, 0 MX25L12850F, 0xC22018, 0x8000000, 0x1000, 0x20, 64, 0 MX25L3273F, 0xC22016, 0x2000000, 0x1000, 0x20, 64, 0 MX25L6473F, 0xC22017, 0x4000000, 0x1000, 0x20, 64, 0 MX25L25735F, 0xC22019, 0x10000000, 0x1000, 0x20, 64, 0 MX25L6445E, 0xC22017, 0x4000000, 0x1000, 0x20, 64, 0 MX25L6455E, 0xC22617, 0x4000000, 0x1000, 0x20, 64, 0 MX25L12855E, 0xC22618, 0x8000000, 0x1000, 0x20, 64, 0 MX25L6436E, 0xC22017, 0x4000000, 0x1000, 0x20, 64, 0 MX25L12836E, 0xC22018, 0x8000000, 0x1000, 0x20, 64, 0 MX25L8036E, 0xC22014, 0x800000, 0x1000, 0x20, 64, 0 MX25L1636E, 0xC22515, 0x1000000, 0x1000, 0x20, 64, 0 MX25L12865E, 0xC22018, 0x8000000, 0x1000, 0x20, 64, 0 MX25L6495F, 0xC29517, 0x4000000, 0x1000, 0x20, 64, 0 MX25L12835E, 0xC22018, 0x8000000, 0x1000, 0x20, 64, 0 MX25L12845E, 0xC22018, 0x8000000, 0x1000, 0x20, 64, 0 MX25L25635E, 0xC22019, 0x10000000, 0x1000, 0x20, 64, 0 MX25U1635F, 0xC22535h, 0x1000000, 0x1000, 0x20, 64, 0 MX25U3235F, 0xC22536h, 0x2000000, 0x1000, 0x20, 64, 0 MX25U6473F, 0xC22537h, 0x4000000, 0x1000, 0x20, 64, 0 MX25U6435F, 0xC22537h, 0x4000000, 0x1000, 0x20, 64, 0 MX25U12835F, 0xC22538h, 0x8000000, 0x1000, 0x20, 64, 0 MX25U12873F, 0xC22538h, 0x8000000, 0x1000, 0x20, 64, 0 MX25U25635F, 0xC22539h, 0x10000000, 0x1000, 0x20, 64, 0 MX25L25673G, 0xC22019h, 0x10000000, 0x1000, 0x20, 64, 0 MX66L51235F, 0xC2201Ah, 0x8000000, 0x1000, 0x20, 64, 0 MX25L51245G, 0xC2201Ah, 0x8000000, 0x1000, 0x20, 64, 0 MX25L12873G, 0xC22018h, 0x8000000, 0x1000, 0x20, 64, 0 MX25U8033E, 0xC22534h, 0x800000, 0x1000, 0x20, 64, 0 MX25U1635F, 0xC22535h, 0x1000000, 0x1000, 0x20, 64, 0 MX25U3273F, 0xC22536h, 0x2000000, 0x1000, 0x20, 64, 0 MX25U6473F, 0xC22537h, 0x4000000, 0x1000, 0x20, 64, 0 MX25U12873F, 0xC22538h, 0x8000000, 0x1000, 0x20, 64, 0 MX25U25635F, 0xC22539h, 0x10000000, 0x1000, 0x20, 64, 0 MX25L8073E, 0xC22014h, 0x800000, 0x1000, 0x20, 64, 0 MX25L1673E, 0xC22415h, 0x1000000, 0x1000, 0x20, 64, 0 MX25L3273F, 0xC22016h, 0x2000000, 0x1000, 0x20, 64, 0 MX25L6473F, 0xC22017h, 0x4000000, 0x1000, 0x20, 64, 0 MX25L6450F, 0xC22017h, 0x4000000, 0x1000, 0x20, 64, 0 MX25L12850F, 0xC22018h, 0x8000000, 0x1000, 0x20, 64, 0 MX25L12873F, 0xC22018h, 0x8000000, 0x1000, 0x20, 64, 0 MX25L25673G, 0xC22019h, 0x10000000, 0x1000, 0x20, 64, 0 MX25L25673G, 0xC2201Ah, 0x20000000, 0x1000, 0x20, 64, 0 MX25L25635F, 0xC22019, 0x10000000, 0x1000, 0x20, 64, 0 MX25L25645G, 0xC22019, 0x10000000, 0x1000, 0x20, 64, 0 MX25U25645G, 0xC22539, 0x10000000, 0x1000, 0x20, 64, 0 MX25U51245G, 0xC2253A, 0x20000000, 0x1000, 0x20, 64, 0 ;micron N25Q128, 0x20BA18, 0x8000000, 0x1000, 0x20, 64, 0 N25Q032, 0x20BB16, 0x2000000, 0x1000, 0x20, 64, 0 N25Q064, 0x20BA17, 0x4000000, 0x1000, 0x20, 64, 0 N25Q016, 0x20BA15, 0x1000000, 0x1000, 0x20, 64, 0 N25Q128A, 0x20BB18, 0x8000000, 0x1000, 0x20, 64, 0 N25Q256A, 0x20BB19, 0x10000000, 0x1000, 0x20, 64, 0 N25Q064A11EF640E, 0x20BB17, 0x4000000, 0x1000, 0x20, 64, 0 MT25QL256ABA1EW9-0SIT, 0x20BA19, 0x10000000, 0x1000, 0x20, 64, 0 MT25QL512ABA,0x20BA20, 0x20000000, 0x1000, 0x20, 64, 0 MT25QU128ABA1ESE, 0x20BB18, 0x8000000, 0x1000, 0x20, 64, 0 N25Q064A11ESEA0F, 0x20BB17, 0x4000000, 0x1000, 0x20, 64, 0 MT25QL128ABA, 0x20BA18, 0x8000000, 0x1000, 0x20, 64, 0 MT25QU128ABA, 0x20BB18, 0x8000000, 0x1000, 0x20, 64, 0 MT25QU256AB, 0x20BB19, 0x10000000, 0x1000, 0x20, 64, 0 ;EON / ESMT EN25QH256, 0x1C7019, 0x10000000, 0x1000, 0x20, 64, 0 EN25QH128A, 0x1C7018, 0x8000000, 0x1000, 0x20, 64, 0 EN25QH64A, 0x1C7017, 0x4000000, 0x1000, 0x20, 64, 0 EN25QH80, 0x1C7014, 0x800000, 0x1000, 0x20, 64, 0 EN25QH16A, 0x1C7015, 0x1000000, 0x1000, 0x20, 64, 0 EN25QH32A, 0x1C7016, 0x2000000, 0x1000, 0x20, 64, 0 EN25QH64, 0x1C7017, 0x4000000, 0x1000, 0x20, 64, 0 EN25Q40A, 0x1C3013, 0x400000, 0x1000, 0x20, 64, 0 EN25Q80B, 0x1C3014, 0x800000, 0x1000, 0x20, 64, 0 EN25S64, 0x1C3817, 0x4000000, 0x1000, 0x20, 64, 0 EN25S64A, 0x1C3817, 0x4000000, 0x1000, 0x20, 64, 0 EN25S10A, 0x1C3811, 0x100000, 0x1000, 0x20, 64, 0 EN25S20A, 0x1C3812, 0x200000, 0x1000, 0x20, 64, 0 EN25S40A, 0x1C3813, 0x400000, 0x1000, 0x20, 64, 0 EN25S80A, 0x1C3814, 0x800000, 0x1000, 0x20, 64, 0 EN25S32, 0x1C3816, 0x2000000, 0x1000, 0x20, 64, 0 EN25QH16, 0x1C7015, 0x0x1000000, 0x1000, 0x20, 64, 0 EN25QH32, 0x1C7016, 0x0x2000000, 0x1000, 0x20, 64, 0 EN25QH128, 0x1C7018, 0x0x8000000, 0x1000, 0x20, 64, 0 ;gigadevice GD25B16B, 0xC84015, 0x1000000, 0x1000, 0x20, 64, 0 GD25B32B, 0xC84016, 0x2000000, 0x1000, 0x20, 64, 0 GD25B64B, 0xC84017, 0x4000000, 0x1000, 0x20, 64, 0 GD25B128C, 0xC84018, 0x8000000, 0x1000, 0x20, 64, 0 GD25LQ64C, 0xC86017, 0x4000000, 0x1000, 0x20, 64, 0 GD25R64B, 0xC84017, 0x4000000, 0x1000, 0x20, 64, 0 GD25B64C, 0xC84017, 0x4000000, 0x1000, 0x20, 64, 0 GD25R64C, 0xC84017, 0x4000000, 0x1000, 0x20, 64, 0 GD25R128C, 0xC84018, 0x8000000, 0x1000, 0x20, 64, 0 GD25LB64, 0xC86017, 0x4000000, 0x1000, 0x20, 64, 0 GD25LB128, 0xC86018, 0x8000000, 0x1000, 0x20, 64, 0 GD25Q256C, 0xC84019, 0x10000000, 0x1000, 0x20, 64, 0 GD25LQ256C, 0xC86019, 0x10000000, 0x1000, 0x20, 64, 0 GD25R127C, 0xC84018, 0x8000000, 0x1000, 0x20, 64, 0 GD25B256C, 0xC84019, 0x10000000, 0x1000, 0x20, 64, 0 GD25B127D, 0xC84018, 0x8000000, 0x1000, 0x20, 64, 0 GD25LB128D, 0xC86018, 0x8000000, 0x1000, 0x20, 64, 0 GD25LB256D, 0xC86019, 0x10000000, 0x1000, 0x20, 64, 0 GD25Q80C, 0xC84014, 0x800000, 0x1000, 0x20, 64, 0 GD25B16C, 0xC84015, 0x1000000, 0x1000, 0x20, 64, 0 GD25Q16C, 0xC84015, 0x1000000, 0x1000, 0x20, 64, 0 GD25B32C, 0xC84016, 0x2000000, 0x1000, 0x20, 64, 0 GD25Q32C, 0xC84016, 0x2000000, 0x1000, 0x20, 64, 0 GD25Q64C, 0xC84017, 0x4000000, 0x1000, 0x20, 64, 0 GD25LQ128D, 0xC86018, 0x8000000, 0x1000, 0x20, 64, 0 GD25Q128C, 0xC84018, 0x8000000, 0x1000, 0x20, 64, 0 GD25B256D, 0xC84019, 0x10000000, 0x1000, 0x20, 64, 0 GD25LQ256D, 0xC86019, 0x10000000, 0x1000, 0x20, 64, 0 ;Adesto AT25SF641, 0x1F3217, 0x4000000, 0x1000, 0x20, 64, 0 AT25SL128A, 0x1F4218, 0x8000000, 0x1000, 0x20, 64, 0 AT25SL641, 0x1F4317, 0x4000000, 0x1000, 0x20, 64, 0 AT25SL321, 0x1F4216, 0x2000000, 0x1000, 0x20, 64, 0 AT25SF128, 0x1F7018, 0x8000000, 0x1000, 0x20, 64, 0 AT25QF128, 0x1F7018, 0x8000000, 0x1000, 0x20, 64, 0 AT25QF641, 0x1F3217, 0x4000000, 0x1000, 0x20, 64, 0 AT25QL128A, 0x1F4218, 0x8000000, 0x1000, 0x20, 64, 0 AT25QL641, 0x1F4317, 0x4000000, 0x1000, 0x20, 64, 0 AT25QL321, 0x1F4216, 0x2000000, 0x1000, 0x20, 64, 0 ;ISSI IS25LP256A, 0x9D6019, 0x10000000, 0x1000, 0x20, 64, 0 IC25LP256A, 0x9D6019, 0x10000000, 0x1000, 0x20, 64, 0 IS25LP128, 0x9D6018, 0x8000000, 0x1000, 0x20, 64, 0 IC25LP128, 0x9D6018, 0x8000000, 0x1000, 0x20, 64, 0 IS25LP064A, 0x9D6017, 0x4000000, 0x1000, 0x20, 64, 0 IC25LP064A, 0x9D6017, 0x4000000, 0x1000, 0x20, 64, 0 IS25WP256A, 0x9D7019, 0x10000000, 0x1000, 0x20, 64, 0 IC25WP256A, 0x9D7019, 0x10000000, 0x1000, 0x20, 64, 0 IS25WP128, 0x9D7018, 0x8000000, 0x1000, 0x20, 64, 0 IC25WP128, 0x9D7018, 0x8000000, 0x1000, 0x20, 64, 0 IS25WP064, 0x9D7017, 0x4000000, 0x1000, 0x20, 64, 0 IC25WP064, 0x9D7017, 0x4000000, 0x1000, 0x20, 64, 0 IS25WP064A, 0x9D7017, 0x4000000, 0x1000, 0x20, 64, 0 IC25WP064A, 0x9D7017, 0x4000000, 0x1000, 0x20, 64, 0 IS25LP256D, 0x9D6019, 0x10000000, 0x1000, 0x20, 64, 0 IC25LP256D, 0x9D6019, 0x10000000, 0x1000, 0x20, 64, 0 IS25WP256D, 0x9D6019, 0x10000000, 0x1000, 0x20, 64, 0 IC25WP256D, 0x9D6019, 0x10000000, 0x1000, 0x20, 64, 0 IS25WP080D, 0x9D7014, 0x800000, 0x1000, 0x20, 64, 0 IS25LP080D, 0x9D6014, 0x800000, 0x1000, 0x20, 64, 0 IS25WP016D, 0x9D7015, 0x1000000, 0x1000, 0x20, 64, 0 IS25LP016D, 0x9D6015, 0x1000000, 0x1000, 0x20, 64, 0 IS25WP032D, 0x9D7016, 0x2000000, 0x1000, 0x20, 64, 0 IS25LP032D, 0x9D6016, 0x2000000, 0x1000, 0x20, 64, 0 IS25LP128F, 0x9D6018, 0x8000000, 0x1000, 0x20, 64, 0 IS25WP128F, 0x9D7018, 0x8000000, 0x1000, 0x20, 64, 0 ;XMC XM25QH64A, 0x207017, 0x4000000, 0x1000, 0x20, 64, 0 XM25QH128A, 0x207018, 0x8000000, 0x1000, 0x20, 64, 0 XM25QU64A, 0x203817, 0x4000000, 0x1000, 0x20, 64, 0 XM25QH32B, 0x204016, 0x2000000, 0x1000, 0x20, 64, 0
U-Boot(Universal Bootloader)是一款开源的、通用的、模块化的嵌入式系统引导加载程序。它可以被用于各种嵌入式系统中,如计算机主板、网络设备、无线设备等。 在U-Boot中,对于Nor Flash的读写,主要是通过SPI接口进行的。下面是Nor Flash读写代码的走读: 1. 首先需要定义Nor Flash的设备结构体,其中包括了Nor Flash的基本信息以及对应的读写函数指针。 ``` struct flash_info { char* name; /* 设备名称 */ unsigned long base; /* 设备物理地址 */ unsigned long size; /* 设备大小 */ unsigned long sector_size; /* 扇区大小 */ unsigned long block_size; /* 块大小 */ void (*erase)(unsigned long); /* 擦除函数指针 */ void (*write)(unsigned long, const uchar*, unsigned long); /* 写函数指针 */ uchar (*read)(unsigned long); /* 读函数指针 */ }; ``` 2. 在U-Boot的配置文件中,需要定义Nor Flash的类型以及对应的设备结构体。 ``` #define CONFIG_SPI_FLASH_SST #define CONFIG_SPI_FLASH_WINBOND #define CONFIG_SPI_FLASH_MACRONIX #define CONFIG_SPI_FLASH_SPANSION #define CONFIG_SPI_FLASH_STMICRO #define CONFIG_SPI_FLASH_SST #define CONFIG_SPI_FLASH_ISSI #define CONFIG_SPI_FLASH_EON #define CONFIG_SPI_FLASH_GIGADEVICE #ifdef CONFIG_SPI_FLASH_SST #define CONFIG_FLASH_CFI_DRIVER #define CONFIG_SYS_MAX_FLASH_BANKS_DETECT 1 #define CONFIG_SYS_FLASH_CFI #define CONFIG_SYS_FLASH_PROTECTION #define CONFIG_SYS_FLASH_BASE 0x80000000 #define CONFIG_SYS_FLASH_EMPTY_INFO #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE #endif #ifdef CONFIG_SPI_FLASH_STMICRO #define CONFIG_FLASH_CFI_DRIVER #define CONFIG_SYS_MAX_FLASH_BANKS_DETECT 1 #define CONFIG_SYS_FLASH_CFI #define CONFIG_SYS_FLASH_PROTECTION #define CONFIG_SYS_FLASH_BASE 0x80000000 #define CONFIG_SYS_FLASH_EMPTY_INFO #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE #endif ``` 3. 在Nor Flash驱动中,需要实现读写、擦除等具体操作函数。 ``` static void spi_flash_cmd_write(struct spi_flash *flash, const void *buf, size_t size, uint32_t addr) { /* 发送写命令 */ spi_flash_cmd_write_enable(flash); spi_flash_cmd_addr(flash, addr, flash->cmd.write); spi_flash_cmd_buf(flash, buf, size); spi_flash_cmd_wait_ready(flash); } static void spi_flash_cmd_read(struct spi_flash *flash, void *buf, size_t size, uint32_t addr) { /* 发送读命令 */ spi_flash_cmd_addr(flash, addr, flash->cmd.read); spi_flash_cmd_buf(flash, NULL, size); spi_flash_cmd_read_data(flash, buf, size); } ``` 4. 在Nor Flash驱动中,还需要实现设备初始化、扇区擦除等操作。 ``` static int spi_flash_probe(struct spi_flash *flash) { /* 初始化设备 */ spi_flash_cmd_init(flash); /* 读取设备ID */ spi_flash_cmd_read_id(flash); /* 设置读写擦除函数指针 */ flash->write = spi_flash_cmd_write; flash->read = spi_flash_cmd_read; flash->erase = spi_flash_cmd_erase; return 0; } static int spi_flash_erase_sector(struct spi_flash *flash, uint32_t addr) { /* 发送擦除命令 */ spi_flash_cmd_write_enable(flash); spi_flash_cmd_addr(flash, addr, flash->cmd.erase); spi_flash_cmd_wait_ready(flash); return 0; } ``` 5. 在main函数中,需要初始化SPI总线以及Nor Flash设备,并进行读写操作。 ``` int main(void) { /* 初始化SPI总线 */ spi_init(); /* 初始化Nor Flash设备 */ spi_flash_init(); /* 读取数据 */ spi_flash_read_data(FLASH_BASE_ADDR, buf, sizeof(buf)); /* 写入数据 */ spi_flash_write_data(FLASH_BASE_ADDR, buf, sizeof(buf)); /* 擦除扇区 */ spi_flash_erase_sector(FLASH_BASE_ADDR); return 0; } ``` 以上就是Nor Flash读写的主要代码走读。在实际应用中,还需要根据具体的Nor Flash型号以及使用场景进行相应的优化和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heat.huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值