参考内核中
driver/mtd/nand/s3c2410.c或者driver/mtd/nand/atmel_nand.c
先把头文件包含进去
我们来看看nand_scan_ident这里面做了什么事情
设置位数,因为我们的数据线只有8位所以这里选八位
设置默认函数
看看这个怎么设置的
如果没设置就用默认的,看看这个默认的函数我们能不能使用
这上面说-1是不选,其他值是某一个芯片
但是这里0的时候什么也没做,显然我们偏选的时候要把
要把这里的第一位设置为0
从这里看默认的函数不适合我们用,所以我们要设置这个函数,我们在默认的基础上看下别人怎么做的
然后自己写一个函数,框架如图
片选之后读了ID,我们来看看这个cmdfunc函数适不适用???
在默认的函数里面最终调用了这个函数来发命令
怎么构造这个函数
我们可以参考atmel的
根据这个我们改成下面这种框架
得到flash的类型
我们来看看nand_get_flash_type干了什么
从这里看出,即发命令又发0地址,为什么,我们前面试验过读ID嘛 发出0x90之后 还要发出0地址
然后读数据
假设我们也不提供这个,用一下默认的,看一下适不适用
它读这个io_addr_r地址,所以我们要设置这个地址
有读就有写
看一下写函数
我们需要提供IO_ADDR_W地址
判断状态勒,在电路原理图上就是读RnB引脚的状态
在内核里我们看一下默认的函数
我们需要写出这个函数
这个函数怎么写呢
这个寄存器的
这一位就可以知道状态
片选
所以最后我们半成品的代码如下
#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> static struct nand_chip *nand; static struct mtd_info *nand_mtd; static void gh_select_chip(struct mtd_info *mtd,int chipnr) { if(chipnr == -1) { //取消选中 将NFCONT[1] 设置为2 } else { //选中 NFCONT【1】设置为0 } } static void gh_cmd_ctrl(struct mtd_info *mtd,int cmd,unsigned int ctrl) { if (ctrl & NAND_CLE) //发命令 NFCMD寄存器 = cmd的值 else //发地址 NFADDR寄存器=cmd的值 } static int gh_dev_ready() { return "NFSTA的第0位"; } static int nand_init(void) { /*1.分配一个nand_chip结构体*/ nand = kzalloc(sizeof(struct nand_chip),GFP_KERNEL); /*2.设置*/ //设置nand_chip是给nand_scan_ident函数用的,如果不知道怎么设置,先看nand_scan_ident怎么使用*/ //它应该提供发命令,发地址,发数据,读数据,判断状态的功能 nand->select_chip = gh_select_chip; nand->cmd_ctrl =gh_cmd_ctrl; nand->dev_ready = gh_dev_ready; nand->IO_ADDR_R = "nfdata寄存器的虚拟地址"; nand->IO_ADDR_W = "NFDATA寄存器的虚拟地址"; /*3.使用*/ nand_mtd=kzalloc(sizeof(struct mtd_info),GFP_KERNEL); //将mtd_info与nandchip相联系起来 nand_mtd->owner = THIS_MODULE; nand_mtd->priv = nand; nand_scan_ident(nand_mtd,1,NULL);//第二个参数是最大芯片个数 nand_scan_tail(nand_mtd); return 0; } static void nand_exit(void) { } module_init(nand_init); module_exit(nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("EIGHT");
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。