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

2023-10-19 01:30

本文主要是介绍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 0x20000mtd_debug write /dev/mtd0 0 0x20000 sample.binmtd_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"

这篇关于Macronix MX25L25645G NOR Flash无法擦除问题分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/236396

相关文章

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

三国地理揭秘:为何北伐之路如此艰难,为何诸葛亮无法攻克陇右小城?

俗话说:天时不如地利,不是随便说说,诸葛亮六出祁山,连关中陇右的几座小城都攻不下来,行军山高路险,无法携带和建造攻城器械,是最难的,所以在汉中,无论从哪一方进攻,防守方都是一夫当关,万夫莫开;再加上千里运粮,根本不需要打,司马懿只需要坚守城池拼消耗就能不战而屈人之兵。 另一边,洛阳的虎牢关,一旦突破,洛阳就无险可守,这样的进军路线,才是顺势而为的用兵之道。 读历史的时候我们常常看到某一方势

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

缓存雪崩问题

缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库,瞬间耗尽数据库资源,导致数据库无法使用。 解决方案: 1、使用锁进行控制 2、对同一类型信息的key设置不同的过期时间 3、缓存预热 1. 什么是缓存雪崩 缓存雪崩是指在短时间内,大量缓存数据同时失效,导致所有请求直接涌向数据库,瞬间增加数据库的负载压力,可能导致数据库性能下降甚至崩溃。这种情况往往发生在缓存中大量 k

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

衡石分析平台使用手册-单机安装及启动

单机安装及启动​ 本文讲述如何在单机环境下进行 HENGSHI SENSE 安装的操作过程。 在安装前请确认网络环境,如果是隔离环境,无法连接互联网时,请先按照 离线环境安装依赖的指导进行依赖包的安装,然后按照本文的指导继续操作。如果网络环境可以连接互联网,请直接按照本文的指导进行安装。 准备工作​ 请参考安装环境文档准备安装环境。 配置用户与安装目录。 在操作前请检查您是否有 sud