Smart210学习记录----nand flash驱动
【详解】如何编写Linux下Nand Flash驱动 :http://www.cnblogs.com/linux-rookie/articles/3016990.html


当读写文件请求到来的时候,流程如下
1.通过vfs进入文件系统,
2.文件系统把文件读写转换为块设备读写,其中有运用算法对读写操作进行合并,排序等,最后把块设备读写放进队列
3.循环从队列中取出读写要求,然后用处理函数(blk_init_queue设置)进行处理。
这个函数就是连接上层(IO调度)跟底层(硬件操作)的桥梁,当我们调用add_mtd_partitions的时候,就建立了上下层的联系。
4.对不同的处理要求,调用不同的nand的底层处理函数
nand flash驱动代码:
#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/cpufreq.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 <plat/regs-nand.h>
#include <plat/nand.h> struct nand_flash_regs {
unsigned long NFCONF ;
unsigned long NFCONT ;
unsigned long NFCMMD ;
unsigned long NFADDR ;
unsigned long NFDATA ;
unsigned long NFMECCD0 ;
unsigned long NFMECCD1 ;
unsigned long NFSECCD ;
unsigned long NFSBLK ;
unsigned long NFEBLK ;
unsigned long NFSTAT ;
unsigned long NFECCERR0 ;
unsigned long NFECCERR1 ;
unsigned long NFMECC0 ;
unsigned long NFMECC1 ;
unsigned long NFSECC ;
unsigned long NFMLCBITPT ;
};
static unsigned long *MP0_3CON ; static struct nand_flash_regs *nand_regs;
static struct nand_chip *chip;
static struct mtd_info *nand_mtd;
static struct clk *nand_clk; //nand flash分区
static unsigned char nbparts = ;
struct mtd_partition mynand_partition_info[] = {
{
.name = "misc",
.offset = (*SZ_1K), /* for bootloader */
.size = (*SZ_1K),
.mask_flags = MTD_CAP_NANDFLASH,
},
{
.name = "recovery",
.offset = MTDPART_OFS_APPEND,
.size = (*SZ_1M),
},
{
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = (*SZ_1M),
},
{
.name = "ramdisk",
.offset = MTDPART_OFS_APPEND,
.size = (*SZ_1M),
},
{
.name = "system",
.offset = MTDPART_OFS_APPEND,
.size = (*SZ_1M),
},
{
.name = "cache",
.offset = MTDPART_OFS_APPEND,
.size = (*SZ_1M),
},
{
.name = "userdata",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
}
}; static void my_select_chip(struct mtd_info *mtd, int chip)
{
if(chip == -) {
/*取消片选*/
nand_regs->NFCONT |= << ;
}
else {
/*使能片选*/
nand_regs->NFCONT &= ~( << );
}
} static void my_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
{
if(ctrl & NAND_CLE) /*发命令*/
nand_regs->NFCMMD = dat;
if(ctrl & NAND_ALE) /*发地址*/
nand_regs->NFADDR = dat;
} static int my_dev_ready(struct mtd_info *mtd)
{
return nand_regs->NFSTAT & ( << );
} static int __init my_nand_init(void)
{
int err;
/*分配一个nand_chip结构体*/
chip = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
if(IS_ERR(chip)) {
printk(KERN_ALERT"nand_chip kzalloc error\n");
return -ENOMEM;
}
nand_regs = ioremap(0xB0E00000, sizeof(struct nand_flash_regs));
MP0_3CON = ioremap(0xE0200320, ); /*使能nand flash时钟*/
nand_clk = clk_get(NULL, "nand");
if(IS_ERR(nand_clk)) {
printk(KERN_ALERT"nand_clk clk_get error\n");
err = -ENOMEM;
goto clk_err;
}
clk_enable(nand_clk); /*设置结构体nand_chip*/
chip->select_chip = my_select_chip;
chip->cmd_ctrl = my_cmd_ctrl;
chip->dev_ready = my_dev_ready;
chip->IO_ADDR_R = &nand_regs->NFDATA;
chip->IO_ADDR_W = &nand_regs->NFDATA;
chip->ecc.mode = NAND_ECC_SOFT; /*硬件设置*/ /*设置MP0_3CON寄存器*/
*MP0_3CON = 0x22222222;
/*设置时序*/
#define TACLS 1
#define TWRPH0 1
#define TWRPH1 1
nand_regs->NFCONF |= (TACLS << ) | (TWRPH0 << ) | (TWRPH1 << ); //1 = 5 address cycle ,其他默认
nand_regs->NFCONF |= << ; //1 = Force nRCS[0] to High (Disable chip select)
//1 = Enable NAND Flash Controller
nand_regs->NFCONT |= ( << ) | ( << ); /*使用nand_chip : nand_sacn*/
nand_mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
if(IS_ERR(nand_mtd)) {
printk(KERN_ALERT"nand_mtd kzalloc error\n");
return -ENOMEM;
} nand_mtd->owner = THIS_MODULE;
nand_mtd->priv = chip; nand_scan(nand_mtd, ); /*添加分区*/
err = mtd_device_register(nand_mtd, mynand_partition_info, nbparts);
if(!err) {
printk(KERN_ALERT"add_mtd_partitions error\n");
return -EINVAL;
} return ; clk_err:
kfree(chip);
return err;
} static void __exit my_nand_exit(void)
{
mtd_device_unregister(nand_mtd);
iounmap(nand_regs);
iounmap(MP0_3CON);
kfree(nand_mtd);
kfree(chip);
} module_init(my_nand_init);
module_exit(my_nand_exit);
MODULE_LICENSE("GPL");
Smart210学习记录----nand flash驱动的更多相关文章
- Smart210学习记录------nor flash驱动
nor flash驱动与nand flash驱动的差别不大,只是设置不同的结构体而已,, nor flash驱动代码: #include <linux/module.h> #include ...
- Smart210学习记录-----Linux i2c驱动
一:Linux i2c子系统简介: 1.Linux 的 I2C 体系结构分为 3 个组成部分: (1) I2C 核心. I2C 核心提供了 I2C 总线驱动和设备驱动的注册.注销方法,I2C 通信方法 ...
- Smart210学习记录------linux串口驱动
转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=27025492&id=327609 一.核心数据结构 串口驱动有 ...
- Smart210学习记录-------Linux设备驱动结构
cdev结构体 1 struct cdev { 2 struct kobject kobj; /* 内嵌的 kobject 对象 */ 3 struct module *owner; /*所属模块*/ ...
- Nand Flash驱动(实现初始化以及读操作)
简单制作一个Nand Flash驱动(只需要初始化Flash以及读Flash) 打开2440芯片手册,K9F2G08U0M芯片手册(因为2440中Nand Flash是用的256MB(2Gb)内存,8 ...
- 如何编写linux下nand flash驱动-2
[Nand Flash引脚(Pin)的说明] 图3.Nand Flash引脚功能说明 上图是常见的Nand Flash所拥有的引脚(Pin)所对应的功能,简单翻译如下: 1. I/O0 ~ ...
- 十八、Nand Flash驱动和Nor Flash驱动
在读者学习本章之前,最好了解Nand Flash读写过程和操作,可以参考:Nand Flash裸机操作. 一开始想在本章写eMMC框架和设备驱动,但是没有找到关于eMMC设备驱动具体写法,所以本章仍继 ...
- linux2.6.30.4内核移植(2)——Nand Flash驱动移植
内核源码:linux2.6.30.4 交叉编译工具:3.4.5 移植linux内核至:TQ2440 工作基础:http://www.cnblogs.com/nufangrensheng/p/36696 ...
- linux下Pl353 NAND Flash驱动分析
linux的NAND Flash驱动位于drivers/mtd/nand子文件夹下: nand_base.c-->定义通用的nand flash基本操作函数,如读写page,可自己重写这些函数 ...
随机推荐
- [问题2014A05] 复旦高等代数 I(14级)每周一题(第七教学周)
[问题2014A05] (1) 设 \(x_1,x_2\cdots,x_n,x\) 都是未定元, \(s_k=x_1^k+x_2^k+\cdots+x_n^k\,(k\geq 1)\), \(s_0 ...
- 怎样在excel中添加下拉列表框
用excel2013打开要编辑的工作表,例子是一个班级名单,可以看到政治面貌目前还没有填写 接着我们找一个空白处,依次写入政治面貌的可能选项: 群众.共青团员 然后选中“政治面貌”这一列,点击 ...
- 程序源系统与当前系统不一致:Carry out repairs in non-original systems only if urgent
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- WebClient上传音频文件
//WebClient上传音频文件 public string UploadVoice(string fileNamePath) { Voice model=new Voice(); string s ...
- js函数、变量提升(hoisting)
其实我只是想复习下变量提升的,然后看到了函数提升,然后再看到了函数声明.函数表达式. 有必要怀着敬仰之心提及园子里的TOM大叔的解密命名函数表达式,不愧是大叔,好好地脑补了下基础知识. 在ECMASc ...
- Linux_命令_积累
1.ps 查看进程状态 ZC: "ps -a" 和 "ps a" 有区别... (具体查看 "man ps") 1.1.ps aux 1.2 ...
- python decorator的理解
一.decorator的作用 装饰器本质上是一个Python函数,可以让其他函数在不做任何代码变动的前提下增加额外功能. 装饰器的返回值也是一个函数对象.python里函数也是对象. 它经常用于有切面 ...
- python的class的__str__()和__repr__()函数
repr(object) 返回一个可以用来表示对象的可打印字符串首先,尝试生成这样一个字符串,将其传给 eval()可重新生成同样的对象 否则,生成用尖括号包住的字符串,包含类型名和额外的信息(比如地 ...
- OpenGL的glTexImage2D()与gluBuild2DMipmaps()的使用方法及区别
OpenGL的glTexImage2D()与gluBuild2DMipmaps()的使用方法及区别 说明:两者的都是生成纹理,即:将载入的位图文件(*.bmp)转换成纹理贴图. 1.glTexImag ...
- django template
一.模板基本元素 1.例子程序 1)urls.py中新增部分 from django.conf.urls import patterns, url, include urlpatterns = pat ...