驱动09.nand flash
1 nand flash的操作
目的:读地址A的数据,把数据B写到地址A。
问1. 原理图上NAND FLASH和S3C2440之间只有数据线,怎么传输地址?
答1.在DATA0~DATA7上既传输数据,又传输地址,当ALE为高电平时传输的是地址。
问2. 从NAND FLASH芯片手册可知,要操作NAND FLASH需要先发出命令
怎么传入命令?
答2.在DATA0~DATA7上既传输数据,又传输地址,也传输命令
当ALE为高电平时传输的是地址,
当CLE为高电平时传输的是命令
当ALE和CLE都为低电平时传输的是数据
问3. 数据线既接到NAND FLASH,也接到NOR FLASH,还接到SDRAM、DM9000等等,那么怎么避免干扰?
答3. 这些设备,要访问之必须"选中",没有选中的芯片不会工作,相当于没接一样。(内存控制器)
问4. 假设烧写NAND FLASH,把命令、地址、数据发给它之后,
NAND FLASH肯定不可能瞬间完成烧写的,怎么判断烧写完成?
答4. 通过状态引脚RnB来判断:它为高电平表示就绪,它为低电平表示正忙
问5. 怎么操作NAND FLASH呢?
答5. 根据NAND FLASH的芯片手册,一般的过程是:
发出命令
发出地址
发出数据/读数据
2 分析nand flash的启动过程
搜"S3C24XX NAND Driver"
S3c2410.c (drivers\mtd\nand)
s3c2410_nand_inithw
s3c2410_nand_init_chip
nand_scan // 根据nand_chip的底层操作函数识别NAND FLASH,构造mtd_info
nand_scan_ident
nand_set_defaults
if (!chip->select_chip)
chip->select_chip = nand_select_chip; // 默认值不适用
if (chip->cmdfunc == NULL)
chip->cmdfunc = nand_command;
chip->cmd_ctrl(mtd, command, ctrl);
if (!chip->read_byte)
chip->read_byte = nand_read_byte;
readb(chip->IO_ADDR_R);
if (chip->waitfunc == NULL)
chip->waitfunc = nand_wait;
chip->dev_ready
nand_get_flash_type
chip->select_chip(mtd, 0);
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
*maf_id = chip->read_byte(mtd);
dev_id = chip->read_byte(mtd);
nand_scan_tail
mtd->erase = nand_erase;
mtd->read = nand_read;
mtd->write = nand_write;
s3c2410_nand_add_partition
add_mtd_partitions
add_mtd_device
list_for_each(this, &mtd_notifiers) { // 问. mtd_notifiers在哪设置
// 答. drivers/mtd/mtdchar.c,mtd_blkdev.c调用register_mtd_user
struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
not->add(mtd);
// mtd_notify_add 和 blktrans_notify_add
先看字符设备的mtd_notify_add
class_device_create
class_device_create
再看块设备的blktrans_notify_add
list_for_each(this, &blktrans_majors) { // 问. blktrans_majors在哪设置
// 答. drivers\mtd\mdblock.c或mtdblock_ro.c register_mtd_blktrans
struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
tr->add_mtd(tr, mtd);
mtdblock_add_mtd (drivers\mtd\mdblock.c)
add_mtd_blktrans_dev
alloc_disk
gd->queue = tr->blkcore_priv->rq; // tr->blkcore_priv->rq = blk_init_queue(mtd_blktrans_request, &tr->blkcore_priv->queue_lock);
add_disk
3 nand flash驱动程序框架
(1)分配一个nand_chip/mtd_info结构体
(2)设置
(3)硬件相关的操作
(4)使用nand_scan/add_mtd_partitions
4 写代码
参考drivers\mtd\nand\s3c2410.c
- /*参考drivers\mtd\nand\at91_nand.c*/
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/init.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/ioport.h>
- #include <linux/platform_device.h>
- #include <linux/delay.h>
- #include <linux/err.h>
- #include <linux/slab.h>
- #include <linux/clk.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/nand_ecc.h>
- #include <linux/mtd/partitions.h>
- #include <asm/io.h>
- #include <asm/arch/regs-nand.h>
- #include <asm/arch/nand.h>
- struct s3c_nand_regs {
- unsigned long nfconf ;
- unsigned long nfcont ;
- unsigned long nfcmd ;
- unsigned long nfaddr ;
- unsigned long nfdata ;
- unsigned long nfeccd0 ;
- unsigned long nfeccd1 ;
- unsigned long nfeccd ;
- unsigned long nfstat ;
- unsigned long nfestat0;
- unsigned long nfestat1;
- unsigned long nfmecc0 ;
- unsigned long nfmecc1 ;
- unsigned long nfsecc ;
- unsigned long nfsblk ;
- unsigned long nfeblk ;
- };
- static struct mtd_info *s3c_mtd;
- static struct nand_chip *s3c_nand;
- static struct mtd_partition s3c_nand_parts[] = {
- [] = {
- .name = "bootloader",
- .size = 0x00040000,
- .offset = ,
- },
- [] = {
- .name = "params",
- .offset = MTDPART_OFS_APPEND,
- .size = 0x00020000,
- },
- [] = {
- .name = "kernel",
- .offset = MTDPART_OFS_APPEND,
- .size = 0x00200000,
- },
- [] = {
- .name = "root",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL,
- }
- };
- static void s3c2440_select_chip(struct mtd_info *mtd, int chipnr)
- {
- if (chipnr == -)
- {
- /* 取消选中: NFCONT[1]设为1 */
- s3c_nand_regs->nfcont |= (<<);
- }
- else
- {
- /* 选中: NFCONT[1]设为0 */
- s3c_nand_regs->nfcont &= ~(<<);
- }
- }
- static void s3c2440_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
- {
- if (ctrl & NAND_CLE)
- {
- /* 发命令: NFCMMD=dat */
- s3c_nand_regs->nfcmd = dat;
- }
- else
- {
- /* 发地址: NFADDR=dat */
- s3c_nand_regs->nfaddr = dat;
- }
- }
- static int s3c2440_dev_ready(struct mtd_info *mtd)
- {
- return (s3c_nand_regs->nfstat & (<<));
- }
- static int s3c_nand_init(void)
- {
- struct clk *clk;
- s3c_nand = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
- s3c_nand_regs = ioremap(0x4E000000, sizeof(struct s3c_nand_regs));
- s3c_nand->select_chip = s3c2440_select_chip;
- s3c_nand->cmd_ctrl = s3c2440_cmd_ctrl;
- s3c_nand->IO_ADDR_R = &s3c_nand_regs->nfdata;
- s3c_nand->IO_ADDR_W = &s3c_nand_regs->nfdata;
- s3c_nand->dev_ready = s3c2440_dev_ready;
- s3c_nand->ecc.mode = NAND_ECC_SOFT;//enable ECC
- clk = clk_get(NULL, "nand");
- clk_enable(clk);
- #define TACLS 0
- #define TWRPH0 1
- #define TWRPH1 0
- s3c_nand_regs->nfconf = (TACLS<<) | (TWRPH0<<) | (TWRPH1<<);
- s3c_nand_regs->nfcont = (<<) | (<<);
- s3c_mtd = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
- s3c_mtd->owner = THIS_MODULE;
- s3c_mtd->priv = s3c_nand;
- nand_scan(s3c_mtd, );//识别nand falsh,构造mtd_info
- add_mtd_partitions(s3c_mtd, s3c_nand_parts,);
- return ;
- }
- static void s3c_nand_exit(void)
- {
- del_mtd_partitions(s3c_mtd);
- kfree(s3c_mtd);
- iounmap(s3c_nand_regs);
- kfree(s3c_nand);
- }
- module_init(s3c_nand_init);
- module_exit(s3c_nand_exit);
- MODULE_LICENSE("GPL");
s3c_nand.c
驱动09.nand flash的更多相关文章
- STM32学习笔记——FSMC 驱动大容量NAND FLASH [复制链接]
本文原创于观海听涛,原作者版权所有,转载请注明出处. 近几天开发项目需要用到STM32驱动NAND FLASH,但由于开发板例程以及固件库是用于小页(512B),我要用到的FLASH为1G bit的大 ...
- 块设备驱动之NAND FLASH驱动程序
转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/25240909 一.框架总结 watermark/2/text/aHR0cDov ...
- 十八、Nand Flash驱动和Nor Flash驱动
在读者学习本章之前,最好了解Nand Flash读写过程和操作,可以参考:Nand Flash裸机操作. 一开始想在本章写eMMC框架和设备驱动,但是没有找到关于eMMC设备驱动具体写法,所以本章仍继 ...
- linux nand flash常用命令
使用命令前用cat /proc/mtd 查看一下mtdchar字符设备:或者用ls -l /dev/mtd*#cat /proc/mtddev: size erasesize namemt ...
- 嵌入式Linux驱动学习之路(二十三)NAND FLASH驱动程序
NAND FLASH是一个存储芯片. 在芯片上的DATA0-DATA7上既能传输数据也能传输地址. 当ALE为高电平时传输的是地址. 当CLE为高电平时传输的是命令. 当ALE和CLE都为低电平时传输 ...
- Smart210学习记录----nand flash驱动
[详解]如何编写Linux下Nand Flash驱动 :http://www.cnblogs.com/linux-rookie/articles/3016990.html 当读写文件请求到来的时候, ...
- nuc900 nand flash mtd 驱动
nuc900 nand flash mtd 驱动,请参考! /* * Copyright © 2009 Nuvoton technology corporation. * * Wan ZongShun ...
- Tiny6410之NAND FLASH驱动
一.NAND FLASH的特点 S3C6410的NAND FLASH控制器有如下特点 1.自导入模式:复位后,引导代码被送入到8KB的STEPPINGSTONE中,引导代码移动完毕,引导代码将在STE ...
- Nand Flash驱动(实现初始化以及读操作)
简单制作一个Nand Flash驱动(只需要初始化Flash以及读Flash) 打开2440芯片手册,K9F2G08U0M芯片手册(因为2440中Nand Flash是用的256MB(2Gb)内存,8 ...
随机推荐
- 解决Ubuntu Adobe Reader 菜单栏空白
sudo gedit /usr/local/share/applications/AdobeReader.desktop将 ”Exec=acroread“ 用 ”Exec=env UBUNTU_ME ...
- HDOJ 5063 Operation the Sequence
注意到查询次数不超过50次,那么能够从查询位置逆回去操作,就能够发现它在最初序列的位置,再逆回去就可以求得当前查询的值,对于一组数据复杂度约为O(50*n). Operation the Sequen ...
- Restful WebApi开发实践
随笔分类 - Restful WebApi开发实践 C#对WebApi数据操作 摘要: ## 目标简化并统一程序获取WebApi对应实体数据的过程,方便对实体进行扩充.原理就是数据服务使用反射发现 ...
- CSS绘制无图片的气泡对话框
<div class="qipao_contianer"> <div class="qipao_content yj3" ...
- Asp.Net异步编程
Asp.Net异步编程-使用了异步,性能就提升了吗? Asp.Net异步编程 写在前面的话,很久没有写Blog了,不对,其实一致就没有怎么写过.今天有空,我也来写一篇Blog 随着.Net4.5的推出 ...
- Matlab中如何用命令方式保存图像?
命令很简单,例如下面这个代码将当前图像保存到F1.emf文件中,保存格式为emf saveas(gcf,'F.emf','emf'); 当然了,也可以保存为jpg格式,修改为: saveas(gcf, ...
- 【值得收藏】数据分析和可视化软件IDL的学习资料汇编【可免费下载】
IDL学习教程 IDL 是一种数据分析和图像化应用程序及编程语言,最初在七十年代后期用于帮助科学家分析火星探险卫星发回的数据.此后,IDL得到广泛运用,使用者日众.IDL能使用户可以迅速且方便地运用此 ...
- c# in deep 之对Linq表达式范围变量限制问题的一些解决办法
linq表达式的标准形式为from...where...select,其中from后面跟的就是范围变量.linq中范围变量需要是泛型的集合,假如我们想对ArrayList或Object[]进行处理,l ...
- 【ios开发】iOS App测试方案
之前IOS测试一半都是采用的Testflight,但是2014.2.19日以后,testflight已经不提供新注册的用户下载SDK了. 但是不用担心我们还可以采用其他几种方案. 1)Ubertest ...
- 【转】Objc的底层并发API
本文由webfrogs译自objc.io,原文作者Daniel Eggert.转载请注明出处! 小引 本篇英文原文所发布的站点objc.io是一个专门为iOS和OS X开发者提供的深入讨论技术的平台, ...