一. Nandflash

1.1 定义

Nand-flash存储器是flash存储器的一种,其内部采用非线性宏单元模式,为固态大容量内存的实现提供了廉价有效的解决方案。Nand-flash存储器具有容量较大,改写速度快等优点,适用于大量数据的存储,因而在业界得到了越来越广泛的应用,如嵌入式产品中包括数码相机、MP3随身听记忆卡、体积小巧的U盘等。

1.2 Nand的型号与命名

(1)Nand的型号命名都有含义,就拿K9F2G08来示例分析一下:K9F表示是三星公司的NandFlash系列。2G表示Nand的大小是2Gbit(256MB)。08表示Nand是8位的(8位就是数据线有8根)
(2)Nand命名中可以看出:厂家、系列型号、容量大小、数据位数等。
(3)Nand有8位数据位的,有16位数据位的。做电路时/写软件时应该根据自己实际采购的Nnad的位数来设计电路/写软件。
(4)说明Nand是并行接口的(8/16位)
(5)Nand的数据线上传递的不一定全部是有效数据,也可能有命令、地址等。

更多详情可参考:http://www.360doc.com/content/15/0209/16/6828497_447485125.shtml

1.3 Nand的功能框图



(我们通过从小到大的方式来认识Nand的结构)
(1)Nand的结构可以看成是一个矩阵式存储器,其中被分成一个一个的小块,每一小块可以存储一个bit位,然后彼此以一定单位组合成整个Nand。
(2)Nand中可以被单次访问的最小单元(就是说对Nand进行一次读写至少要读写这么多,或者是这么多的整数倍)叫做Page(页),在K9F2G08芯片中,Page的大小是2KB+64B。也就是说我们要读写K9F2G08,每次至少要读写2KB或者n*2KB,即使我们只是想要其中的一个字节。这就是我们说的典型的块设备(现在有些块设备为了方便,提供了一种random read模式,可以只读取1个字节)。
(3)页往上还有个Block(块)的概念,1个块等于若干个页(譬如在K9F2G08中1个块等于64页)。
(4)页往上就是整个Nand芯片了,叫做Device。一个Device是若干个Block,譬如K9F2F08一个Device有2028个block。所以整个Device大小为:2048×64×2K = 256MB

(5)块设备分page、block有什么意义?

  1. 块设备不能完全按字节访问而必须块访问是物理上的限制,而不是人为设置的障碍。
  2. Page和Block各有各的意义,譬如Nand中:Page是读写Nand的最小单位;Block是擦除Nand的最小单位。(这些规则都是Nand的物理原理和限制要求的,不是谁想要这样的,所以对于我们做软件的来说,只能去想办法适应硬件,不是想着超越硬件)。
  3. Nand的页和以前讲过的块设备(尤其是硬盘)的扇区是类似的。扇区最早在磁盘中是512字节,后来也有些高级硬盘扇区不是512字节而是1024字节/2048字节/4096字节等。Nand也是一样,不同的Nand的页的大小是不同的,也有512字节/1024字节/2048字节/4096字节等。
  4. 一个block等于多少page也是不定的,不同的Nand也不同。一个Nand芯片有多少block也是不定的,不同的Nand芯片也不同。

(6)Nand芯片中主要包含2部分:Nand存储颗粒+Nand接口电路。存储颗粒就是纯粹的Nand原理的存储单元,类似于仓库;Nand接口电路是用来管理存储颗粒,并且给外界提供一个统一的Nand接口规格的访问接口的。
(7)Nand中有多个存储单元,每个单元都有自己的地址(地址是精确到字节的)。所以Nand是地址编排精确到字节,但是实际读写却只能精确到页(所以Nand的很多操作都要求给的地址是页对齐的,譬如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芯片的。

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

(1)Nand的每个页由2部分组成,这2部分各自都有一定的存储空间。
譬如K9F2G08(Figure2)中为2K+64字节。其中的2K字节属于带内数据,是我们真正的存储空间,将来存储在Nand中的有效数据就是存在这2K范围内的(我们平时计算nand的容量时也是只考虑这2KB);64字节的带外数据不能用来存储有效数据,是作为别的附加用途的(譬如用来存储ECC数据、用来存储坏块标志等····)
(2)什么是ECC:(error correction code,错误校验码)。因为nand存储本身出错(位反转)概率高(Nand较Nor最大的缺点就是稳定性),所以当我们将有效信息存储到Nand中时都会同时按照一定算法计算一个ECC信息(譬如CRC16等校验算法),将ECC信息同时存储到Nand这个页的带外数据区。然后等将来读取数据时,对数据用同样的算法再计算一次ECC,并且和从带外数据区读出的ECC进行校验。如果校验通过则证明Nand的有效数据可信,如果校验不通过则证明这个数据已经被损坏(只能丢弃或者尝试修复)。
(3)坏块标志:Nand芯片用一段时间后,可能某些块会坏掉(这些块无法擦除了,或者无法读写了),nand的坏块非常类似于硬盘的坏道。坏块是不可避免的,而且随着Nand的使用坏块会越来越多。当坏块还不算太多时这个Nand都是可以用的,除非坏块太多了不划算使用了才会换新的。所以我们为了管理Nand发明了一种坏块标志机制。Nand的每个页的64字节的带外数据中,我们(一般是文件系统)定义一个固定位置(譬如定位第24字节)来标记这个块是好的还是坏的。文件系统在发现这个块已经坏了没法用了时会将这个块标记为坏块,以后访问nand时直接跳过这个块即可。

1.5 Nand的地址时序


(1)nand的地址有多位,分4或5期通过IO引脚发送给Nand芯片来对Nand进行寻址。寻址的最小单位是字节,但是读写的最小单位是页。
(2)nand的地址在写代码时要按照Nand要求的时序和顺序去依次写入。

1.6 Nand的命令码

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

1.7 NandFlash的常见操作及流程分析

1.7.1 坏块检查

(1)Flash使用之前要先统一擦除(擦除的单位是块)。Flash类设备擦除后里面全是1,所以擦干净之后读出来的值是0xff。
(2)检查坏块的思路就是:先块擦除,然后将整块读出来,依次检测各自节是否为0xff,如果是则表明不是坏块,如果不是则表明是坏块,如上图所示,如果不是就会建立一个坏块表或者更新最初的坏块表。

1.7.2 页写(program)操作

(1)写之前确保这个页是被擦除干净的。如果不是擦除干净的(而是脏的、用过的)页,写进去的值就是错的,不是你想要的结果。
(2)写操作(write)在flash的操作中就叫编程(program)
(3)SoC写Flash时通过命令线、IO线依次发送写命令、写页地址、写数据等进入NandFlash。
(4)写的过程:SOC通过Nand控制器和Nand芯片完成顺序对接,然后按照时序要求将一页数据发给Nand芯片内部的接口电路。接口电路先接收收据到自己的缓冲区,然后再集中写入Nand芯片的存储区域中。Nand接口电路将一页数据从缓冲区中写入Nand存储系统中需要一定的时间,这段时间Nand芯片不能再响应SOC发过来的其他命令,所以SoC要等待Nnad接口电路忙完。等待方法是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值进行校验。校验通过则说明读写正确,校验不通过则说明不正确(放弃数据或者尝试修复)。

1.7.3 擦除(erase)操作/页读(read)操作


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

1.8 S5PV210的NandFlash控制器

1.8.1 SoC的Nand控制器的作用

(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编码),现在大部分的application级别的SoC都有集成的内部编码器(像S5PV210就有、更复杂的譬如4418、6818就更不用说了,只会更多更先进),我们可以利用这些硬件编码器来进行快速编解码,这样软件工作量和难度降低了很多(这就是所谓的硬件加速)。

1.8.2 结构框图分析


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

1.8.3 S5PV210的Nand控制器的主要寄存器

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

1.8.4 Nand操作代码解析

(1)擦除函数
结合擦除的流程框图

// 擦除块,参数为块号(0 ~ MAX_NAND_BLOCK-1)
int nand_block_erase(unsigned long block_num)
{unsigned long i = 0;// 获得row地址,即页地址  unsigned long row = block_num * NAND_BLOCK_SIZE;// 1. 发出片选信号 ,通过对寄存器NFCONT 的bit1 进行配置。nand_select_chip();// 2. 擦除:第一个周期发命令0x60,第二个周期发块地址,第三个周期发命令0xd0  nand_send_cmd(NAND_CMD_BLOCK_ERASE_1st);  for(i=0; i<10; i++);// Row Address A12~A19    rNFADDR = row & 0xff;             //查询NFADDR的寄存器介绍可知,bit0~7 是存放地址value的,         for(i=0; i<10; i++);               //并且根据时序,row地址需要三个循环来寻址,所以我们从低位到// Row Address A20~A27             //到高位依次取出rNFADDR = (row >> 8) & 0xff;for(i=0; i<10; i++);// Row Address A28~A30  rNFADDR = (row >> 16) & 0xff;   rNFSTAT |= (1<<4);                  // clear RnB bit ,用来侦测是否已经擦除完毕,我们这一步先清nand_send_cmd(NAND_CMD_BLOCK_ERASE_2st);for(i=0; i<10; i++);// 3. 等待就绪  nand_wait_idle();                 //通过rNFSTAT的bit4 用来侦测是否已经擦除完毕// 4. 读状态  unsigned char status = nand_read_status();   //通过read status (70h)command,可以获取NFDATA 寄存器中的状态,我们也可以读取NFSTAT寄存器if (status & 1 )                             {// statas[0] = 1,表示擦除失败,详见NAND Flash数据手册中 READ STATUS一节的描述// 取消片选信号  nand_deselect_chip();                     printf("masking bad block %d\r\n", block_num);return -1;}else{// status[0] = 0,表示擦除成功,返回0nand_deselect_chip();return 0;}
}

(2)页读取函数
框图见1.7.3

int nand_page_read(unsigned int pgaddr, unsigned char *buf, unsigned int length)
{int i = 0;// 1 发出片选信号  nand_select_chip();// 2 写页读命令1st  nand_send_cmd(NAND_CMD_READ_1st);// 3 写入页地址rNFADDR = 0;                                     rNFADDR = 0;rNFADDR = pgaddr&0xff;rNFADDR = (pgaddr>>8)&0xff;rNFADDR = (pgaddr>>16)&0xff;// 4 clear RnBrNFSTAT |= (1<<4);// 5  写页读命令2st nand_send_cmd(NAND_CMD_READ_2st);// 6 等待空闲nand_wait_idle();// 7 连续读取2KB的Page main区数据 (继续读取可读出64B的spare area数据)for (i=0; (i<NAND_PAGE_SIZE) && (length!=0); i++,length--)*buf++ = nand_read8();// 8 读状态  unsigned char status = nand_read_status();if (status & 1 ){// 读出错,取消片选信号,返回错误码-1  nand_deselect_chip();printf("nand random read fail\r\n");return -1;}else{// 读正确,取消片选,返回0nand_deselect_chip();return 0;}
}

(3)页写入函数

int nand_page_write(unsigned int pgaddr, const unsigned char *buf, unsigned int length)
{int i = 0;// 1 发出片选信号  nand_select_chip();// 2 write cmd 1st  nand_send_cmd(NAND_CMD_WRITE_PAGE_1st);// 3 write page addrrNFADDR = 0;rNFADDR = 0;rNFADDR = pgaddr&0xff;rNFADDR = (pgaddr>>8)&0xff;rNFADDR = (pgaddr>>16)&0xff;// 4 写入一页内容for(; i<NAND_PAGE_SIZE && length!=0; i++,length--)nand_write8(*buf++);// 5 clear RnBrNFSTAT = (rNFSTAT)|(1<<4);// 6 write cmd 2nand_send_cmd(NAND_CMD_WRITE_PAGE_2st);// 7 wait idlenand_wait_idle();// 8 读状态  unsigned char status = nand_read_status();if (status & 1 ){// 取消片选信号  nand_deselect_chip();printf("nand random write fail\r\n");return -1;}else{nand_deselect_chip();return 0;}}

1.8.5 总结

(1)像NandFlash这类芯片,通过专用的接口时序和SoC内部的控制器相连(这种连接方式是非常普遍的,像LCD、DDR等都是类似的连接)。这种接法和设计对我们编程来说,关键在于

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

二. iNand介绍

2.1 iNand/eMMC/SDCard/MMCCard的关联

(1)最早出现的是MMC卡,卡片式结构,按照MMC协议设计。(相较于NandFlash芯片来说,MMC卡有2个优势:第一是卡片化,便于拆装;第二是统一了协议接口,兼容性好。)
(2)后来出现SD卡,兼容MMC协议。SD卡较MMC有一些改进,譬如写保护、速率、容量等。
(3)SD卡遵守SD协议,有多个版本。多个版本之间向前兼容。
(4)iNand/eMMC在SD卡的基础上发展起来,较SD卡的区别就是将SD卡芯片化了(解决卡的接触不良问题,便于设备迷你化)。
(5)iNand和eMMC的关联:eMMC是协议,iNand是Sandisk公司符合eMMC协议的一种芯片系列名称。

2.2 iNand/eMMC的结构框图及其与NandFlash的区别

(1)iNand内部也是由存储系统和接口电路构成(和Nand结构特性类似,不同之处在于接口电路功能不同)。
(2)iNand的接口电路挺复杂,功能很健全。譬如:
第一,提供eMMC接口协议,和SoC的eMMC接口控制器通信对接。
第二,提供块的ECC校验相关的逻辑,也就是说iNand本身自己完成存储系统的ECC功能,SoC使用iNand时自己不用写代码来进行ECC相关操作,大大简化了SoC的编程难度。(NandFlash分2种:SLC和MLC,SLC更稳定,但是容量小价格高;MLC容易出错,但是容量大价格低)
第三,iNand芯片内部使用MLC Nand颗粒,所以性价比很高。
第四,iNand接口电路还提供了cache机制,所以inand的操作速度很快。

2.3 iNand/eMMC的物理接口和SD卡物理接口的对比

(1)S5PV210芯片本身支持4通道的SD/MMC,在X210中实际是在SD/MMC0通道接了iNand芯片,而SD/MMC2接了SD卡(SD/MMC3也接了SD卡)。
(2)对比inand和SD卡接线,发现:这两个接线几乎是一样的,唯一的区别就是SD卡IO线有4根,而iNand的IO线有8根。


(3)这个告诉我们,我们在实际操作iNand芯片时和操作SD卡时几乎是一样的(物理接线几乎一样,软件操作协议几乎一样)。

结论
iNand/eMMC其实就是芯片化的SD/MMC卡,软件操作和SD卡相同。
分析iNand芯片的操作代码时,其实就是以前的SD卡的操作代码。一些细节的区别就是为了区分各种不同版本的SD卡、iNand的细节差异。

2.4 SD卡/iNand操作

2.4.1 硬件接口:DATA、CLK、CMD

(1)iNand的IO线有8根,支持1、4、8线并行传输模式;SD卡IO线有4根,支持1、4线并行传输模式。
(2)CMD线用来传输命令、CLK线用来传输时钟信号。
(3)接口有CLK线,工作时主机SoC通过CLK线传输时钟信号给SD卡/iNand芯片,说明:SD/iNand是同步的,SD/iNand的工作速率是由主机给它的CLK频率决定的。

2.4.2 命令响应的操作模式

(1)SD协议事先定义了很多标准命令(CMD0、CMD1·····),每个命令都有它的作用和使用条件和对应的响应。SD卡工作的时候就是一个一个的命令周期组合起来的,在一个命令周期中,主机先发送CMD给SD卡,然后SD卡解析这个命令并且执行这个命令,然后SD卡根据结果回发给主机SoC一个响应。(有些命令是不需要响应的,这时SD卡不会给主机回发响应,主机也不用等待响应)。标准的命令+响应的周期中,主机发完一个命令后应该等待SD卡的响应而不是接着发下一条命令。

2.4.3 SD/iNand的体系结构图

SD卡内部有一个接口控制器,这个控制器类似于一个单片机,这个单片机的程序功能就是通过CMD线接收外部主机SoC发给SD卡的命令码,然后执行这个命令并且回发响应给主机SoC。这个单片机处理命令及回发响应遵循的就是SD协议。这个单片机同时可以控制SD卡内部的存储单元,可以读写存储单元。

2.4.4 SD/iNand的寄存器(重点是RCA寄存器)

(1)注意这里说的是SD卡内部的寄存器,而不是主机SoC的SD控制器的寄存器。(很多外置芯片内部都是有寄存器的,这些寄存器可以按照一定的规则访问,访问这些寄存器可以得知芯片的一些信息)。
(2)RCA(relative address,相对地址寄存器)。我们在访问SD卡时,实际上SD卡内部每个存储单元的地址没有绝对数字,都是使用相对地址。相对地址由SD卡自己决定的,存放在RCA寄存器中。
(3)OCR ,操作情况寄存器,强制。
(4)CID ,卡的 ID;用于识别卡的 ID ,强制.
(5)DSR,驱动器级寄存器;配置卡的输出驱动器。可选
(6)CSD,卡的专用数据;关于卡的操作情况信息。强制
(7)SCR,SD 配置寄存器;关于 SD 存储卡的专用特性信息。强制

注意:不同的SoC可能在SD/MMC/iNand等支持方面有差异,但是如果支持都是通过内部提供SD控制器来支持的,S5PV210的SD卡控制器在Section8.7部分。

2.5 SD/iNand 实战知识点

2.5.1.1 命令码CMD和ACMD

(1)SD卡工作在命令+响应的模式下。
(2)SD协议的命令分2种:CMDx和ACMDx。CMD是单命令命令,就是单独发一个CMD即可表示一个意思。ACMD是一种扩展,就是发2个CMD加起来表示一个意思。可以认为ACMDx = CMDy+CMDz(y一般是55)。

2.5.1.2 卡类型识别SD or MMC?

1)MMC协议、SD协议、eMMC协议本身是一脉相承的,所以造成了一定的兼容性,所以当我们SoC控制器工作时连接到SoC上的可能是一个MMC卡、也可能是SD卡、也可能是iNand芯片。主机SoC需要去识别这个卡到底是什么版本的卡。

2)SoC如何区分卡种类?因为不同版本的卡内部协议不同的,所以对卡识别命令的响应也是不同的。SoC通过发送一些命令、听取响应就可以根据不同的响应判定卡的版本。

2.5.1.3 卡状态

(1)SD卡内部的接口控制器类似于一个单片机,这个单片机其实是一个状态机。所以SD卡任何时候都属于某一种状态(空闲状态、准备好状态、读写状态、出错状态····都是事先定义好的),在这种状态下能够接受的命令是一定的,接受到命令之后执行一定的操作然后根据操作结果会跳转为其他状态。如果主机发过来的命令和当前状态不符状态机就不响应,如果收到命令和当前状态相符就会执行相应操作,执行完之后根据结果跳转为其他状态。

2.5.1.4 卡回复类型

(1)一般来说,SD卡的命令都属于:命令+响应的模式。也有极少数的SD卡命令是不需要回复的。
(2)卡回复有R1、R7、R1B等8种类型,每种卡回复类型都有自己的解析规则。然后卡在特定状态下响应特定命令时有可能回复哪种响应都是SD协议事先规定好的,详细细节要查阅协议文档。

  • 代码分析

注: 以上内容来自朱老师物联网大讲堂裸机课件

嵌入式裸机NandFlash和 SD/iNand学习笔记相关推荐

  1. 朱有鹏老师linux核心大讲堂---ARM裸机第十一部分 NandFlash和iNand学习笔记

    目录 1.NandFlash的接口  数据手册:K9F2G08/K9F4G08 2.NandFlash结构框图 3.Nandflash的结构 4.NandFlash常见操作以及流程分析 5.S5PV2 ...

  2. 嵌入式linux-arm(gec6818开发板)回忆学习笔记

    19-20Y 嵌入式系统及应用课程 嵌入式的一花一木 三源码项 一.课程学习结果 安装VMware虚拟机,配置Ubuntu系统镜像(安装VMware-Tools工具,文件可直接拉入虚拟机,反之也可.还 ...

  3. 嵌入式系统开发:基于Linux学习笔记整理(学期汇总)

    Linux命令操作部分 Ubuntu虚拟机使用 快照 拍摄快照是为了方便还原虚拟机,因为虚拟机(Virtual Machine)是虚拟出来的出来的一台物理计算机,如果你在实验中操作不当或者其他原因导致 ...

  4. STM32学习笔记(四)丨TIM定时器及其应用(定时中断、内外时钟源选择)

    本篇文章包含的内容 一.TIM 定时器 1.1 TIM 定时器简介 1.2 TIM 定时器类型及其工作原理简介 1.2.1 基本定时器工作原理及其结构 1.2.2 通用定时器工作原理及其结构 1.2. ...

  5. STM32学习笔记(八)丨ADC模数转换器(ADC单、双通道转换)

    本篇文章包含的内容 一.ADC 模数转换器 1.1 ADC简介 1.2 逐次逼近型ADC工作原理 1.3 STM32中的ADC基本结构 1.4 STM32中ADC的输入通道 1.5 STM32中的AD ...

  6. STM32学习笔记(三)丨中断系统丨EXTI外部中断(对射式红外传感器计次、旋转编码器计次)

    本篇文章包含的内容 一.中断系统 1.1 中断的定义 1.2 中断优先级 1.3 中断的嵌套 1.4 STM32中的中断系统 1.4.1 STM32的中断资源 1.4.2 嵌套中断向量控制器 NVIC ...

  7. 电路设计学习笔记(一)丨运算放大器

    本篇文章包含的内容 一.集成运算放大器供电 1.1 单/双电源供电 1.1.1 集成运放的供电准则 1.1.2 双电源供电 1.1.3 单电源供电 1.2 运放供电电路PCB设计 1.2.1 去耦电容 ...

  8. 嵌入式知识-ARM裸机-学习笔记(9):SD卡启动详解(S5PV210)

    嵌入式知识-ARM裸机-学习笔记(9):SD卡启动详解(S5PV210) 一.SD卡介绍 1. SD卡背景知识和特点 SD卡.MMC卡.MicroSD.TF卡:这些卡其实内部就是Flash存储颗粒,比 ...

  9. 嵌入式知识-ARM裸机-学习笔记(2):利用GPIO来控制LED(附mkv210_image.c文件解析)

    嵌入式知识-ARM裸机-学习笔记(2):利用GPIO来控制LED(附mkv210_image.c文件解析) 首先声明该博客是针对朱有鹏老师的嵌入式课程进行笔记的总结. 一.通过GPIO控制点亮LED( ...

最新文章

  1. php lock sh,php文件加锁 lock_sh ,lock_ex
  2. 缓存-分布式锁-缓存一致性解决
  3. 虚拟机ubuntu安装ssh服务器,经过Xshell远程链接虚拟机VMVARE中的Ubuntu
  4. mac安装mysql记录,使用zsh
  5. memcached 使用 java_使用Java java_memcached client的陷阱
  6. offsetLeft,Left,clientLeft的区别
  7. 低微漏洞处理办法记录
  8. apktool(android app逆向)
  9. 火山PC_POST教程
  10. java需要知道哪些英语单词_70个学习JAVA必背的英语单词,了解下
  11. 服务器安装Ubuntu Server 18.04及磁盘分区
  12. 平方根python_python如何求平方根
  13. Android图形绘制之——简单的几何图形
  14. 为什么我坚定看好分布式存储
  15. 拯救智慧城市:要智商还有生气
  16. 自学编程的30岁男人,能按应届生那样找工作吗?
  17. 寒江独钓——Windows内核安全编程
  18. 有效的沟通,如忍者的最后一击!
  19. 服务器bcd配置损坏怎么修复,引导记录损坏修复方法详解
  20. format在java_java Format什么意思

热门文章

  1. GPS信号接收机的频偏和相位锁定matlab仿真
  2. 如何消除下一代Wi-Fi 6E设备的延迟
  3. android 波斯语,android – 如何在视图中显示波斯语(波斯语)数字
  4. c语言修炼内功,助你升级打怪!!
  5. windows 记得pin码 忘记登录密码
  6. 百度云主机BCC挂载云盘CDS
  7. Neo4j图数据库,用py2neo中的OGM操作(类似ORM)
  8. 2017,人们视算法为「洪水猛兽」;算法说:我不想背锅
  9. 转换cdm为mysql_【PowerDesigner】PowerDesigner之CDM、PDM、SQL之间转换
  10. MATLAB文件夹页面被隐藏后如何恢复