nand控制器器需要额外做什么动作才能更好的利用nand存储器

拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(3cb823b1c6864364-ua98).
重新安装浏览器,或使用别的浏览器您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
应用于SSD的NAND+FLASH控制器的设计.pdf 77页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:200 &&
应用于SSD的NAND+FLASH控制器的设计.pdf
你可能关注的文档:
··········
··········
隶.初大·粤
硕士学位论文
应用于SSD的NANDFLASH控制器的设计
ofNANDFLASH
Controllerfor
Solid..StateDisks
ThesisSubmittedto
University
FortheAcademicofMasterof
Engineering
SHENYunfei
Supervisedby
Prof.HUChen
ofElectronicScienceand
Engineering
University
东南大学学位论文独创性声明
本人声明所呈交的学位论文是我个人在导师指导下进行的研究工作及取得的研究成果。尽我所
知,除了文中特别加以标注和致谢的地方外,论文中不包含其他人已经发表或撰写过的研究成果,
也不包含为获得东南大学或其它教育机构的学位或证书而使用过的材料。与我一同工作的同志对本
研究所做的任何贡献均已在论文中作了明确的说明并表示了谢意。
研究生签名:』臣』』L日期:j生坚。盖—耻
东南大学学位论文使用授权声明
东南大学、中国科学技术信息研究所、国家图书馆有权保留本人所送交学位论文的复印件和电
子文档,可以采用影印、缩印或其他复制手段保存论文。本人电子文档的内容和纸质论文的内容相
一致。除在保密期内的保密论文外,允许论文被查阅和借阅,可以公布(包括以电子信息形式刊登)
论文的全部内容或中、英文摘要等部分内容。论文的公布(包括以电子信息形式刊登)授权东南大
学研究生院办理。
研究生签名:l担堇:&~导师签名:
当今的数字时代对数据存储的大容量、高速度的需求不断提高,传统的机械硬盘(加)D,Hard
Disk)已不能满足这样的需求,在这样的情况下固态硬盘(SSD,SolidDisk)应运而生。
固态硬盘主要采用NANDFLASH作为存储单元,而控制芯片主要用于NANDFLASH的管理,NAND
FLASH控制器的好坏将直接影响控制芯片的好坏,进而影响固态硬盘的性能。
本论文研究了应用于SSD的NANDFLASH控制器的实现方案,完成了控制器的设计并进行了
系统的验证。为了提高SSD中的FLASH接口的数据带宽本控制器采用8通道8级流水线操作来控
子模块、命令控制子模块、NANDFLASH接口子模块、ECC管理子模块。除ECC子模块外其他部
传输。为了提高少量数据操作时的性能,本控制器支持“伪DMA’操作,通过CPU和DMA接口的
混合使用来提高数据传输率,经过测试,在少量数据操作时其可以将效率提升10倍。另外本控制器
可以对每个通道单独操作,可以在不浪费存储空间的前提下进行少量数据的
正在加载中,请稍后...linux driver(23)
今天学习了NandFlash的驱动,硬件操作非常简单,就是这个linux下的驱动比较复杂,主要还是MTD层的问题,用了一下午时间整理出来一份详细的分析,只是分析函数结构和调用关系,具体代码实现就不看了,里面有N个结构体,搞得我头大。
我用linux2.6.25内核,2440板子,先从启动信息入手。
内核启动信息,NAND部分:
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2440-nand s3c2440-nand: Tacls=2, 20ns Twrph0=3 30ns, Twrph1=2 20ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)
Scanning device for bad blocks
Creating 3 MTD partitions on &NAND 64MiB 3,3V 8-bit&:
0xx : &boot&
0xx : &kernel&
0xx03ffc000 : &yaffs2&
第一行,在driver/mtd/nand/s3c2410.c中第910行,s3c2410_nand_init函数:
printk(&S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n&);
行二行,同一文件,第212行,s3c2410_nand_inithw函数:
dev_info(info-&device, &Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n&, tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate));
第三行,在driver/mtd/nand/nand_base.c中第2346行,
printk(KERN_INFO &NAND device: Manufacturer ID:& & 0x%02x, Chip ID: 0x%02x (%s %s)\n&, *maf_id, dev_id, nand_manuf_ids[maf_idx].name, type-&name);
第四行,在driver/mtd/nand/nand_bbt.c中第380行,creat_bbt函数:
Printk(KERN INFO & Scanning device for bad blocks \n&);
第五行,在driver/mtd/mtdpart.c中第340行,add_mtd_partitions函数:
printk (KERN_NOTICE &Creating %d MTD partitions on \&%s\&:\n&, nbparts, master-&name);
下面三行,是flash分区表,也在mtdpart.c同一函数中,第430行:
printk (KERN_NOTICE &0x%08x-0x%08x : \&%s\&\n&, slave-&offset, slave-&offset + slave-&mtd.size, slave-&mtd.name);
MTD体系结构:
在linux中提供了MTD(Memory Technology Device,内存技术设备)系统来建立Flash针对linux的统一、抽象的接口
引入MTD后,linux系统中的Flash设备驱动及接口可分为4层:
MTD原始设备层
硬件驱动层
硬件驱动层:Flash硬件驱动层负责底层硬件设备实际的读、写、擦除,Linux MTD设备的NAND型Flash驱动位于driver/mtd/nand子目录下
s3c2410对应的nand Flash驱动为s3c2410.c
MTD原始设备层:MTD原始设备层由两部分构成,一部分是MTD原始设备的通用代码,另一部分是各个特定Flash的数据,比如分区
主要构成的文件有:
drivers/mtd/mtdcore.c 支持mtd字符设备
driver/mtd/mtdpart.c& 支持mtd块设备
MTD设备层:基于MTD原始设备,Linux系统可以定义出MTD的块设备(主设备号31) 和字符设备(设备号90),构成MTD设备层
简单的说就是:使用一个mtd层来作为具体的硬件设备驱动和上层文件系统的桥梁。mtd给出了系统中所有mtd设备(nand,nor,diskonchip)的统一组织方式。
mtd层用一个数组struct mtd_info *mtd_table[MAX_MTD_DEVICES]保存系统中所有的设备,mtd设备利用struct mtd_info 这个结构来描述,该结构中描述了存储设备的基本信息和具体操作所需要的内核函数,mtd系统的那个机制主要就是围绕这个结构来实现的。结构体在include/linux/mtd/mtd.h中定义:
struct mtd_info {
u_&&&&&&&&& &&//MTD 设备类型
u_int32_&&& &&&&//MTD设备属性标志
u_int32_ &&&&&&&&//标示了这个mtd设备的大小
u_int32_ &&&//MTD设备的擦除单元大小,对于NandFlash来说就是Block的大小
u_int32_& &&&&//oob区在页内的位置,对于512字节一页的nand来说是512
u_int32_&& &&&//oob区的大小,对于512字节一页的nand来说是16
u_int32_&&&&& //ecc校验类型
u_int32_ &&&&&//ecc的大小
char *&&&&&&&&&&&& //设备的名字
&&&&&&&&&&&&& //设备在MTD列表中的位置
struct nand_ //oob区的信息,包括是否使用ecc,ecc的大小
//以下是关于mtd的一些读写函数,将在nand_base中的nand_scan中重载
int (*erase)
int (*read)
int (*write)
int (*read_ecc)
int (*write_ecc)
int (*read_oob)
int (*read_oob)
void *//设备私有数据指针,对于NandFlash来说指nand芯片的结构
下面看nand_chip结构,在include/linux/mtd/nand.h中定义:
struct nand_chip {
void& __iomem&& *IO_ADDR_R;& &&//这是nandflash的读写寄存器
void& __iomem&&&& *IO_ADDR_W;&
//以下都是nandflash的操作函数,这些函数将根据相应的配置进行重载
u_char&&& (*read_byte)(struct mtd_info *mtd);
void&&&&& (*write_byte)(struct mtd_info *mtd, u_char byte);
u16&&&&&& (*read_word)(struct mtd_info *mtd);
void&&&&& (*write_word)(struct mtd_info *mtd, u16 word);
void&&&& (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len);
void&&&& (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);
int&&&& (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);
void&&&& (*select_chip)(struct mtd_info *mtd, int chip);
int&&&& (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
int&&&&& (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
void&&&& (*hwcontrol)(struct mtd_info *mtd, int cmd);
int&&&&& (*dev_ready)(struct mtd_info *mtd);
void&& &&(*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
int&&& &&(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state);
int&&&& (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
int& &(*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
void& &&(*enable_hwecc)(struct mtd_info *mtd, int mode);
void&&& (*erase_cmd)(struct mtd_info *mtd, int page);
int&&&& (*scan_bbt)(struct mtd_info *mtd);
int&&&&&&&& &&//ecc的校验模式(软件,硬件)
int& &&&&&chip_& //芯片时序延迟参数
int&&&&&& page_& //页偏移,对于512B/页的,一般是9
u_char&&& *data_ &&//数据缓存区
跟NAND操作相关的函数:
1、 nand_base.c:
定义了NAND驱动中对NAND芯片最基本的操作函数和操作流程,如擦除、读写page、读写oob等。当然这些函数都只是进行一些常规的操作,若你的系统在对NAND操作时有一些特殊的动作,则需要在你自己的驱动代码中进行定义。
2、 nand_bbt.c:
定义了NAND驱动中与坏块管理有关的函数和结构体。
3、 nand_ids.c:
定义了两个全局类型的结构体:struct nand_flash_dev nand_flash_ids[ ]和struct nand_manufacturers nand_manuf_ids[ ]。其中前者定义了一些NAND芯片的类型,后者定义了NAND芯片的几个厂商。NAND芯片的ID至少包含两项内容:厂商ID和厂商为自己的NAND芯片定义的芯片ID。当NAND加载时会找这两个结构体,读出ID,如果找不到,就会加载失败。
4、 nand_ecc.c:
定义了NAND驱动中与softeware ECC有关的函数和结构体,若你的系统支持hardware ECC,且不需要software ECC,则该文件也不需理会。
我们需要关心的是/nand/s3c2410,这个文件实现的是s3cnandflash控制器最基本的硬件操作,读写擦除操作由上层函数完成。
s3c2410.c分析:
首先看一下要用到的结构体的注册:
struct s3c2410_nand_mtd {
&&& struct mtd_info&&&&&&& //mtd_info的结构体
&&& struct nand_chip&&&&& //nand_chip的结构体
&&& struct s3c2410_nand_set&&&& *
&&& struct s3c2410_nand_info && *
&&& int&&&&&&&&&& scan_
enum s3c_cpu_type {& //用来枚举CPU类型
&&& TYPE_S3C2410,
&&& TYPE_S3C2412,
&&& TYPE_S3C2440,
struct s3c2410_nand_info {&
&&& /* mtd info */
&&& struct nand_hw_control&&&&&
&&& struct s3c2410_nand_mtd&&&& *
&&& struct s3c2410_platform_nand&&& *
&&& /* device info */
&&& struct device&&&&&&& *
&&& struct resource&&&&&&&&& *
&&& struct clk&&&&&&& *
&&& void __iomem&&&&&&&& *
&&& void __iomem&&&&&&&& *sel_
&&& int&&&&&&&&&& sel_
&&& int&&&&&&&&&& mtd_
&&& unsigned long&&&&&&& save_
&&& enum s3c_cpu_type&&& cpu_
设备的注册:
static int __init s3c2410_nand_init(void)
&&& printk(&S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n&);
&&& platform_driver_register(&s3c2412_nand_driver);
&&& platform_driver_register(&s3c2440_nand_driver);
&&& return platform_driver_register(&s3c2410_nand_driver);
platform_driver_register向内核注册设备,同时支持这三种CPU。
&s3c2440_nand_driver是一个platform_driver类型的结构体:
static struct platform_driver s3c2440_nand_driver = {
&&& .probe&&&& = s3c2440_nand_probe,
&&& .remove&& = s3c2410_nand_remove,
&&& .suspend&& = s3c24xx_nand_suspend,
&&& .resume&&& = s3c24xx_nand_resume,
&&& .driver&&& = {
&&&&&& .name& = &s3c2440-nand&,
&&&&&& .owner = THIS_MODULE,
最主要的函数就是s3c2440_nand_probe,(调用s3c24XX_nand_probe),完成对nand设备的探测,
static int s3c24xx_nand_probe(struct platform_device *pdev,
&&&&&&&&&& &&&&& enum s3c_cpu_type cpu_type)
&&&&&& /*主要完成一些硬件的初始化,其中调用函数:*/
&&&&&& s3c2410_nand_init_chip(info, nmtd, sets);
&&&&&& /*init_chip结束后,调用nand_scan完成对flash的探测及mtd_info读写函数的赋值*/
nmtd-&scan_res = nand_scan(&nmtd-&mtd, (sets) ? sets-&nr_chips : 1);
&&&&&& if (nmtd-&scan_res == 0) {
&&&&&&&&&& s3c2410_nand_add_partition(info, nmtd, sets);
Nand_scan是在初始化nand的时候对nand进行的一步非常好重要的操作,在nand_scan中会对我们所写的关于特定芯片的读写函数重载到nand_chip结构中去,并会将mtd_info结构体中的函数用nand的函数来重载,实现了mtd到底层驱动的联系。
并且在nand_scan函数中会通过读取nand芯片的设备号和厂家号自动在芯片列表中寻找相应的型号和参数,并将其注册进去。
static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
&&&&&&&&&&&&& && struct s3c2410_nand_mtd *nmtd,
&&&&&&&&&&&&& && struct s3c2410_nand_set *set)
&&& struct nand_chip *chip = &nmtd-&
&&& void __iomem *regs = info-&
&&& /*以下都是对chip赋值,对应nand_chip中的函数*/
&&& chip-&write_buf&&& = s3c2410_nand_write_& //写buf
&&& chip-&read_buf&&&& = s3c2410_nand_read_&& //读buf
&&& chip-&select_chip& = s3c2410_nand_select_//片选
&&& chip-&chip_delay&& = 50;
&&& chip-&priv && =
&&& chip-&options && = 0;
&&& chip-&controller&& = &info-& //??
&&& switch (info-&cpu_type) {
&&& case TYPE_S3C2440:
&&&&&& chip-&IO_ADDR_W = regs + S3C2440_NFDATA;& //数据寄存器
&&&&&& info-&sel_reg&& = regs + S3C2440_NFCONT;& //控制寄存器
&&&&&& info-&sel_bit = S3C2440_NFCONT_nFCE;
&&&&&& chip-&cmd_ctrl& = s3c2440_nand_ //硬件控制
&&&&&& chip-&dev_ready = s3c2440_nand_& //设备就绪
&&&&&& chip-&read_buf& = s3c2440_nand_read_& //读buf
&&&&&& chip-&write_buf&& = s3c2440_nand_write_//写buf
&&& chip-&IO_ADDR_R = chip-&IO_ADDR_W; //读写寄存器都是同一个
&&& nmtd-&info && =
&&& nmtd-&mtd.priv&&& && = //私有数据指针指向chip
&&& nmtd-&mtd.owner&&& = THIS_MODULE;
&&& nmtd-&set& && =
&&& /*后面是和ECC校验有关的,省略*/
初始化后,实现对nand的基本硬件操作就可以了,包括以下函数:
s3c2410_nand_inithw& //初始化硬件,在probe中调用
s3c2410_nand_select_chip& //片选
s3c2440_nand_hwcontrol& //硬件控制,其实就是片选
s3c2440_nand_devready& //设备就绪
s3c2440_nand_enable_hwecc& //使能硬件ECC校验
s3c2440_nand_calculate_ecc& //计算ECC
s3c2440_nand_read_buf& s3c2440_nand_write_buf
注册nand设备到MTD原始设备层:(这个函数由probe调用)
#ifdef CONFIG_MTD_PARTITIONS&& //如果定义了MTD分区
static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
&&&&&&&&&&&&& &&&&& struct s3c2410_nand_mtd *mtd,
&&&&&&&&&&&&& &&&&& struct s3c2410_nand_set *set)
&&& if (set == NULL)
&&&&&& return add_mtd_device(&mtd-&mtd);
&&& if (set-&nr_partitions & 0 && set-&partitions != NULL) {
&&&&&& return add_mtd_partitions(&mtd-&mtd, set-&partitions, set-&nr_partitions);
&&& return add_mtd_device(&mtd-&mtd);
注册设备用这两个函数:
add_mtd_device& //如果nand整体不分区,用这个,
//该函数在mtdcore.c中实现
add_mtd_partitions& //如果nand是分区结构,用这个,
//该函数在mtdpart.c中实现
同样,注销设备也有两个函数:
del_mtd_device
del_mtd_partitions
NandFlash还有一个分区表结构体,mtd_partition,这个是在arch/arm/plat-s3c24XX/common-smdk.c中定义的。
static struct mtd_partition smdk_default_nand_part[] = {
&&& [0] = {
&&&&&& .name& = &boot&,
&&&&&& .size& = 0x,
&&&&&& .offset&&& = 0,
&&& [1] = {
&&&&&& .name& = &kernel&,
&&&&&& .offset = 0x,
&&&&&& .size& = 0x,
&&& [2] = {
&&&&&& .name& = &yaffs2&,
&&&&&& .offset = 0x,
&&&&&& .size& = 0x03DB0000,
记录了当前的nand flash有几个分区,每个分区的名字,大小,偏移量是多少
系统就是依靠这些分区表找到各个文件系统的
这些分区表nand中的文件系统没有必然关系,分区表只是把flash分成不同的部分
如果自己编写一个nandflash驱动,只需要填充这三个结构体:
Mtd_info&&&& nand_chip&&&& mtd_partition
并实现对物理设备的控制,上层的驱动控制已由mtd做好了,不需要关心
2410NandFlash控制器
D[7:0]: DATA0-7 数据/命令/地址/的输入/输出口(与数据总线共享)
CLE : GPA17& 命令锁存使能 (输出)
ALE : GPA18& 地址锁存使能(输出)
nFCE : GPA22 NAND Flash 片选使能(输出)
nFRE : GPA20 NAND Flash 读使能 (输出)
nFWE : GPA19 NAND Flash 写使能 (输出)
R/nB : GPA21 NAND Flash 准备好/繁忙(输入)
相关寄存器:
NFCONF&& NandFlash控制寄存器
&[15]NandFlash控制器使能/禁止&&&& 0 = 禁止&& 1 = 使能
&[14:13]保留
&[12]初始化ECC解码器/编码器&&& 0 = 不初始化&& 1 = 初始化
&[11]芯片使能& nFCE控制&&&&&&& 0 = 使能&&&&&& 1 = 禁止
&[10:8]TACLS&& 持续时间 = HCLK*(TACLS+1)
&[6:4] TWRPH0
&[2:0] TWRPH1
NFCMD& 命令设置寄存器
&[7:0] 命令值
NFADDR 地址设置寄存器
&[7:0] 存储器地址
NFDATA 数据寄存器
&[7:0] 存放数据
NFSTAT 状态寄存器
&[0]&&& 0 = 存储器忙&&&& 1 = 存储器准备好
NFECC& ECC寄存器
&[23:16]ECC校验码2
&[15:8] ECC校验码1
&[8:0]& ECC校验码0
写入操作以页为单位。写入必须在擦除之后,否则写入将出错。
页写入周期中包括以下步骤:
写入串行数据输入指令(80h)。然后写入4个字节的地址,最后串行写入数据(528Byte)。串行写入的数据最多为528byte。
串行数据写入完成后,需要写入“页写入确认”指令10h,这条指令将初始化器件内部写入操作。
10h写入之后,nand flash的内部写控制器将自动执行内部写入和校验中必要的算法和时序,
系统可以通过检测R/B的输出,或读状态寄存器的状态位(I/O 6)来判断内部写入是否结束
擦除操作:
擦除操作时以块(16K Byte)为单位进行的
擦除的启动指令为60h,随后的3个时钟周期是块地址。其中只有A14到A25是有效的,而A9到A13是可以忽略的。
块地址之后是擦除确认指令D0h,用来开始内部的擦除操作。
器件检测到擦除确认命令后,在/WE的上升沿启动内部写控制器,开始执行擦除和擦除校验。内部擦除操作完成后,应该检测写状态位(I/O 0),从而了解擦除操作是否成功完成。
读操作有两种读模式:
读方式1用于读正常数据;
读方式2用于读附加数据
在初始上电时,器件进入缺省的“读方式1模式”。在这一模式下,页读取操作通过将00h指令写入指令寄存器,接着写入3个地址(一个列地址和2个行地址)来启动。一旦页读指令被器件锁存,下面的页操作就不需要再重复写入指令了。
写入指令和地址后,处理器可以通过对信号线R//B的分析来判断该才作是否完成。
外部控制器可以再以50ns为周期的连续/RE脉冲信号的控制下,从I/O口依次读出数据
备用区域的从512到527地址的数据,可以通过读方式2指令进行指令进行读取(命令为50h)。地址A0~A3设置了备用区域的起始地址,A4~A7被忽略掉
时序要求:
写地址、数据、命令时,nCE、nWE信号必须为低电平,它们在nWE信号的上升沿被锁存。命令锁存使能信号CLE和地址锁存信号ALE用来区分I/O引脚上传输的是命令还是地址。
寻址方式:
的寻址方式和的组织方式紧密相关。的数据以的方式保存在,一个中只能存储一个。这些以个或者个为单位,连成,形成,这就是的数据宽度。
这些会再组成,典型情况下:通常是或者。然后,每个形成一个,。其中,前为数据区,后存放数据校验码等,因此习惯上人们称有个字节,每个有;
现在在一些大容量的存贮设备中也采用以下配置:或;;;同上:,人们习惯称一页含个字节,一个含有个页,容量为;
是中最大的操作单元,擦除可以按照或为单位完成,而编程读取是按照为单位完成的
所以,按照这样的组织方式可以形成所谓的三类地址:
首先,必须清楚一点,对于来讲,地址和命令只能在上传递,数据宽度可以是位或者位,但是,对于的,只用于传递数据。
清楚了这一点,我们就可以开始分析的寻址方式了。
以总容量的器件为例:
用户数据保存在中。
需要来表示,对于系列的,这被分成和各自的访问由所谓的命令来选择,也就是选择了的高低。因此就是,就是所谓的。
个需要来表示,占用,即该在块内的相对地址。
的地址是由以上的来表示,例如的,共,因此,需要个来表示,即,如果是的的,共个,则用表示。
的地址表示为:
|& Page Address in block&
|& half page pointer |
&Column Address
地址传送顺序是。
例如一个地址:
&&&&&& & 1010& 1010& 0101 &0101 &1010 &1010
由于地址只能在上传递,因此,必须采用移位的方式进行。
例如,对于的,地址范围是,只要是这个范围内的数值表示的地址都是有效的。
第步是传递,就是,不需移位即可传递到上,而即是由操作指令决定的,即指令决定在哪个上进行读写,而真正的的值是的。
第步就是将右移位,将传到上
第步将放到上
第步需要将放到上
因此,整个地址传递过程需要步才能完成,即。
如果的容量是以下,那么,最高位只到,因此寻址只需要步。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:33657次
排名:千里之外
转载:333篇
(20)(57)(38)(34)(40)(38)(14)(38)(20)(34)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix' 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
garfield系列处理器的nand控制器设计
下载积分:2000
内容提示:garfield系列处理器的nand控制器设计
文档格式:PDF|
浏览次数:1|
上传日期: 18:49:28|
文档星级:
全文阅读已结束,如果下载本文需要使用
 2000 积分
下载此文档
该用户还上传了这些文档
garfield系列处理器的nand控制器设计
关注微信公众号}

我要回帖

更多关于 nand控制器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信