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,可自己重写这些函数 ...
随机推荐
- [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)
DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...
- 9----Lua中的面向对象
什么是面向对象? 使用对象.类.继承.封装.消息等基本概念来进行程序设计 面向对象最重要的两个概念就是:对象和类 对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位 一个对象由一组属性 ...
- 5----table类型
table类型是非常重要的Lua数据类型,也是Lua唯一能描述数据结构的类型 table类型可以很灵活的描述多种数据结构,其本身是基于键值对的形式存储数据的 字典结构 字典结构的table 的两种创建 ...
- Gitblit Go
1.Download the "Gitblit Go" package from the www.gitblit.com 2.UnZip the package 3.Open th ...
- Eclipse 修改API
真机调试时报错,提示application api 21,device api 10 Automatic Target Mode: Unable to detect device compatibil ...
- Less入门到上手——前端开发利器<二>深入了解
接着昨天的继续... ... 4.嵌套: HTML部分 <table> <tr> <th colspan="3">测试列表标题</th&g ...
- Ubuntu14.04安装redis和简单配置
1.前言 Redis是常用基于内存的Key-Value数据库,比Memcache更先进,支持多种数据结构,高效,快速.用Redis可以很轻松解决高并发的数据访问问题:做为时时监控信号处理也非常不错. ...
- MFC编程入门之十七(对话框:文件对话框)
上一讲介绍的是消息对话框,本节讲解文件对话框.文件对话框也是很常用的一类对话框. 文件对话框的分类 文件对话框分为打开文件对话框和保存文件对话框,相信大家在Windows系统中经常见到这两种文件对话框 ...
- windows下开启mysql远程访问
USE mysql;SELECT * FROM USER ; 直接修改user=root host=127.0.0.1为% FLUSH PRIVILEGES;
- USACO2016Splitting the Field分割牧场
Description FJ的N头奶牛分别位于他二维的牧场的不同位置.FJ想用一个矩形栅栏围住这些牛(牛可以在栅栏边上),并使这个栅栏尽可能小.这个栅栏的边与x轴或y轴平行.不幸的是,FJ上个季度的牛 ...