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

news2024/12/30 1:39:32

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"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/999813.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

十 动手学深度学习v2 ——卷积神经网络之NiN + GoogLeNet

文章目录 网络中的网络(NiN)InceptionGoogLeNet总结: 网络中的网络(NiN) NiN块使用卷积层加两个1x1卷积层 后者对每个像素增加了非线性性 NiN使用全局平均池化层来替代VGG和AlexNet中的全连接层 不容易过拟合&#xf…

win10CPU占用率高达100%怎么办

很多小伙伴在打开任务管理器的时候会发现win10CPU的占用率高达了100%,这使得我们的电脑用起来十分的卡顿,那么这个问题该怎么解决呢,这里小编就给大家带来win10CPU占用率高达100%的解决方法,有需要的小伙伴快来看看吧。 win10CPU占…

电子行业云MES解决方案

电子行业MES解决方案主要是针对目前电子生产制造企业面临的产品迭代升级中多品种小批量混线生产、存呆滞问题多;质量检查标准多、售后问题难追溯;生产进度难追踪、车间物料难管控、实际成本难计算等问题,提出的一种切实可行且能降低成本、提高效率的有效…

【视觉检测】电源线圈上的导线弯直与否视觉检测系统软硬件方案

 检测内容 线圈上的导线弯直与否检测系统。  检测要求 检测线圈上的导线有无弯曲,弯曲度由客户自己设定。检测速度5K/8H625PCS/H。  视觉可行性分析 对样品进行了光学实验,并进行图像处理,原则上可以使用机器视觉进行测试测量…

手把手教你maven的安装与配置(windows)

手把手教你maven的安装与配置 一、Maven 是什么二、Maven 的安装1. 下载2. 环境配置 三、Maven 的配置文件1. 本地仓库2. 远程仓库3. 代理服务器4. 服务器认证5. 其他选项6. 配置示例 四、对接IDEA 提起Maven,相信大家并不陌生,对于一些java开发者&#…

C#获取屏幕的分辨率、工作区分辨率

运行结果如下; 由于屏幕的任务栏在侧面所以屏幕宽度变化。 代码如下 private void Form1_Load(object sender, EventArgs e){int SH Screen.PrimaryScreen.Bounds.Height; //1080int SW Screen.PrimaryScreen.Bounds.Width; //1920System.Drawing.Rectangle rec Screen.Get…

从零开始搭建Apache服务器并使用内网穿透技术实现公网访问

Apache服务安装配置与结合内网穿透实现公网访问 文章目录 Apache服务安装配置与结合内网穿透实现公网访问前言1.Apache服务安装配置1.1 进入官网下载安装包1.2 Apache服务配置 2.安装cpolar内网穿透2.1 注册cpolar账号2.2 下载cpolar客户端 3. 获取远程桌面公网地址3.1 登录cpo…

【hive】—原有分区表新增加列(alter table xxx add columns (xxx string) cascade;)

项目场景: 需求:需要在之前上线的分区报表中新增加一列。 实现方案: 1、创建分区测试表并插入测试数据 drop table test_1; create table test_1 (id string, score int, name string ) partitioned by (class string) row format delimit…

OSPF实验:配置与检测全网互通

文章目录 一、实验背景与目的二、实验拓扑三、实验需求四、实验解法1. 配置 IP 地址2. 按照图示分区域配置 OSPF ,实现全网互通3. 检查是否全网互通 摘要: 本篇文章介绍了一个 OSPF(Open Shortest Path First)实验,旨在…

瀑布流布局2

要实现瀑布流布局中让图片先排满第一行再排第二行,你可以使用 CSS 的多列布局(CSS multi-column layout)来控制。目前你的布局使用了 column-count 和 column-gap 来定义列数和列之间的间隙,但这会导致在不同列之间平均分布元素。…

【c#】log4net用法

log4net用法 1、新建配置文件 在项目的bin文件下新建config文件&#xff1a;\logUtil\bin\Debug\net6.0\log4net.config文件&#xff0c; 2、config配置文件参考&#xff1a; 配置一&#xff1a; <?xml version"1.0"?> <configuration><config…

Apache服务器的下载与安装

Apache官方下载地址是&#xff1a;https://httpd.apache.org/&#xff0c;点击右上角“Download” 点击“Files for Micsoft Windows” 点击“ApacheHaus” 根据系统选择对应的版本&#xff08;我选择 64 位的&#xff09;&#xff0c;点击图标开始下载 解压到自己的目录下…

【多线程】阻塞队列 详解

阻塞队列 详解 一. 什么是阻塞队列二. 生产者消费者模型三. 标准库中的阻塞队列四. 阻塞队列实现 一. 什么是阻塞队列 阻塞队列是一种特殊的队列. 也遵守 “先进先出” 的原则. 阻塞队列是一种线程安全的数据结构, 并且具有以下特性: 当队列满的时候, 继续入队列就会阻塞, 直…

freeswitch 播放远程文件的流程

freeswitch中既可以播放本地文件&#xff0c;也可以播放远程文件&#xff0c;如 loop_playback(1 https://xxxxxx/filename.wav) 即文件名以https:// 或者 http:// 开头。 流程图如下&#xff1a; 如何根据文件找对应的open回调函数呢&#xff1a; 用命令&#xff1a;show…

开利网络为祥兴集团营销团队提供驻场服务,共建数字化活力世界

近日&#xff0c;开利网络到访广西祥兴实业集团&#xff0c;参与全员营销会议&#xff0c;就集团目前如何推动业务增速、如何推动集团“活力世界”平台落地运营、共建营销激励机制进行落地沟通。 ​开利网络认为&#xff0c;集团目前存在营销目标分散、营销机制不清和营销产品混…

Apinto 网关: Go语言实现 HTTP 转 gRPC

gRPC 是由 Google 开发的一个高性能、通用的开源RPC框架&#xff0c;主要面向移动应用开发且基于 HTTP/2 协议标准而设计&#xff0c;同时支持大多数流行的编程语言。 gRPC 基于 HTTP/2 协议传输&#xff0c; HTTP/2 相比 HTTP1.x有以下优势: 采用二进制格式传输协议&#xff…

你真的会设计测试用例吗?

前言 最近干的最多的事情就是设计测试用例、评审测试用例了&#xff0c;于是我不禁又想到了一个经典的问题&#xff1a;如何设计出优秀的测试用例&#xff1f; 可能有些童鞋看到这个问题会有些不以为然&#xff0c;这有什么好想的&#xff1f;干个测试谁还不会设计测试用例&a…

IDEA插件的在线离线安装

插件的使用 插件的设置 在 IntelliJ IDEA 的安装讲解中我们其实已经知道&#xff0c;IntelliJ IDEA 本身很多功能也都是通过插件的方式来实现的&#xff0c;只是 IntelliJ IDEA 本身就是它自己的插件平台最大的开发者而已&#xff0c;开发了很多优秀的插件。 官网插件库&…

pdf怎么转换成ppt?可以试试这三种方法

pdf怎么转换成ppt&#xff1f;PDF和PPT是我们工作、学习中最为常见的文档格式之一&#xff0c;特别是PPT&#xff0c;几乎成为了商务汇报和学术演示的标配。有时候&#xff0c;我们需要将PDF文档转换成PPT格式以方便编辑和演示。那么&#xff0c;PDF怎么转换成PPT呢&#xff1f…

信息化建设第三方验收测试报告要求

信息化建设是企业未来高质量发展的必由之路&#xff0c;也是企业法治的必要手段。 信息化建设指品牌利用现代信息技术来支撑品牌管理的手段和过程。随着计算机技术、网络技术和通信技术的发展和应用&#xff0c;企业信息化已成为品牌实现可持续化发展和提高市场竞争力的重要保…