裸机——Nand
Posted yangxinrui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了裸机——Nand相关的知识,希望对你有一定的参考价值。
1.首先需要知道Nand的基础知识
从Nand的芯片手册可以获得
我使用的芯片手册是 K9F2G08
首先从芯片手册的名称可以获得信息:
K9F:三星
2G : 2Gb (256MB)
08 : 8位数据线
下面列出芯片手册中对编程有用的部分
上面这张图就是Nand存储颗粒的排列方式,
对Nand存储单元的管理方式如下:
Nand的存储单元和DDR一样按照字节编址,但是读写和擦除的最小单位不同。
Page是最小的读写单位
Block是最小的擦除单位
Page Register 之后的 64 Bytes 为带外数据区,用于 ECC 校验 和 坏块管理。
ECC 校验:由于Nand的物理性质导致可能发生位反转,即存的是1,却自动翻转成0,所以为了防止位反转的危害,数据写入时,会计算出ECC校验,存入带外区,将来读数据时,需要再次计算ECC校验,并对比带外区中的校验。
坏块管理:Nand的块可能坏掉,对于坏块的处理是标记为坏块,不再使用,标记坏块就需要确定坏块,确定的方法是:擦除块(Nand擦除后,所以数据成1),然后读出,比较数据是否每一位都为1,如果不是就标记为坏块。(这通常由文件系统处理)。
上面这张图进行对Nand传地址,
首先由于我这个芯片只有8根数据线(注意Nand的数据线负责传输:数据、地址、命令),所以地址信息分为5个周期传输,
前两个周期为 Col ,后3个为Row,
注意,由于Nand读写擦除都是以Page对齐的,所以Col其实都为0。
这张图是命令,也是编程。
这时需要了解 SoC和Nand之间是怎么通信的。
如下
CPU通过控制 SFR 控制 Nand控制器, Nand控制器按照时序与Nand芯片上的主控IC进行通信,
Nand芯片上的主控IC根据Nand控制器传来的命令等数据直接操作存储单元。
为什么CPU不直接操作Nand上的控制电路呢?
理论上是可以的,单片机上就是这么做的,但是太复杂,比如CPU需要完成这样的时序操作。
CLE、CE。。。这些是什么呢?
查看原理图可以晓得
原理图告诉我们,数据线有 I/O0-7一共8根,其他几乎都是时序线(有上滑线的表示低电压有效)。
所以结合上面的时序图,我们晓得了,时序控制就是按照时序拉高拉低这些时序线,显然这是否困难。
所以Nand控制器出现,Nand控制器的工作就是完成这些时序控制,SoC就只需要控制Nand控制器的SFR。
既然Nand控制器这么厉害,那他的逻辑结构是什么样的呢?
由于Nand控制器是SoC上的,所以在SoC的数据手册可以找到。
可以控制器工作在 HCLK,并且带有硬件实现的 ECC 模块,我们通过控制SFR,使用 ECC 和 Control & State Machine。
下面就是使用Nand控制器后,与Nand主控IC进行通信的流程
如何实现这些流程呢?按照前面的分析就是设置Nand控制器的SFR
// 从sdram中写数据到nand int copy_sdram_to_nand(unsigned char *sdram_addr, unsigned long nand_addr, unsigned long length) { unsigned long i = 0; // 1. 发出片选信号 nand_select_chip(); // 2. 从sdram读数据到nand,第一周期发命令0x80,第二周期发地址nand_addr,第三个周期写一页(2k)数据,第四周期发0x10 while(length) { nand_send_cmd(NAND_CMD_WRITE_PAGE_1st); nand_send_addr(nand_addr); // 列地址,即页内地址 unsigned long col = nand_addr % NAND_PAGE_SIZE; i = col; // 写一页数据,每次拷1byte,共拷2048次(2k),直到长度为length的数据拷贝完毕 for(; i<NAND_PAGE_SIZE && length!=0; i++,length--) { nand_write8(*sdram_addr); sdram_addr++; nand_addr++; } rNFSTAT = (rNFSTAT)|(1<<4); nand_send_cmd(NAND_CMD_WRITE_PAGE_2st); nand_wait_idle(); } // 3. 读状态 unsigned char status = nand_read_status(); if (status & 1 ) { // 取消片选信号 nand_deselect_chip(); printf("copy sdram to nand fail "); return -1; } else { nand_deselect_chip(); return 0; } }
这样就知道了Nand的编程和相关的基础知识。
接下来要做的就是结合芯片手册的工作流程和SoC手册的寄存器解释理解源码。
当然还需要结合Nand的基础知识理解源码的有些操作,
如:
每次发送数据后,都需要短暂的等待,以保证Nand主控IC完成操作。
对于Nand进行读写操作的地址应该Page对齐,擦除操作的地址应该Block对齐。
Nand操作前后需要先选片,后释放。
每次长时间的操作,如写Nand后,需要轮询的读状态寄存器,确定Nand主控IC已经完成写操作。
对于写操作,写之前需要擦除。
以上是关于裸机——Nand的主要内容,如果未能解决你的问题,请参考以下文章