| 一、结构分析 S3C2410处理器集成了8位Nand Flash控制器。目前市场上常见的8位NandFlash有三星公司的k9f1208、k9f1g08、k9f2g08等。k9f1208、k9f1g08、k9f2g08的数据页大小分别为512Byte、2kByte、2kByte。它们在寻址方式上有一定差异,所以程序代码并不通用。本文以S3C2410处理器和k9f1208系统为例,讲述NandFlash的读写方法。 NandFlash的数据是以bit 的方式保存在memory cell里的,一般来说,一个cell 中只能存储一个bit,这些cell 以8 个或者16 个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND Device 的位宽。这些Line 组成Page, page 再组织形成一个Block。k9f1208的相关数据如下: 1block=32page;1page=528byte=512byte(Main Area)+16byte(Spare Area)。 总容量为=4096(block数量)*32(page/block)*512(byte/page)=64Mbyte NandFlash以页为单位读写数据,而以块为单位擦除数据。按照k9f1208的组织方式可以分四类地址: Column Address、halfpage pointer、Page Address 、Block Address。A[0:25]表示数据在64M空间中的地址。 Column Address表示数据在半页中的地址,大小范围0~255,用A[0:7]表示; halfpage pointer表示半页在整页中的位置,即在0~255空间还是在256~511空间,用A[8]表示; Page Address表示页在块中的地址,大小范围0~31,用A[13:9]表示; Block Address表示块在flash中的位置,大小范围0~4095,A[25:14] 表示; 二、读操作过程 K9f1208的寻址分为4个cycle。分别是:A[0:7]、A[9:16]、A[17:24]、A[25]。 读操作的过程为: 1、发送读取指令;2、发送第1个cycle地址;3、发送第2个cycle地址;4、发送第3个cycle地址;5、发送第4个cycle地址;6、读取数据至页末。 K9f1208提供了两个读指令,‘0x00’、‘0x01’。这两个指令区别在于‘0x00’可以将A[8]置为0,选中上半页;而‘0x01’可以将A[8]置为1,选中下半页。 虽然读写过程可以不从页边界开始,但在正式场合下还是建议从页边界开始读写至页结束。下面通过分析读取页的代码,阐述读过程。 static void ReadPage(U32 addr, U8 *buf) //addr表示flash中的第几页,即‘flash地址>>9’ { U16 i; NFChipEn(); //使能NandFlash WrNFCmd(READCMD0); //发送读指令‘0x00’,由于是整页读取,所以选用指令‘0x00’ WrNFAddr(0); //写地址的第1个cycle,即Column Address,由于是整页读取所以取0 WrNFAddr(addr); //写地址的第2个cycle,即A[9:16] WrNFAddr(addr>>8); //写地址的第3个cycle,即A[17:24] WrNFAddr(addr>>16); //写地址的第4个cycle,即A[25]。 WaitNFBusy(); //等待系统不忙 for(i=0; i<512; i++) buf[i] = RdNFDat(); //循环读出1页数据 NFChipDs(); //释放NandFlash } 三、写操作过程 写操作的过程为: 1、发送写开始指令;2、发送第1个cycle地址;3、发送第2个cycle地址;4、发送第3个cycle地址;5、发送第4个cycle地址;6、写入数据至页末;7、发送写结束指令 下面通过分析写入页的代码,阐述读写过程。 static void WritePage(U32 addr, U8 *buf) //addr表示flash中的第几页,即‘flash地址>>9’ { U32 i; NFChipEn(); //使能NandFlash WrNFCmd(PROGCMD0); //发送写开始指令’0x80’ WrNFAddr(0); //写地址的第1个cycle WrNFAddr(addr); //写地址的第2个cycle WrNFAddr(addr>>8); //写地址的第3个cycle WrNFAddr(addr>>16); 写地址的第4个cycle WaitNFBusy(); //等待系统不忙 for(i=0; i<512; i++) WrNFDat(buf[i]); //循环写入1页数据 WrNFCmd(PROGCMD1); //发送写结束指令’0x10’ NFChipDs(); //释放NandFlash } 四、总结 本文以S3C2410处理器和k9f1208系统为例讲述了nand flash的读写过程。在读写过程中没有考虑到坏块问题,有关ecc及坏块处理问题将在下个专题中讲述。 我的板子上使用的是SAMSUNG的K9F1208U0B,下面我将对此型号的NandFlash读取操作做一个讲解。 首先我们先从物理结构上来了解这颗芯片,结构图如下所示 正如硬盘的盘片被分为磁道,每个磁道又被分为若干扇区,一块Nand Flash被分为若干Block,每个Block又被分为若干Page。 由上图我们可以知道flash中Byte(字节),Page(页),Block(块)3个单位之间的关系为 1 Page =512 Bytes Data Field+ 16 Bytes Spare Field 1 Blcok="32" Pages 我们讨论的K9F1208U0B总共有4096 个Blocks,故我们可以知道这块flash的容量为4096 *(32 *528)= 69206016 Bytes = 66 MB 但事实上每个Page上的最后16Bytes是用于存贮检验码用的,并不能存放实际的数据,所以实际上我们可以操作的芯片容量为 4096 *(32 *512) = 67108864 Bytes = 64 MB 由上图所示,1个Page总共由528 Bytes组成,这528个字节按顺序由上而下以列为单位进行排列(1列代表一个Byte。第0行为第0 Byte ,第1行为第1 Byte,以此类推,每个行又由8个位组成,每个位表示1个Byte里面的1bit)。这528Bytes按功能分为两大部分,分别是Data Field和Spare Field,其中Spare Field占528Bytes里的16Bytes,这16Bytes是用于在读写操作的时候存放校验码用的,一般不用做普通数据的存储区,除去这16Bytes,剩下的512Bytes便是我们用于存放数据用的Data Field,所以一个Page上虽然有528个Bytes,但我们只按512Bytes进行容量的计算。 Data Field按位置关系又可分为两个部分,分别称为1st half与2nd half,每个half各占256个bytes。或许你会感到纳闷,为什么要把DataField分为两个部分?把他们看做一个整体进行操作不就好了吗?呵呵,凡事都有因果关系,这么分块自然有它的道理所在,但现在还不是告诉你答案的时候。我们还是先讨论一下它的操作吧。 对K9F1208U0B的操作是通过向Nand Flash命令寄存器(对于s3c2410来说此寄存器为NFCMD,内存映射地址为0x4e000004)发送命令队列进行的,为什么说是命令队列?就是因为要完成某个操作的时候发送的不是一条命令,而是连续几条命令或是一条命令加几个参数 下面是K9F1208U0B的操作命令集: 读命令有两个,分别是 Read1,Read2其中Read1用于读取Data Field的数据,而Read2则是用于读取Spare Field的数据。对于Nand Flash来说,读操作的最小操作单位为Page,也就是说当我们给定了读取的起始位置后,读操作将从该位置开始,连续读取到本Page的最后一个Byte为止(可以包括Spare Field) Nand Flash的寻址 Nand Flash的地址寄存器把一个完整的Nand Flash地址分解成Column Address与Page Address.进行寻址 Column Address: 列地址。Column Address其实就是指定Page上的某个Byte,指定这个Byte其实也就是指定此页的读写起始地址。 Page Address:页地址。由于页地址总是以512Bytes对齐的,所以它的低9位总是0。确定读写操作是在Flash上的哪个页进行的。 Read1命令 当我们得到一个Nand Flash地址src_addr时我们可以这样分解出Column Address和Page Address column_addr=src_addr%512; // column address page_address=(src_addr>>9); // page address 也可以这么认为,一个Nand Flash地址的A0~A7是它的column_addr,A9~A25是它的Page Address。(注意地址位A8并没有出现,也就是A8被忽略,在下面你将了解到这是什么原因) Read1命令的操作分为4个Cycle,发送完读命令00h或01h(00h与01h的区别请见下文描述)之后将分4个Cycle发送参数,1st.Cycle是发送Column Address。2nd.Cycle ,3rd.Cycle和4th.Cycle则是指定Page Address(每次向地址寄存器发送的数据只能是8位,所以17位的Page Address必须分成3次进行发送)。 4个Cycle 你是否还记得我上文提到过的Data Field被分为1st half 和2end half两个部分?而从上面的命令集我们看到Read1的命令里面出现了两个命令选项,分别是00h和01h。这里出现了两个读命是否令你意识到什么呢?是的,00h是用于读写1st half的命令,而01h是用于读取2nd half的命令。现在我可以结合上图给你说明为什么K9F1208U0B的DataField被分为2个half了。 如上文我所提及的,Read1的1st.Cycle是发送Column Address,假设我现在指定的Column Address是0,那么读操作将从此页的第0号Byte开始一直读取到此页的最后一个Byte(包括Spare Field),如果我指定的Column Address是127,情况也与前面一样,但不知道你发现没有,用于传递Column Address的数据线有8条(I/O0~I/O7,对应A0~A7,这也是A8为什么不出现在我们传递的地址位中),也就是说我们能够指定的Column Address范围为0~255,但不要忘了,1个Page的DataField是由512个Byte组成的,假设现在我要指定读命令从第256个字节处开始读取此页,那将会发生什么情景?我必须把Column Address设置为256,但Column Address最大只能是255,这就造成数据溢出。。。正是因为这个原因我们才把Data Field分为两个半区,当要读取的起始地址(Column Address)在0~255内时我们用00h命令,当读取的起始地址是在256~511时,则使用01h命令.假设现在我要指定从第256个byte开始读取此页,那么我将这样发送命令串 column_addr=256; NF_CMD=0x01; 从2nd half开始读取 NF_ADDR=column_addr&0xff; 1st Cycle NF_ADDR=page_address&0xff; 2nd.Cycle NF_ADDR=(page_address>>8)&0xff; 3rd.Cycle NF_ADDR=(page_address>>16)&0xff; 4th.Cycle 其中NF_CMD和NF_ADDR分别是NandFlash的命令寄存器和地址寄存器的地址解引用,我一般这样定义它们, #define rNFCMD (*(volatile unsigned char *)0x4e000004) //NADD Flash command #define rNFADDR (*(volatile unsigned char *)0x4e000008) //NAND Flash address 事实上,当NF_CMD=0x01时,地址寄存器中的第8位(A8)将被设置为1(如上文分析,A8位不在我们传递的地址中,这个位其实就是硬件电路根据01h或是00h这两个命令来置高位或是置低位),这样我们传递column_addr的值256随然由于数据溢出变为1,但A8位已经由于NF_CMD=0x01的关系被置为1了,所以我们传到地址寄存器里的值变成了 A0 A1 A2 A3 A4 A5 A6 A7 A8 1 0 0 0 0 0 0 0 1 这8个位所表示的正好是256,这样读操作将从此页的第256号byte(2nd half的第0号byte)开始读取数据。 Read2 Read2则是指定读取Spare Field的内容 其实Read1和Read2都是读命令,他们的区别相当于对一个读指针进行不同区域的定位。 nand_flash.c中包含3个函数 void nf_reset(void); void nf_init(void); void nf_read(unsigned int src_addr,unsigned char *desc_addr,int size); nf_reset()将被nf_init()调用。 nf_init()是nand_flash的初始化函数,在对nand flash进行任何操作之前,nf_init()必须被调用。 nf_read(unsigned int src_addr,unsigned char *desc_addr,int size);为读函数,src_addr是nand flash上的地址,desc_addr是内存地址,size是读取文件的长度。 在nf_reset和nf_read函数中存在两个宏 NF_nFCE_L(); NF_nFCE_H(); 你可以看到当每次对Nand Flash进行操作之前NF_nFCE_L()必定被调用,操作结束之时NF_nFCE_H()必定被调用。这两个宏用于启动和关闭Flash芯片的工作(片选/取消片选)。 至于nf_reset()中的 rNFCONF=(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); 这一行代码是对NandFlash的控制寄存器进行初始化配置,rNFCONF是Nand Flash的配置寄存器,各个位的具体功能请参阅s3c2410数据手册。 现在举一个例子,假设我要从Nand Flash中的第5000字节处开始读取1024个字节到内存的0x30000000处,我们这样调用read函数 nf_read(5000, 0x30000000,1024); 我们来分析5000这个src_addr. 根据 column_addr=src_addr%512; page_address=(src_addr>>9); 我们可得出column_addr=5000%512=392 page_address=(5000>>9)=9 于是我们可以知道5000这个地址是在第9页的第392个字节处,于是我们的nf_read函数将这样发送命令和参数 column_addr=5000%512; page_address=(5000>>9); NF_CMD=0x01; 从2nd half开始读取 NF_ADDR= column_addr &0xff; 1st Cycle NF_ADDR=page_address&0xff; 2nd.Cycle NF_ADDR=(page_address>>8)&0xff; 3rd.Cycle NF_ADDR=(page_address>>16)&0xff; 4th.Cycle 向NandFlash的命令寄存器和地址寄存器发送完以上命令和参数之后,我们就可以从rNFDATA寄存器(NandFlash数据寄存器)读取数据了. 我用下面的代码进行数据的读取. for(i=column_addr;i<512;i++) { *buf++=NF_RDDATA(); } 每当读取完一个Page之后,数据指针会落在下一个Page的0号Column(0号Byte). Fisrt part : NAND flash和NOR flash的不同 NOR flash采用位读写,因为它具有sram的接口,有足够的引脚来寻址,可以很容易的存取其内部的每一个字节。NAND flash使用复杂的I/O口来穿行地存取数据。8个引脚用来传送控制、地址和数据信息。NAND的读和写单位为512Byte的页,擦写单位为32页的块。 ● NOR的读速度比NAND稍快一些。 ● NAND的写入速度比NOR快很多。 ● NAND的4ms擦除速度远比NOR的5s快。 ● 大多数写入操作需要先进行擦除操作。 ● NAND的擦除单元更小,相应的擦除电路更少。 在NOR器件上运行代码不需要任何的软件支持,在NAND器件上进行同样操作时,通常需要驱动程序,也就是内存技术驱动程序(MTD),NAND和NOR器件在进行写入和擦除操作时都需要MTD。 ---------摘抄自网上流传很广的《NAND 和 NOR flash的区别》 Second part: NAND Flash结构与驱动分析 一、NAND flash的物理组成 NAND Flash 的数据是以bit的方式保存在memory cell,一般来说,一个cell 中只能存储一个bit。这些cell 以8个或者16个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND Device的位宽。这些Line会再组成Page,(NAND Flash 有多种结构,我使用的NAND Flash 是K9F1208,下面内容针对三星的K9F1208U0M),每页528Bytes(512byte(Main Area)+16byte(Spare Area)),每32个page形成一个Block(32*528B)。具体一片flash上有多少个Block视需要所定。我所使用的三星k9f1208U0M具有4096个block,故总容量为4096*(32*528B)=66MB,但是其中的2MB是用来保存ECC校验码等额外数据的,故实际中可使用的为64MB。 NAND flash以页为单位读写数据,而以块为单位擦除数据。按照这样的组织方式可以形成所谓的三类地址: Column Address:Starting Address of the Register. 翻成中文为列地址,地址的低8位 Page Address :页地址 Block Address :块地址 对于NAND Flash来讲,地址和命令只能在I/O[7:0]上传递,数据宽度是8位。 二、NAND Flash地址的表示 512byte需要9bit来表示,对于528byte系列的NAND,这512byte被分成1st half Page Register和2nd half Page Register,各自的访问由地址指针命令来选择,A[7:0]就是所谓的column address(列地址),在进行擦除操作时不需要它,why?因为以块为单位擦除。32个page需要5bit来表示,占用A[13:9],即该page在块内的相对地址。A8这一位地址被用来设置512byte的1st half page还是2nd half page,0表示1st,1表示2nd。Block的地址是由A14以上的bit来表示。 例如64MB(512Mb)的NAND flash(实际中由于存在spare area,故都大于这个值),共4096block,因此,需要12个bit来表示,即A[25:14],如果是128MB(1Gbit) 的528byte/page的NAND Flash,则block address用A[26:14]表示。而page address就是blcok address|page address in block NAND Flash 的地址表示为: Block Address|Page Address in block|halfpage pointer|Column Address 地址传送顺序是Column Address,Page Address,Block Address。 由于地址只能在I/O[7:0]上传递,因此,必须采用移位的方式进行。 例如,对于512Mbit x8的NAND flash,地址范围是0~0x3FF_FFFF,只要是这个范围内的数值表示的地址都是有效的。 以NAND_ADDR 为例: 第1 步是传递column address,就是NAND_ADDR[7:0],不需移位即可传递到I/O[7:0]上,而halfpage pointer即A8 是由操作指令决定的,即指令决定在哪个halfpage 上进行读 写,而真正的A8 的值是不需程序员关心的。 第2 步就是将NAND_ADDR 右移9位,将NAND_ADDR[16:9]传到I/O[7:0]上; 第3 步将NAND_ADDR[24:17]放到I/O上; 第4步需要将NAND_ADDR[25]放到I/O上; 因此,整个地址传递过程需要4 步才能完成,即4-step addressing。 如果NAND Flash 的容量是32MB(256Mbit)以下,那么,block adress最高位只到bit24,因此寻址只需要3步。 下面,就x16 的NAND flash 器件稍微进行一下说明。 由于一个page 的main area 的容量为256word,仍相当于512byte。但是,这个时候没有所谓的1st halfpage 和2nd halfpage 之分了,所以,bit8就变得没有意义了,也就是这个时候 A8 完全不用管,地址传递仍然和x8 器件相同。除了,这一点之外,x16 的NAND使用方法和 x8 的使用方法完全相同。 三、NAND flash驱动解读 以前由于做移植多一些,那些工作很简单(现在看来),从来都不用去关心驱动里面到底怎么实现的,这几次面试才发现真的是学的太浅了,似乎我还在学习仰泳而那些牛人基本都属于潜水级的了,潜的不知有多深。我对照着开发板所带的NAND flash驱动和k9f1208的芯片资料把这些代码通读了一遍,终于明白了NAND flash的读写过程是如何实现的了。我所参考的驱动是mizi公司为三星芯片所写的,我看看了,大概和官方2.4.18内核的nand.c差不多。 在s3c2410处理器中有专门的NAND flash控制器,他们位于SFR区,具体可以参看s3c2410用户手册。以下的这些代码均可以在vivi或者kernel里面找到,文中会标明程序出自何处。在vivi中,有关NAND flash的驱动都在driver/mtd/nand/下,该目录中包含的源文件:smc_core.c是NAND flash的主要驱动。 NAND flash 芯片定义了一个很长的结构,这个结构中包含了操作NAND flash的函数和一些必要的变量(include/mtd/nand.h)。 struct nand_chip { #ifdef CONFIG_MTD_NANDY /* =y */ void (*hwcontrol)(int cmd); void (*write_cmd)(u_char val); void (*write_addr)(u_char val); u_char (*read_data)(void); void (*write_data)(u_char val); void (*wait_for_ready)(void); int page_shift; u_char *data_buf; u_char *data_cache; int cache_page; struct nand_smc_dev *dev; u_char spare[SMC_OOB_SIZE]; #else /* CONFIG_MTD_NANDY */ …… #ifdef CONFIG_MTD_NAND_ECC u_char ecc_code_buf[6]; u_char reserved[2]; #endif #endif /* CONFIG_MTD_NANDY */ }; 纵观对NAND flash的各种操作(read、write、erase),无外乎如下几种操作: 1.选择flash nand_select() 2.发送命令 nand_command() 3.进行相应操作 read,write…… 4.反选NAND flash nand_deselect() 下面是以上四步的实现代码: 1、选择NAND flash #define nand_select() this->hwcontrol(NAND_CTL_SETNCE); \ nand_command(mtd, NAND_CMD_RESET, -1, -1); \ udelay (10); hwcontrol(NAND_CTL_SETNCE)的作用是设置2410的NAND FLASH CONFIGURATION (NFCONF) REGISTER的NAND Flash Memory chip enable位为0,这位寄存器在自动重启后就被系统自动清零。如果要访问NAND flash的内存,这位必须置1。 nand_command(mtd, NAND_CMD_RESET, -1, -1);向flash发送命令,此命令为reset,即为重置NAND flash。 然后是10us的延迟,给flash个反应时间。 2、发送命令 Nand_command()同样在smc_core.c中实现。NAND flash的命令有如下几种: 命令 命令值 描述 NAND_CMD_READ0 0 读操作 NAND_CMD_READ1 1 读操作 NAND_CMD_PAGEPROG 0x10 页编程操作 NAND_CMD_READOOB 0x50 读写OOB NAND_CMD_ERASE1 0x60 读写操作 NAND_CMD_STATUS 0x70 读取状态 NAND_CMD_STATUS_MULTI 0x71 读取状态 NAND_CMD_SEQIN 0x80 写操作 NAND_CMD_READID 0x90 读Flash ID号 NAND_CMD_ERASE2 0xd0 擦写操作 NAND_CMD_RESET oxff 复位操作 按照程序的注释,可以将该函数的实现分为如下几步: 1、Begin command latch cycle 实现代码: this->hwcontrol(NAND_CTL_SETCLE); this->hwcontrol(NAND_CTL_DAT_OUT); 找到第二条语句的定义,发现什么都么做,不解!!希望达人解答。我猜想可能是一个数据读出的使能操作,允许数据读出。 Command Latch Enable(CLE) and Address Latch Enable(ALE) are used to multiplex command and address respectively, via the I/O pins. The CLE input controls the path activation for commands sent to the command register. When active high, commands are latched into the command register through the I/O ports on the rising edge of the nWE signal. 看了这段英文相信对第一条语句的作用已经十分清楚了,他就是用来控制向命令寄存(COMMAND SET (NFCMD) REGISTER)发送命令的。 2、 Write out the command to the device 这部分对于不同的命令来说,操作的步骤也不太相同,如果为写操作,那么还有根据flash不同的容量决定操作步骤,具体可以参看代码。如果为其他命令,那么就是简单的一行: this->write_cmd (command); 将命令直接想到命令寄存器(NFCMD[7:0])中。 3、 Set ALE and clear CLE to start address cycle & Serially input address 1中已经提到了ALE和CLE的作用,现在开始发送地址。 实现代码: this->hwcontrol(NAND_CTL_CLRCLE); // clear the command latch enable this->hwcontrol(NAND_CTL_SETALE); // set the address latch enable 然后按位操作,是用函数write_addr()将地址写到NAND FLASH ADDRESS SET (NFADDR) REGISTER中。 4、 Latch in address 实现代码: this->hwcontrol(NAND_CTL_CLRALE); this->hwcontrol(NAND_CTL_DAT_IN); 地址发送完毕,清楚ALE。 5、 Pause for 15us 我使用的VIVI中,使用udelay (15)延时15us,但这个时间会因NAND Flash的不同而不同。 三、Operation 根据函数的不同,操作部分会不一样,但是主要的是对NAND FLASH DATA (NFDATA) REGISTER的操作,或写(编程)或者读。通过读或写函数的参数来返回或传递读出的值或写入的值。写得操作通常比较麻烦,他要将写到flash的内容重新读出后进行ECC校验,如果数据正确则在重新真正的写(编程),如果错误,则将数据写入flash的另一个块。读和写都是以页为单位进行操作。而擦除则以块为单位,三个周期发送完地址。擦除完毕后同样需要进行检察以确定是否擦除成功。 四、De-select the NAND device 实现代码: #define nand_deselect() this->hwcontrol(NAND_CTL_CLRNCE); 反选flash吧,不知这样叫正确与否,跟select the NAND device相反,亦即使用完后将使能flash位清0,代码是NFCONF位于0x4e00_0000的位置(NFCONF |= NFCONF_nFCE_HIGH;),有兴趣的可以读读代码,看看这是怎么实现的,我的感觉就是关于寄存器的清置读起来都比较晕。 好了,到此flash操作的框架基本完成。 |
相关推荐
NAND_FLASH(K9F1208U0C)驱动分析
一、 编写目的 2 二、 NAND FLASH(K9F1208U0C) 2 1. 引脚说明 2 2. memory组织方式 3 3. 地址传输 4 4. 命令 5 5. 模式控制 5 6. 操作时间限制 6 三、 Bootstrap驱动分析 6 1. CPU引脚设置 6 2. CPU NAND控制器设置 6 3. 读取NAND ID 6 4. 读取一页数据 7 5. 读取
NandFlash读写过程
一、结构分析 S3C2410处理器集成了8位NandFlash控制器。目前市场上常见的8位NandFlash有三星公司的k9f1208、k9f1g08、k9f2g08等。k9f1208、k9f1g08、k9f2g08的数据页大小分别为512Byte、2kByte、2kByte
RAM、NAND Flash、NOR Flash的区别详解
一、RAM和Flash的区别 RAM有两大类,一种称为静态RAM (Static RAM/SRAM),SRAM速度非常快,是目前读写最快的存储设备了,但是它也非常昂贵,所以只在要求很苛刻的地方使用,譬如CPU的一级缓冲cache。另一种称为动态RAM(Dynamic RAM/DRAM),DRAM保留数据的时间很短,速度也比SRAM慢,不过它还是比任何的ROM都要快,但从价格上来说DRAM
NAND Flash硬件读写原理
1.nand接口 s3c2440板的Nand Flash模块由两部分组成:Nand Flash控制器(集成在s3c2440)和Nand Flash存储芯片(K9F1208U0B)两大部分组成。当要访问Nand Flash中的数据时,必须通过Nand Flash控制器发送命令序列才能完成。所以, Nand Flash相当于s3c2440的一个外设,而不位于它的内存地址区.。
NAND FLASH 内存详解与读写寻址方式
目录: 第一章 绪论 1.1 课题来源 1.2 研究背景与意义 1.2.1 Flash介绍 1.2.2 NAND Flash介绍 1.2.3 NAND Flash与NOR Flash比较 1.2.4 研究目的 1.3 论文章节安排 第二章 NAND Flash结构与原理 2.1 NAND Flash种类 2.1.1 ...
08-Nand flash
声明: 本文是本人在韦东山笔记的基础上加了一些注释,方便理解。原文地址:http://wiki.100ask.org/%E7%AC%AC016%E8%AF%BE_Nand_Flash#.E7.AC.AC001.E8.8A.82_NAND_FLASH.E6.93.8D.E4.BD.9C.E5.8E.9F.E7.90.86 第1节 Nand flash操作原理 1.1 几个问题 首先看一下Nand flash的PCB原理图: 可以看出,NAND FLASH是一个存储芯片 那么: 这样的操作很合理即----“读
NAND FLASH的读写操作(硬件原理图分析)
转载:NAND FLASH的读操作及原理 硬件原理 上面是我使用的NAND FLASH的硬件原理图,面对这些引脚,很难明白他们是什么含义,下面直接引用韦东山老师的课程中的提问: NAND FLASH是一个存储芯片 那么: 这样的操作很合理"读地址A的数据,把数据B写到地址A" 问1. 原理图上NAND FLASH和S3C2440之间只有数据线, 怎么传输地址? 答1.在DA...
NAND Flash控制器读写编程指南
为了有效地使用NAND Flash存储器,开发人员需要了解如何编写NAND Flash控制器的读写程序。本指南将介绍NAND Flash控制器的读写编程,并提供相应的源代码示例。NAND Flash存储器是一种基于闪存技术的存储设备,它由多个存储单元组成,每个存储单元可以存储多个位的数据。每个页通常包含多个字节的数据和一个校验码。但是,以上代码提供了一个起点,可以帮助您开始编写NAND Flash控制器的读写程序。对于NAND Flash的读操作,我们首先需要选择合适的读命令,并提供相应的地址信息。
闪存flash读写原理
首先讲述的是基本原理,因为前面总结了很多基本原理,所以这个位置比较粗略的带过。 1、基本原理 从图上可以看出,Vt为开启电压,对于N沟道的cmos,当门极加的电压逐渐变大的时候,多数载流子被门极所吸引,向上移动,形成N型沟道,N型半导体即被导通,有导通电流。开始有导通电流的门极所加的电压我们称为开启电压,随着开启电压的增大,电流逐渐增大。这就是cmos管的基本原理。 从cmos管过渡到nand ...
不用API Key也能玩转Obsidian AI:本地大模型离线配置全攻略
本文详细介绍了如何在无需API Key的情况下,通过本地部署大型语言模型(LLM)为Obsidian注入AI能力。文章以Ollama为例,提供了从环境准备、模型选择到与Obsidian插件(如Text Generator)集成的完整配置攻略,旨在帮助用户打造一个安全、离线可用的智能笔记工作流,实现数据隐私与AI助力的完美结合。
用Isaac Sim复现经典案例:手把手教你写Python脚本控制机械臂抓取(附避障算法调试心得)
本文详细介绍了如何使用NVIDIA Isaac Sim仿真系统复现机械臂抓取经典案例,包括Python脚本编写、避障算法调试等关键步骤。通过URDF模型导入、关节控制逻辑实现和RMPFlow避障配置等实战演示,帮助开发者快速掌握机器人仿真技术,特别分享了官方文档未提及的实用调试技巧和性能优化策略。
NAND Flash学习总结
nand flash学习总结
宝塔面板+pbootCMS建站全流程:从服务器选购到上线优化(附常见问题排查)
本文提供了一份详尽的宝塔面板与pbootCMS建站实战指南。内容涵盖从云服务器选购、宝塔面板部署与安全加固,到pbootCMS安装、权限配置、数据库连接等核心步骤。同时深入讲解了PHP环境优化、Nginx伪静态设置、缓存开启等性能与SEO优化技巧,并附有常见问题排查与后期维护建议,帮助用户高效、稳健地完成专业网站构建。
uboot下nand flash读写方法_电脑手机都用它:一文读懂DRAM、SRAM和Flash原理
DRAM、SRAM和Flash都属于存储器,DRAM通常被称为内存,也有些朋友会把手机中的Flash闪存误会成内存。SRAM的存在感相对较弱,但他却是CPU性能发挥的关键。DRAM、SRAM和Flash有何区别,它们是怎样工作的?DRAM:动态随机存取存储器DRAM的全称是Dynamic Random Access Memory,动态随机存取存储器。"随机存取"意味着CPU可以存取其中的的任意位置...
AutoModelForCausalLM 加载失败:flash_attn 缺失的三种解决方案
本文针对使用AutoModelForCausalLM加载大语言模型时因缺失flash_attn依赖而报错的问题,提供了三种实用解决方案。最推荐通过修改模型配置文件或代码动态指定注意力实现为“eager”模式来绕过检查,也介绍了临时修改库源码的应急方法,并解释了flash_attn的作用及正确安装指南。
NVIDIA DGX Spark实战:如何在桌面上轻松运行200B参数大模型(附配置教程)
本文提供了NVIDIA DGX Spark在桌面端运行200B参数大模型的完整实战指南。详细介绍了从硬件初始化、系统配置、容器化环境搭建,到模型加载、量化、推理流水线编写及性能调优的全过程。重点阐述了如何利用其统一内存架构和TensorRT-LLM等工具进行高效本地推理,并探讨了通过双机互联扩展以应对超大规模模型的方法。
NAND FLASH 原理
NAND FLASH 原理 http://www.360doc.com/content/12/0522/21/21412_212888167.shtml 闪存保存数据的原理: 与DRAM以电容作为存储元件不同,闪存的存储单元为三端器件,与场效应管有相同的名称:源极、漏极和栅极。栅极与硅衬底之间有二氧化硅绝缘层,用 来保护浮置栅极中的电荷不会泄漏。采用这种结构,使得存储单元具有了电荷保持能力,就像是装进瓶子里的水,当你倒入水后,水位就一直保持在那里,直到你再 次倒入或倒出,所以闪存具有记忆能力。
浅谈MOS管的发热原因和解决办法
解读一下开关管发热原因,解决方案和开关损耗测试。
【FLASH存储器系列四】NAND和NOR两种Flash的本质区别是什么?
详述nand flash和nor flash的区别,以及导致这些区别的本质
第三节:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入门 - 对接后端登录接口(上)
这里是Vben Admin V5版本实战体验,上一节我们前端已正常运行,但是没有实现登录。本节的重点是对接后端接口。上一节地址:第一节:Vben Admin 最新 v5.0初体验第二节:Vben Admin 登录逻辑梳理和对接后端准备后端我们采用Python的Flask项目,Flask-SQLAlchemy管理数据库模型,Flask-Migrate进行模型迁移。参考版本如下:Flask3.0.23.1.1到这里,登录接口完成,下一步要实现获取用户信息和权限的接口功能。
在iPad上使用Python进行编程
如果你拥有一台iPad,并且想在上面编写和运行Python代码,你会发现iPad提供了一些适用的工具和应用程序来满足你的需求。安装一个Python解释器应用程序,编写和运行Python代码,使用第三方库和模块,以及存储和共享代码,这些步骤将帮助你在iPad上进行Python编程。要在iPad上运行Python代码,首先需要安装一个Python解释器。这些应用程序提供了一个交互式的开发环境,允许你编写、编辑和运行Python代码。一旦你安装了Python解释器应用程序,你可以开始编写Python代码了。
NAND Flash--嵌入式NAND Flash读写技术
NAND Flash控制器 S3C2410板的Nand Flash支持由两部分组成:Nand Flash控制器(集成在S3C2410 CPU)和Nand Flash存储芯片(K9F1208U0B)两部分组成。当要访问Nand Flash中的数据时,必须通过Nand Flash控制器发送命令才能完成。所以Nand Flash相当于S3C2410的一个外设,而不位于它的内存地址区.
数学建模模型总结
这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!
5541



被折叠的 条评论
为什么被折叠?



