ARM NandFlash 介绍

news2024/11/15 12:43:41

一、NandFlash 的接口

1、Nand 的型号与命名

(1) Nand 的型号命名都有含义,就拿 K9F2G08 来示例分析一下:K9F 表示是三星公司的 NandFlash 系列。2G 表示 Nand 的大小是 2Gbit(256MB)。08 表示 Nand 是 8 位的( 8 位就是数据线有 8 根)。

(2) Nand 命名中可以看出:厂家、系列型号、容量大小、数据位数。


2、Nand 的数据位

(1) Nand 有 8 位数据位的,有 16 位数据位的。做电路时/写软件时应该根据自己实际采购的 Nnad 的位数来设计电路/写软件。

(2) 说明 Nand 是并行接口的(8/16位)。

(3) Nand 的数据线上传递的不一定全部是有效数据,也可能有命令、地址等。


3、Nand 的功能框图

在这里插入图片描述


在这里插入图片描述

(1) Nand 的结构可以看成是一个矩阵式存储器,其中被分成一个一个的小块,每一小块可以存储一个 bit 位,然后彼此以一定单位组合成整个 Nand。

(2) Nand 中可以被单次访问的最小单元(就是说对 Nand 进行一次读写至少要读写这么多,或者是这么多的整数倍)叫做 Page(页)。在 K9F2G08 芯片中,Page 的大小是 2KB+64B。也就是说我们要读写 K9F2G08,每次至少要读写 2KB 或者 n*2KB,即使我们只是想要其中的一个字节。这就是我们说的典型的块设备(现在有些块设备为了方便,提供了一种 random read 模式,可以只读取 1 个字节)。

(3) 页往上还有个 Block(块)的概念,1个块 Block 等于若干个页 Page(譬如在 K9F2G08 中 1 个块 Block 等于 64 页 Page)。

(4) 块 Block 往上就是整个 Nand 芯片了,叫做 Device。一个 Device 是若干个 Block,譬如 K9F2F08 一个 Device 有 2028 个 block。所以整个 Device 大小为: 2048×64×2K = 256MB。

(5) 块设备分 page、block 有什么意义?首先要明白,块设备不能完全按字节访问而必须块访问,是物理上的限制,而不是人为设置的障碍。其次,Page 和 Block 各有各的意义,譬如 Nand 中:Page 是读写 Nand 的最小单位;Block 是擦除 Nand 的最小单位。(这些规则都是 Nand 的物理原理和限制要求的,不是谁想要这样的,所以对于我们做软件的来说,只能去想办法适应硬件,不是想着超越硬件)。

在这里插入图片描述


(6) Nand 芯片中主要包含 2 部分:Nand 存储颗粒+ Nand 接口电路。 存储颗粒就是纯粹的 Nand 原理的存储单元,类似于仓库;Nand 接口电路是用来管理存储颗粒,并且给外界提供一个统一的 Nand 接口规格的访问接口的。

(7) Nand 中有多个存储单元,每个单元都有自己的地址(地址是精确到字节的)。所以 Nand 是地址编排精确到字节,但是实际读写却只能精确到页 Page(所以 Nand 的很多操作,都要求给的地址是页 Page 对齐的,譬如 2K、4K、512K 等这样的地址,不能给 3000B 这样的地址)。Nand 读写时地址传递是通过 IO 线发送的,因为地址有 30 位而 IO 只有 8 位,所以需要多个 cycle 才能发送完毕。一般的 Nand 都是 4cycle 或者 5cycle 发送地址(从这里把 Nand 分为了4cycle Nand 和 5cycle Nand)。

在这里插入图片描述


总结:Nand 芯片内部有存储空间,并且有电路来管理这些存储空间,向外部提供统一的 Nand 接口的访问规则,然后外部 SoC 可以使用 Nand 接口时序来读写这个 Nand 存储芯片。Nand 接口是一种公用接口,是一种标准,理论上来说外部 SoC 可以直接模拟 Nand 接口来读写 Nand 芯片,但是实际上因为 nand 接口对时序要求非常严格,而且时序很复杂,所以一般的 SoC 都是通过专用的硬件的 Nand 控制器(这些控制器一般是作为 SoC 的内部外设来存在的)来操控 Nand 芯片的。


二、NandFlash 的结构

1、Nand 的单元组织:block与page(大页Nand与小页Nand)

(1) Nand 的页 page 和以前讲过的块设备(尤其是硬盘)的扇区 sector 是类似的。 扇区最早在磁盘中是 512 字节,后来也有些高级硬盘扇区不是 512 字节,而是 1024字节/2048字节/4096字节等。Nand 也是一样,不同的 Nand 的页的大小是不同的,也有 512字节/1024字节/2048字节/4096字节等。

(2) 一个 block 等于多少 page 也是不定的,不同的 Nand 也不同。一个 Nand 芯片有多少 block 也是不定的,不同的 Nand 芯片也不同。

总结:Nand 的组织架构挺乱的,接口时序也不同,造成结果就是不同厂家的 Nand 芯片,或者是同一个厂家的不同系列型号存储容量的 nand 接口也不一样。所以 nand 有一个很大的问题就是,一旦升级容量或者换芯片系列则硬件要重新做、软件要重新移植。


2、带内数据和带外数据(ECC与坏块标记)

(1) Nand 的每个页 page 由 2 部分组成,这 2 部分各自都有一定的存储空间。譬如 K9F2G08 中为 2K+64 字节。其中的 2K 字节属于带内数据,是我们真正的存储空间,将来存储在 Nand 中的有效数据就是存在这 2K 范围内的(我们平时计算 nand 的容量时也是只考虑这 2KB);64 字节的带外数据不能用来存储有效数据,是作为别的附加用途的(譬如用来存储 ECC 数据、用来存储坏块标志等····)。
在这里插入图片描述


(2) 什么是 ECC:(error correction code,错误校验码)。因为 nand 存储本身出错(位反转)概率高(NandFlash 较 NorFlash 最大的缺点就是稳定性),所以当我们将有效信息存储到 Nand 中时都会同时按照一定算法,计算一个 ECC 信息(譬如 CRC16 等校验算法),将 ECC 信息同时存储到 Nand 这个页的带外数据区。 然后等将来读取数据时,对数据用同样的算法再计算一次 ECC,并且和从带外数据区读出的 ECC 进行校验。 如果校验通过,则证明 Nand 的有效数据可信;如果校验不通过,则证明这个数据已经被损坏(只能丢弃或者尝试修复)。

(3) 坏块标志:Nand 芯片用一段时间后,可能某些块会坏掉(这些块无法擦除了,或者无法读写了),nand 的坏块非常类似于硬盘的坏道。坏块是不可避免的,而且随着 Nand 的使用,坏块会越来越多。当坏块还不算太多时,这个 Nand 都是可以用的,除非坏块太多了不划算使用了才会换新的。所以我们为了管理 Nand 发明了一种坏块标志机制。Nand 的每个页的 64 字节的带外数据中,我们(一般是文件系统)定义一个固定位置(譬如定位第24字节)来标记这个块是好的还是坏的。文件系统在发现这个块已经坏了没法用了时,会将这个块标记为坏块,以后访问 nand 时直接跳过这个块即可。

Invalid Block(s)

在这里插入图片描述


在这里插入图片描述


3、Nand 的地址时序

(1) nand 的地址有多位,分 4/5 周期通过 IO 引脚发送给 Nand 芯片来对 Nand 进行寻址。寻址的最小单位是字节,但是读写的最小单位是页 page。

在这里插入图片描述

(2) nand 的地址在写代码时,要按照 Nand 要求的时序和顺序去依次写入。


4、Nand 的命令码

(1) 外部 SoC 要想通过 Nand 控制器来访问 Nand(实质就是通过 Nand 接口),就必须按照Nand 接口给 nand 发送命令、地址、数据等信息来读写 Nand。

(2) Nand 芯片内部的管理电路本身可以接收外部发送的命令,然后根据这些命令来读写 Nand 内容与外部 SoC 交互。所以我们对 nand 进行的所有操作(擦除、读、写···)都要有命令、地址、数据的参与才能完成,而且必须按照 Nand 芯片规定的流程来做。


三、NandFlash的常见操作及流程分析

1、坏块检查

在这里插入图片描述

(1) Flash 使用之前要先统一擦除(擦除的单位是块)。Flash 类设备擦除后里面全 是1,所以擦干净之后读出来的值是 0xff。


在这里插入图片描述

(2) 检查坏块的思路就是:先块擦除,然后将整块读出来,依次检测各自节是否为 0xff,如果是则表明不是坏块,如果不是则表明是坏块。


2、页写(program)操作

(1) 写之前确保这个页是被擦除干净的。如果不是擦除干净的(而是脏的、用过的)页,写进去的值就是错的,不是你想要的结果。

(2) 写操作(write)在 flash 的操作中就叫编程(program)。

在这里插入图片描述


(3) SoC 写 Flash 时通过命令线、IO 线依次发送写命令、写页地址、写数据等进入 NandFlash。

(4) 写的过程:SoC 通过 Nand 控制器和 Nand 芯片完成顺序对接,然后按照时序要求,将一页 page 数据发给 Nand 芯片内部的接口电路。 接口电路先接收数据到自己的缓冲区,然后再集中写入 Nand 芯片的存储区域中。Nand 接口电路将一页 page 数据从缓冲区中写入 Nand 存储系统中需要一定的时间,这段时间 Nand 芯片不能再响应 SoC 发过来的其他命令,所以 SoC 要等待Nand 接口电路忙完。等待方法是, SoC 不断读取状态寄存器(这个状态寄存器有 2 种情况:一种是 SoC 的 Nand 控制器自带的,另一种是 SoC 通过发命令得到命令响应得到的),然后通过检查这个状态寄存器的状态位就能知道 Nand 接口电路刚才写的那一页数据写完了没、写好了没。直到 SoC 收到正确的状态寄存器响应才能认为刚才要写的那一页数据已经 ok。(如果 SoC 收到的状态一直不对,可以考虑重写或者认为这一页所在的块已经是坏块,或者整个 Nand 芯片已经挂掉了)。

(5) 正常情况下到了第四步就已经完了。但是因为 Nand 的读写有不靠谱情况,因此我们为了安全会去做 ECC 校验。ECC 校验有硬件式校验和软件式校验 2 种。软件式校验可以采用的策略有很多,其中之一(Nand 芯片手册上推荐的方式是):将刚才写入的 1 页数据读出来,和写入的内容进行逐一对比。如果读出的和写入的完全一样,说明刚才的写入过程正确完成了;如果读出来的和写入的不完全一样,那就说明刚才的写入有问题。

(6) 硬件式 ECC:SoC 的 Nand 控制器可以提供硬件式 ECC(这个也是比较普遍的情况)。硬件式 ECC就是在 Nand 的控制器中有个硬件模块专门做 ECC 操作。当我们操作 Nand 芯片时,只要按照 SoC 的要求按时打开 ECC 生成开关,则当我们写入 Nand 芯片时,SoC 的 Nand 控制器的 ECC 模块会自动生成 ECC 数据放在相应的寄存器中,然后我们只需要将这生成的 ECC 数据写入 Nand 芯片的带外数据区即可;在将来读取这块 Nand 芯片时,同样要打开硬件 ECC 开关,然后开始读,在读的过程当中,硬件 ECC 会自动计算读进来的一页数据的 ECC 值并将之放到相应的寄存器中。然后我们再读取带外数据区中原来写入时存入的 ECC 值,和我们刚才读的时候得到的 ECC 值进行校验。 校验通过则说明读写正确,校验不通过则说明不正确(放弃数据或者尝试修复)。


3、擦除(erase)操作

(1) 擦除时必须给块对齐的地址。如果给了不对齐的地址,结果是不可知的(有些 Nand 芯片没关系,它内部会自动将其对齐,而有些 Nand 会返回地址错误)。
(2) 读写时给的地址也是一样,要求是页对齐地址。如果给了不对齐的,也是有可能对有可能错。

在这里插入图片描述


4、页读(read)操作

在这里插入图片描述


四、S5PV210 的 NandFlash 控制器

1、SoC 的 Nand 控制器的作用

在这里插入图片描述

由于 NOR flash 以及价格适中的 DRAM 和 NAND flash 的价格最近有所上涨,客户更喜欢在NAND flash 上执行引导代码 boot code,并在 DRAM 上执行主代码 main code 。

S5PV210 中的引导代码 boot code 可以在外部 NAND flash 上执行。它将 NAND flash 数据复制到 DRAM。为了验证 NAND 闪存数据,S5PV210 包括硬件纠错码(ECC)。NAND flash 内容复制到 DRAM 后,主程序 main program 将在 DRAM 上执行。


(1) Nand 芯片本身通过 Nand 接口电路来存取数据,Nand 接口电路和 SoC 之间通过 Nand 接口时序来通信。Nand 接口时序相对复杂,如果要 SoC 完全用软件来实现 Nand 接口时序有一些不好(主要是:第一很难保证时序能满足、容易不稳定;第二代码很难写)。解决方案是:在 SoC 内部集成一个 Nand 控制器(实质就是一块硬件电路,这个硬件电路完全满足 Nand 接口时序的操作,然后将接口时序的操作寄存器化)。

(2) SoC 和 Nand 芯片之间通信。在 SoC 没有 Nand 控制器时,需要 SoC 自己来处理接口时序,编程很麻烦,需要程序员看 Nand 芯片的接口时序图,严格按照接口时序图中编程(尤其要注意各个时间参数);在 SoC 有 Nand 控制器时,SoC 只需要编程操控 Nand 控制器的寄存器即可,Nand 控制器内部硬件会根据寄存器值来生成合适的 Nand 接口时序,来和 Nand 芯片通信。所以在有 Nand 控制器时,编程要简单很多,我们读写 Nand 芯片时,再也不用关注 Nand 接口时序了,只要关注 SoC 的 Nand 控制器的寄存器即可。

(3) 扩展来讲,现在的技术趋势就是:几乎所有的外设在 SoC 内部都有对应的控制器来与其通信,那么 SoC 内部集成的各种控制器(也就是各种内部外设)越多,则 SoC 硬件能完成的功能越多,将来用这个 SoC 来完成相应任务时,软件编程越简单。譬如说图形处理和图像处理领域,2D图像编码(jpeg编码)、视频编码(h.264编码),现在大部分的a pplication 级别的 SoC 都有集成的内部编码器(像S5PV210就有、更复杂的譬如4418、6818就更不用说了,只会更多更先进),我们可以利用这些硬件编码器来进行快速编解码,这样软件工作量和难度降低了很多(这就是所谓的硬件加速)。


2、结构框图分析

在这里插入图片描述

结构框图中关键点:SFR(我们后续编程的关键,编程时就是通过读写 SFR 来产生 Nand 接口时序,以读写 Nand 芯片的) + Nand interface(硬件接口,将来和 Nand 芯片的相应引脚进行连接) + ECC 生成器。


3、S5PV210 的 Nand 控制器的主要寄存器

NFCONF、NFCONT、NFCMMD、NFADDR、NFDATA、NFMECCD0&NFMECCD1、NFSECCD、NFSTAT。

在这里插入图片描述


在这里插入图片描述

《x210cv3.pdf》


在这里插入图片描述


在这里插入图片描述


五、Nand 操作代码解析

1、擦除函数

2、页读取函数

3、页写入函数


总结:

(1) 像 NandFlash 这类芯片,通过专用的接口时序和 SoC 内部的控制器相连(这种连接方式是非常普遍的,像 LCD、DDR 等都是类似的连接)。这种接法和设计对我们编程来说,关键在于两点:SoC 的控制器的寄存器理解,和 Nand 芯片本身的文档、流程图等信息。

(2) 对于我们来说,学习 NandFlash,要注意的是:
第一,要结合 SoC 的数据手册、Nand 芯片的数据手册、示例代码三者来理解。
第二,初学时不要尝试完全不参考,自己写出 Nand 操作的代码,初学时应该是先理解实例代码,知道这些代码是怎么写出来的,必要时对照文档来理解代码。代码理解之后去做实践,实践成功后以后再考虑,自己不参考代码只参考文档来写出 nand 操作的代码。


源自朱有鹏老师.

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

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

相关文章

员工入职管理系统|员工管理系统|基于SpringBoot+Vue的企业新员工入职系统

作者主页:编程指南针 作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

SICTF2023 WP

前言 新年前的最后一场比赛&#xff0c;感谢shenghuo2师傅提供的misc和密码的wp&#xff0c;把misc和密码ak了&#xff0c;太强了 web 兔年大吉 源码 <?php highlight_file(__FILE__); error_reporting(0);class Happy{private $cmd;private $content;public function _…

Registration Center

CAP●一致性(Consistency)&#xff1a;所有节点在同一时间具有相同的数据&#xff1b;●可用性(Availability) &#xff1a;保证每个请求不管成功或者失败都有响应&#xff1b;某个系统的某个节点挂了&#xff0c;但是并不影响系统的接受或者发出请求。●分隔容忍(Partition to…

python循环语句

Python循环语句 文章目录Python循环语句一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.While循环结构2.While无限循环3.For循环语法4.break语句和continue语句一、实验目的 掌握循环结构的语法 二、实验原理 Python中的循环语句有 for 和 while。 Python…

AcWing蓝桥杯AB组辅导课07、贪心

文章目录前言一、贪心模板题例题1&#xff1a;AcWing 104. 货仓选址&#xff08;贪心&#xff0c;简单&#xff0c;算法竞赛进阶指南&#xff09;分析题解&#xff1a;贪心思路例题例题1&#xff1a;AcWing 1055. 股票买卖 II&#xff08;贪心、状态机&#xff0c;简单&#xf…

[ESP][驱动]GT911 ESP系列驱动

GT911ForESP GT911在ESP系列上的驱动&#xff0c;基于IDF5.0&#xff0c;ESP32S3编写 本库使用面向对象思想编写&#xff0c;可创建多设备多实例 Github&#xff0c;Gitee同步更新&#xff0c;Gitee仅作为下载仓库&#xff0c;提交Issue和Pull request请到Github Github: h…

具体芯片的I2C_Adapter驱动分析

具体芯片的I2C_Adapter驱动分析 文章目录具体芯片的I2C_Adapter驱动分析参考资料&#xff1a;一、 I2C控制器内部结构1.1 通用的简化结构1.2 IMX6ULL的I2C控制器内部结构二、 I2C控制器操作方法三、 分析代码3.1 设备树3.2 驱动程序分析致谢参考资料&#xff1a; Linux内核真正…

03_筛选标记2.0版和3.0版FIND及ColorIndex

文章目录2.0版工作簿筛选标记筛选sheet标记取消筛选标记3.0版ColorIndex 下标代码特别鸣谢,大佬的分享FIND方法的使用2.0版 工作簿筛选标记 Option Explicit Sub 自动筛选()Dim Town As StringDim wsh As WorksheetCall 初始化 初始化表格状态Town InputBox("请输入街…

SLAM笔记——turtlebot传感器ekf实验实验

这里写目录标题实验内容实验准备msg数据类型给uwb和odom增加噪声robot_pose_ekf发布路径实验结果实验内容 本实验将在gazebo仿真环境中使用ekf进行传感器数据融合。本文使用turtlebot3进行实验&#xff0c;turtlebot本身会发布odom和imu。imu的误差可以在urdf文件中进行调整&a…

追梦之旅【数据结构篇】——对数据结构的认知 + 初识时间复杂度和空间复杂度~

详解C语言函数模块知识(下篇&#xff09;&#x1f60e;前言&#x1f64c;浅谈数据结构~&#x1f64c;1、什么是数据结构&#xff1f;(ˇˍˇ) 想&#xff5e;2、什么是算法&#xff1f;ˇˍˇ) 想&#xff5e;3、数据结构和算法的重要性&#x1f60a;4、如何才能学好数据结构呢…

初识 NodeJS(基于 Chrome V8 引擎的 JavaScript 运行时环境)

初识 NodeJS&#xff08;基于 Chrome V8 引擎的 JavaScript 运行时环境&#xff09;参考描述NodeJSNodeJS 可以做什么&#xff1f;特点用武之地获取检测运行JavaScript 运行时环境JavsScript 引擎浏览器中的 JavaScript 运行时环境Chrome 浏览器运行时环境NodeJS 中的 JavaScri…

【着色器实现海面效果_菲尼尔/Unlit/Transparent】

1.水体颜色 2.反射,水面波纹流动 3.折射、水底、水底透明度和折射 4.焦散,在水底接近岸边的水域 5.岸边泡沫,水花接近岸边的泡沫 6.水体运动,顶点动画 用灯光模式是Light Model :Unilt Render Type:Transparent 获取水面深度 利用这个节点,从深度图获取世界空间的位…

如何做流程图?这几个实用的制作流程图方法分享给你

说到流程图的制作&#xff0c;相信大家都并不陌生&#xff0c;在日常的工作和学习中&#xff0c;我们都会根据需求接触到各种各样的流程图&#xff0c;有时还要自己动手绘制流程图并使用&#xff0c;但你是否会因为不会绘制流程图而感到苦恼呢&#xff1f;没关系&#xff0c;今…

vue中利用ref实现更灵活的子向父传值

目录前言一&#xff0c;基础代码二&#xff0c;层次递进的讲解用法2.1 给子组件设置ref2.2 自定义事件2.3 给子组件设置一个自定义事件三&#xff0c;灵活性四&#xff0c;注意后记前言 目前我们熟知的子向父传值有两种方式&#xff1a; 一种是在父组件中定义函数&#xff0c;…

【AI】Windows配置GPU Cuda驱动和Pytorch框架

目录 1、Cuda驱动安装 1.1 查看显卡硬件 1.2 查看cuda版本 2、Annaconda python环境准备 2.1 创建pytorch_gpu 2.2 查看python版本 3、Pytorch和torchVsion软件安装 4、验证测试 在进行AI项目开发的时候&#xff0c;经常要在GPU环境中运行代码&#xff0c;对于没有配置…

动手深度学习-pytorch线性代数

标量简单操作长度向量简单操作长度其他操作矩阵简单操作乘法&#xff08;矩阵*向量&#xff09;乘法&#xff08;矩阵*矩阵&#xff09;范数取决于如何衡量b和c的长度常见范数矩阵范数&#xff1a;最小的满足的上面公式的值Frobenius范数特殊矩阵对称和反对称正定正交矩阵置换矩…

Solidity 中的数学(第 4 部分:复利)

本文是关于在 Solidity 中进行数学运算的系列文章中的第四篇。这次的主题是&#xff1a;复利。 介绍 在我们之前的文章中&#xff0c;我们讨论了百分比以及它们是如何在 Solidity 中计算的。在金融数学中&#xff0c;百分比通常与贷款和存款支付的利息有关。在每个时间段结束时…

深度学习入门基础CNN系列——批归一化(Batch Normalization)和丢弃法(dropout)

想要入门深度学习的小伙伴们&#xff0c;可以了解下本博主的其它基础内容&#xff1a; &#x1f3e0;我的个人主页 &#x1f680;深度学习入门基础CNN系列——卷积计算 &#x1f31f;深度学习入门基础CNN系列——填充&#xff08;padding&#xff09;与步幅&#xff08;stride&…

CSS 搜索框

CSS 搜索框 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>搜索框</title><style type"text/css">* {margin: 0;padding: 0;}.search-container {margin: 50px;display: flex;width: 500px;height:…

rtthread pwm

1、配置PWM设备驱动相关宏定义 1.1 配置PWM和TIM设备驱动 在RT-Thread Settings 配置界面中&#xff0c;在设备驱动程序目录下勾选 HWTIMER 和 PWM设备驱动程序&#xff0c;如下图所示&#xff1a; 配置完后在 rtconfig.h 中可以查看刚刚配置的 RT_USING_HWTIMER 和 RT_U…