深入理解nandflash之基本特性

2023-11-07

nandflash作为嵌入式中的”磁盘”, 被广泛的应用, 以(K9F2G08U0B)为例,其他型号都差不多

  • nandflash的结构
    这里写图片描述
    nandflash的结构有页(page), block(块)的概念,其中页是真实概念,而块儿是虚拟概念(目的是为了更好的管理存储空间)
    page: 一个page大小为2K + 64bytes, 如上图所示,其中的64bytes是所在页的infomation, 记录着此页的使用情况,比如剩余存空间等
    block: 一个block由64个页组成, 一个nandflash芯片由2k个block组成,算算就知道,一个nandflash芯片一共能存储256M的数据.
  • nandflash的引脚说明
    这里写图片描述
  • nandflash与2440的连接
    这里写图片描述
    由上连接图可以看出,ALE,CLE这种信号其实就是2440的GPIO(体现了管脚复用的功能)
    注意,与nandflash的数据传输接口就只有IO0->IO7这8根并行的数据线,所以我们发送读命令还是写命令还是地址,都是通过这8跟先发出的,具体情况如下分析
  • nandflash的读操作,先给出时序图(datasheet),之后在分析
    这里写图片描述
    首先我们先看一下读取nandflash需要一个什么样的周期
    1.首先发命令 00H(读命令)
    2.发送地址
    3.发送地址
    4.发送命令 30H(读命令)
    5.忙等待
    6.读取数据
    从数据手册上来看,对于命令代表的意义如下图所示
    这里写图片描述
    我们看到,读命令确实要发两次,那么为什么要这么操作呢?这其实根据nandflash的硬件来定的,第一次发读命令是把读取的命令放到nandflash的IO BUFFers这个硬件中,之后再发一次读命令才真正的把命令写入nandflash中,这样做的好处是为了降低页的写入时间
  • 根据时序图看过程1
    我们通过IO1–>IO7来发送读命令,此时nandflash如何区分到底是命令,地址,还是数据呢?
    很简单: 拉高CLE, 拉低ALE ,之后拉低WE,把命令00H放到I/O总线上,当WE由电平至高电平转变时,发生锁存,nandflash获取读命令
    这个过程要注意的是: 拉高CLE是为了锁存使能,也就是WE上升沿的时候可以锁存成功从而使nandflash获取命令数据,ALE拉低是为了告诉nandflash此时发的是命令数据
  • 根据时序图看过程2
    我们通过IO1–>IO7来发送地址
    这里写图片描述
    上图即我们需要传送地址的顺序,我们通过时序图发现要传送5次(5个周期)地址,每次的格式如上图所示,接着分析, 当拉低CLE,拉高ALE即认为开始发送地址信息, 之后拉低WE,将地址信息放到总线上,之后WE上升沿锁存,nandflash获取地址信息
    之后的分析过程相信自己就能分析了,
    注意:
    1.根据ALE与CLE的变化来区分总线IO1->IO7上的数据type
    2.关于地址说明:大多nandflash是以页为单位进行读取或者写入的,以K9F2G08U0B为例 子,读取一次数据最小就是2k(一页的数据量)的数据量,这是由硬件特性决定的,但不是绝对的,比如K9F2G08U0C这一款的nandflash支持页内的地址访问,所以我们在写nandflash底层读写函数都应该以页为单位进行读写
    3.写nandflash时,需要先擦除存储单元, 之后在向存储单元写入数据,要注意的是,nandflash擦除是以block为单位,也就是说一次最少要擦除1个block即64页的数据, 这也是硬件的限制,至于为什么要擦除?是因为硬件的原因,使得nandflash只能写入0,不能写1,所以擦除是为了让存储单元都变为1
  • 对于发送的地址要进行一个问题的讲解
    这里写图片描述
    上图中A0—>A11为Column Address,对应的是页内的偏移,问题来了, 一个页为2k大小,理论上A0->A10就可以了,那么为什么多出个A11呢?别忘了,一个页上除了2k大小的地方,还有个64Bytes的地方,要访问它的话,A0->A10地方不够不是,所以多出了个A11,当A11为0时,nandflash也不会理会这个ECC空间(64Bytes) 剩下的A12–>A28为页索引,因为一个块有64个页,所以我们把A12->A17定为页索引, A18->A28定为块索引,其对应关系如下图:
    这里写图片描述这个图很容易被人误导,
    比如我要发送读取nandflash 4096这个地址的数据, 换句话讲,应该是nandflash 4k数据后开始的数据,应该是第三个页的数据(即第2页,因为一个页大小为2k),所以将地址传入认为
    第一周期应该发送:A0-A7 —>00
    第二周期应该发送:A8-A11 —>00
    第三周期应该发送:A12-A19 —>01
    第四周期应该发送:A20-A27—->00
    第五周期应该发送:A28———>00
    这里写图片描述
    即上图中错误认为的情况,因为在我们的角度看来,是不存在A11的,所以应该是图中下面表示正确的情况(黄色为4096的2进制),或许说到这里大家还是似懂非懂,那我们在简单一点,比如从2049这个地址上取数据,在我们看来,应该是从第1页开始取数据,但是站在nandflash发送地址周期的角度上看,其实是访问第0页的地址(因为有A11为1,即访问64Bytes的范围),也就是说如果把2049严格按照发送周期送地址的话其实访问的是第0页64Bytes范围中了,这不是我们所希望的,所以我们要把2049这个地址变成第1页开始的地方,怎么办呢?将A11位至0,之后向后串一位即可.上图可以慢慢体会
    总结:
    此 Nand Flash 地址周期共有 5 个,2 个列(Column),3个行(Row)周期,而对于对应地,我们可以看出,实际上,列地址 A0~A10,就是页内地址,地址范围是从0 到2047,而对出的 A11,理论上可以表示 2048~4095,但是实际上,我们最多也只用到了2048~2011, 用于表示页内的oob区域,其大小是 64 字节。对应地,A12~A28,称作页号,页的号码,可以定位到具体是哪一个页。而其中,A18~A28,表示对应的块号,即属于哪个块。
我们写程序发送地址的时候是这样写的:
..........
unsigned int col_add = addr & 0x7ff; //A0-->A10(column Address)
unsigned int raw_add = (addr >> 11)&0x1ffff; //A11-->A28(页索引)

NFADDR = col_add & 0xff; //A0-A7 8位 
NFADDR = (col_add >> 8) & 0x7; //a11为0 A8-A11 3位
NFADDR = raw_add & 0xff; 
NFADDR = (raw_add >> 8) & 0xff;
NFADDR = (raw_add >> 16) & 0x1;
.....
..

在这里有些人感觉很奇怪,表格里rows明明是从A12开始的可是程序里raw_add= (addr >> 11)&0x1ffff,只向由移11位,不是应该addr >> 12吗?
最关键的地方到了,你别忘了,我们在存放数据的时候,数据里面不包括ECC信息,也就是说在我们自己看来nandflash页大小就是2K。比如说我往nand的0x0地址存了0x800(2KB)大小数据,接下来,如果我们再存数据就继续从0x800的地址开始存,在这里你跳过前一页的ECC部分了吗?很明显没有,理论上前一页占了0x1000(4KB)大小,我们应该从0x1000开始存接下的数据,可是,我们实际上不会这么干,我们忽略ECC占的空间,我们认为一页大小就是2KB。

所以在我们看来nandflash地址就是这样的:
nand地址=(rows:A27-A11)(columns:A10-A0)
接受到地址后,在发送地址时,我们是这么干的,把A0-A10取出来,再添上一位A11=0,,然后把A11-A27取出来,对应A12-A28发过去,这样就实现了在发送地址时跳过每一页的ECC部分,但在用户看来每一页大小还是2KB,这里有些绕,但是好好想一想还是能想清楚的。实在理解不了可以这么想,地址2049,应该是第1页开始地址,如果要访问第1页开始的地址,那么地址如何发?所以转换关系为: 2096—>第1页开始—>转换为5个周期地址

  • 关于nandflash的写擦除时序,与读的过程都大同小异,这里贴出datasheet中写时序,擦除时序图,方便以后查阅
  • 写时序
    这里写图片描述
    可以看到除了命令之外,其余与读时序基本差不多
  • 擦除block时序
    这里写图片描述
    如图可知,擦除的时序以block为单位,发送的地址 Row Add1后的三个地址
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入理解nandflash之基本特性 的相关文章

  • 决策树——信息熵,条件熵,信息增益

    1 信息熵 信息熵是度量样本集的纯合度的一种常用的指标 熵值越大 随机变量的不确定性越高 比如 0 0 01 1 1 1 1 2 3 4 5 6 7 在这两组数据中 上面的数据的不确定性要小 只有两种可能性 抽中的数字2的概率为1 2 所以
  • overleaf写论文笔记(latex)

    overleaf官网 www overleaf com overleaf中文版 cn overleaf com 目录 从零开始 获取模板 文章标题修改 作者修改 摘要 页脚文字重叠 遮挡 三线表绘制 表格内单元格合并 不同行列数不同 文字加
  • 黑盒、白盒、灰盒,如何选择合适的模糊测试工具?

    在软件开发和安全领域 模糊测试是一种常用技术 用于发现应用程序或系统中的潜在漏洞和安全弱点 选择不同的模糊测试方法将极大地影响测试的有效性和效率 本文将比较对比黑盒 白盒和灰盒模糊测试的特点和优势并提供选型指导 模糊测试的分类 黑盒模糊测试
  • JDBC学习笔记一之JDBC的下载、引用、标准api介绍

    1 下载MySQL的JDBC驱动jar包 进入MySQL官网 https www mysql com 然后按图操作 2 下载Oracle的JDBC驱动jar包 按图提示操作 2 1引用Oracle的JDBC驱动jar包 2 2 Oracle
  • 软件测试工程师工作有多累?怎么入门学习软件测试呢?

    软件测试随着时间的发展 越来越受欢迎了 那么 你了解过软件测试吗 软件测试工程师工作累吗 跟随千锋一起来了解一下吧 1 其实IT行业都需要经常加班的 所以软件测试和软件开发其实都一样 当然了 一般来说开发会更累一点 2 目前国内软件测试的待
  • neo4j 内存介绍

    描述Neo4j内存配置和使用的不同方面 内容翻译neo4j 操作手册 1 总览 1 1 操作系统内存 必须保留一些内存以运行操作系统本身的进程 不可能显式配置应为操作系统保留的RAM数量 因为这是在配置页面缓存和堆空间之后仍保持可用的RAM
  • 遍历子文件编码格式互换(UTF-8与GB2312)

    遍历子文件编码格式互换 UTF 8与GB2312 在日常开发中 我们经常会遇到需要将文件的编码格式从一种转换为另一种的情况 特别是在不同的操作系统和编辑器之间共享代码文件时 本篇文章将介绍一个Python脚本 用于遍历指定文件夹下的所有 c
  • 12月9号实验报告四

    完成apache服务器能够使用php解析 phtml php3 第一步 先修改配置文件httpd conf 添加 phtml php3 第二步 创建 phtml文件 php3文件 第三步 验证 phtml文件 php3文件
  • MyBatis(四) 主键生成策略

    1 数据库支持自动生成主键 若数据库支持自动生成主键的字段 比如 MySQL和 SQL Server 则可以设置useGeneratedKeys true 然后再把keyProperty 设置到目标属性上 mysql 支持自增主键 自增主键
  • Python3入门基础(10)一个对象

    Python3 面向对象 面向对象技术 与 Java 类似 类 Class 用来描述具有相同的属性和方法的对象的集合 它定义了该集合中每个对象所共有的属性和方法 对象是类的实例 方法 类中定义的函数 类变量 类变量在整个实例化的对象中是公用
  • discuz手机端默forum.php,discuz手机wap版模板开发方式简述

    近期项目需要对discuz论坛的手机模板进行开发调整 在官方论坛和搜索引擎找了很久 都没有找到相应的文章 只好自己着手开始研究 手机模板文件的所在目录 template default mobile 手机模板文件的主目录 template
  • 用Python+PIL将多个jpg图像批量合并成一个pdf文件

    一 引言 在 用Python PIL将目录下jpg图像批量转成pdf文件 介绍了将一个目录下所有的jpg文件批量转成一对一的pdf文件的方法 但单位后来又要求将所有图片合并到一个PDF中看 在实际工作中 确实有时还需要将批量图片文件合并生成
  • 用于视觉跟踪的在线特征选择研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 视觉跟踪是计算机视觉中的重要任务之一 它涉
  • QQuickWidget + QML编程实现酷炫动态动画效果

    1 具体需求 当Qt开发项目中需要实现简单的动态酷炫动画效果时 我们可以使用Qt中的QQuickWidget来实现 同时还可以使用QML编程来实现具体的动画效果 具体实现的效果如下所示 2 具体操作和实现效果图 1 按下start按钮 音乐
  • 解决win10运行Android Studio卡死问题

    问题 最近window来了一波强制更新 然后我发现在Android Studio内点运行 很容易就卡死在install处 完全不能动 只能在任务管理器上杀进程 用了很多办法都没解决 最后还是觉得是杀软的问题 处理了一下 解决办法 第一个办法
  • Python TimedRotatingFileHandler 多进程环境下的问题和解决方法

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 问题 Python 自带了一个 handler 可以实现每天自动切割日志文件的功能 其实支持各种按时间切割的方法 不过按日期切割是最常用的一种 切割 这件事的触发和执行逻辑
  • springboot在使用Scheduled做定时任务出现Autowired注入空指针

    错误示范 以往的依赖注入直接使用 Autowired Autowired BrowseRecordsService browseRecordsService ApiOperation 清除过期的浏览记录 public void remove
  • 【业务功能篇36】Springboot+activiti7 工作流引擎

    业务场景 前段时间总结的有一个告警工单流程 我们都是直接自己建表 状态节点 操作节点 都是自定义设计的 而到后面会有很多的工单流程 比如创建一个遗留问题电子流 指定处理人进行分析闭环 等等多种电子流 后期重复的开发工作以及维护工作会越来越多

随机推荐

  • C语言 递归实现汉诺塔问题 【图文讲解、简单易懂】

    汉诺塔问题是我们在学习函数递归时常遇见的一类问题 那么如何用简单易懂的思路来解决汉诺塔问题呢 下面我会为大家进行讲解 目录 汉诺塔是什么 汉诺塔的来源 用C语言实现汉诺塔 汉诺塔问题分析思路 用代码实现汉诺塔问题 总结 汉诺塔是什么 汉诺塔
  • 1 ubuntu18 docker配置与安装 镜像加速配置

    0 背景 搭建环境到创建第一个容器 1 搭建环境 需求 1 安装docker环境 2 镜像加速站 3 多台主机安装docker 1 1 docker环境 电脑为老联想电脑 cpu 2 7ghz 内存12GB 用vmware搞了两个ubunt
  • NOIP2014 Day2 模拟赛赛后总结&题解

    考试时的心态 还能有什么心态 考炸了嘛 题解 第一题 无线电通讯 水题 直接模拟 就不多说了 第二题 图论水题 其实也挺水的 只要倒着来广搜一遍 把能到达的边标记一下就可以了 接下来从起点出发BFS一遍就可以了 但是我考试的时候没有想那么多
  • 现在网红里骗子占一半。

    大家好 我是北妈 0 每天和身边朋友还有读者交流 打工没有出路 几乎成为打工人的普遍共识 也有越来越多人尝试或已经在实践打造个人 IP 超级个体品牌这条路 我的星球桃花岛 还有群也很多人每天在交流怎么做个人ip或者视频自媒体 大家都很想破圈
  • C++ STL::list常用操作及底层实现(中2)——实现list常用操作之删除(erase、remove、pop_front、pop_back、clear)

    list 常用操作及自底层实现 1 erase 按链表迭代器删除 1 1函数格式1 iterator erase iterator position 1 2函数格式2 iterator erase iterator first iterat
  • 用TensorFlow编写训练模型的程序——快速导读

    1 训练模型是怎么回事 训练模型是指 通过程序的反复迭代来修正神经网络中各个节点的值 从而实现具有一定拟合效果的算法 在训练神经网络的过程中 数据流有两个方向 正向和反向 正向负责预测生成结果 沿着网络节点的运算方向一层层计算下去 反向负责
  • 如何高速安装jetson-inference,一步到位,避免踩坑!

    踩了很长时间的坑 终于弄明白怎么高速下载jetson inference 来源 安装jetson inference 自动下载模型 满速下载起飞 解决下载模型被墙问题 奈流云何的博客 CSDN博客 需要将Github的仓库复制到Gitee上
  • 使用stm32的ADC得到准确的电压

    一 引脚多一点的stm32单片机存在VREF 和VREF 引脚 由上面的供电图知道 如果存在VREF 和VREF 引脚 那么ADC是由这两个引脚供电的 ADC的采集电压范围为 VREF
  • 理解Vue插槽

    引言 在Vue开发中 我们多采用组件化开发 组件化开发最大特点就是对页面结构化划分 组件的复用 而在实际中 页面对组件的需求或许也稍有不同 那么就需要一种需求 为页面定制组件 解决的方式便是通过插槽 实例
  • Java动态执行计算表达式利器 -- ScriptEngine

    在通过配置文件对系统进行参数配置时 有时需要更好的理解参数值的具体意义 往往采用计算表达式的方式设置 例如1天换成秒数为86400 如果写成24 60 60就很清晰的表达是一天的秒数 但是这个表达式通过properties的方式获取为字符串
  • Celery ValueError: not enough values to unpack (expected 3, got 0)

    目录 1 Celery ValueError not enough values to unpack expected 3 got 0 2 AttributeError async 1 Celery ValueError not enoug
  • 使用CUDA实现零拷贝技术

    使用CUDA实现零拷贝技术 零拷贝技术是指在内存和设备之间传输数据时 不需要显式地将数据从内存复制到设备的过程 从而提高数据传输效率 本文将介绍如何使用CUDA实现零拷贝技术 并提供示例代码 在使用CUDA进行图像处理时 通常需要将数据从主
  • 【计算机视觉

    文章目录 一 SqueezeNet 二 Inception v3 三 Visual Geometry Group 19 Layer CNN 四 MobileNetV1 五 Data efficient Image Transformer 六
  • 【CentOS7】开机自启动三种方法

    有个需求 比如说我想要执行开机杀毒程序 就需要去做开机自启动相关操作 准备工作 在 usr local目录下建立killviruses sh 前提 安装病毒库 vi killviruses sh 键入以下内容 前提 已安装ClamAV cl
  • js纯ajax,纯js 的Ajax 请求

    纯js 的Ajax 请求 2018 02 24 126 var XMLHttpReq function createXMLHttpRequest try XMLHttpReq new ActiveXObject Msxml2 XMLHTTP
  • 深度学习优化算法大全系列3:NAG(Nesterov Acceleration Gradient)

    1 NAG与SGD M的区别 NAG全称为Nesterov Accelerated Gradient 是在SGD Momentum基础进一步优化所得 前面的文章我们提到过 SGD M主要是利用历史累积动量来代替当前梯度从而达到减小震荡 加速
  • python自定义assert抛出的异常

    方法一 常用于assert失败后的提示用语 assert 1 gt 4 what 异常为 AssertionError what 方法二 常用于assert失败后推断导致的报错 try assert 1 gt 4 except Except
  • 前端实现导出Excel

    一 准备文件 1 创建excel文件夹 excel Blob js Export2Excel js 2 Blob js文件夹内容 eslint disable Blob js global self unescape jslint bitw
  • python pygame 游戏实战:Maze 迷宫生成,显示和游戏(附全部代码)

    生成迷宫 maze 的算法有很多种 论坛上有很多这方面的资料可以参考 这里使用回溯法 backtracking 主要参考Build a 2 player maze game with Python Part 4 Coding TidBits
  • 深入理解nandflash之基本特性

    nandflash作为嵌入式中的 磁盘 被广泛的应用 以 K9F2G08U0B 为例 其他型号都差不多 nandflash的结构 nandflash的结构有页 page block 块 的概念 其中页是真实概念 而块儿是虚拟概念 目的是为了