块设备驱动程序之nandflash——基本框架

发布者:Meilin8888最新更新时间:2016-12-04 来源: eefocus关键字:块设备驱动  nandflash  基本框架 手机看文章 扫描二维码
随时随地手机看文章

我们先查看内核的启动信息,以搞清楚从哪个文件着手来分析:


S3C24XX NAND Driver, (c) 2004 Simtec Electronics

s3c2440-nand s3c2440-nand: Tacls=3, 30ns Twrph0=7 70ns, Twrph1=3 30ns

NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)

Scanning device for bad blocks

Bad eraseblock 408 at 0x03300000

Bad eraseblock 441 at 0x03720000

Bad eraseblock 804 at 0x06480000

Bad eraseblock 1155 at 0x09060000

Bad eraseblock 1236 at 0x09a80000

Creating 4 MTD partitions on "NAND 256MiB 3,3V 8-bit":

0x00000000-0x00040000 : "bootloader"

0x00040000-0x00060000 : "params"

0x00060000-0x00260000 : "kernel"

0x00260000-0x10000000 : "root"


我们来搜索:S3C24XX NAND Driver

结果我们在drivers\mtd\nand\s3c2410.c文件里发现了打印这句话的函数:

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,

},

};

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);

}

我们看到了,nandflash采用的是平台总线设备机制,当发现名字是s3c2440-nand的设备的时候,就会调用probe函数,那么我们就从probe函数入手了:

s3c24xx_nand_probe

          s3c2410_nand_inithw(info, pdev);//初始化硬件

          s3c2410_nand_init_chip(info, nmtd, sets);//初始化芯片,这里设置了chip的一些信息

          nand_scan(&nmtd->mtd, (sets) ? sets->nr_chips : 1);//扫描芯片

                    nand_scan_ident(struct mtd_info *mtd, int maxchips)

                              nand_set_defaults(chip, busw);//设置默认函数

                              nand_get_flash_type(mtd, chip, busw, &nand_maf_id);//获取nandflash类型

                                        chip->select_chip(mtd, 0);//选中芯片

                                        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);//发出读ID的命令,NAND_CMD_READID为90h

                                        *maf_id = chip->read_byte(mtd);//读厂家ID

                                          dev_id = chip->read_byte(mtd);//读设备ID

                                  for (i = 0; nand_flash_ids[i].name != NULL; i++) //根据设备id在nand_flash_ids[i]数组中找到其类型

                                          {

                                      if (dev_id == nand_flash_ids[i].id) 

                                                     {

                                     type =  &nand_flash_ids[i];

                                     break;

                                       }

                                   }

                    nand_scan_tail(mtd);//这里设置了读写和擦除函数

                              mtd->erase = nand_erase;

                              mtd->read = nand_read;

                              mtd->write = nand_write;

          s3c2410_nand_add_partition(info, nmtd, sets);//添加分区

                    add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions);

                              add_mtd_device(&mtd->mtd);

                                list_for_each(this, &mtd_notifiers) //详见注释1

                                        {

                    struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);

                    not->add(mtd);

                   }

注释1:

list_for_each(this, &mtd_notifiers)

{

struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);

not->add(mtd);

}

首先我们要搞清楚这个宏:list_entry(this, struct mtd_notifier, list);它会返回一个指向mtd_notifier结构体的指针

这样我们就明白了,我们需要知道在哪里定义了mtd_notifier这个东西,这样才能知道它的成员add函数。我们发现:

void register_mtd_user (struct mtd_notifier *new)

{

         ..........................................................

list_add(&new->list, &mtd_notifiers);

        ...........................................................

}

那么是谁调用了 register_mtd_use 函数呢?我们发现:

drivers\mtd\Mtd_blkdevs.c和drivers\mtd\Mtdchar.c文件里面都调用了这个函数,这两个文件一个对应字符设备一个对应块设备,这也说明了nandflash既可以作为字符设备,也可以作为块设备。我们先进入字符设备看看吧:

很快我们发现了add函数的定义:

static void mtd_notify_add(struct mtd_info* mtd)

{

if (!mtd)

return;

class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),NULL, "mtd%d", mtd->index);//创建设备节点

class_device_create(mtd_class, NULL,MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),NULL, "mtd%dro", mtd->index);//创建只读设备节点

}

我们有必要分析一下这个文件:

register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops);//注册字符设备

class_create(THIS_MODULE, "mtd");//创建类,但是并没有在类下创建设备节点哦,这个节点要在适当的时候才来创建

mtd_notify_add(struct mtd_info* mtd);


我们再来看一下块设备驱动的吧:

很快我们就发下了add函数的定义:

static void blktrans_notify_add(struct mtd_info *mtd)

{

struct list_head *this;

if (mtd->type == MTD_ABSENT)

 return;

list_for_each(this, &blktrans_majors) {

 struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);

 tr->add_mtd(tr, mtd);

}

}

不过我们好像还得继续向上搜寻,我们要看一看是谁设置了blktrans_majors:

int register_mtd_blktrans(struct mtd_blktrans_ops *tr)

{

        ..........................................................

        list_add(&tr->list, &blktrans_majors);

         ..........................................................

}

那么我们还要看看register_mtd_blktrans这个函数在哪里调用:

我们在drivers\mtd\Mtdblock.c文件里面发现了调用:

很快我们找到了add函数的定义:
mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)

         add_mtd_blktrans_dev(dev);

                        alloc_disk(1 << tr->part_bits);//申请磁盘,一下就可以看出和我们上节课编写的驱动程序挂钩了哦!

                        gd->queue = tr->blkcore_priv->rq;//设置队列

                        add_disk;//注册磁盘

针对上面的分析,我们在这里整理一下,首先来说一说将nandflash当作块设备来用的时候,其工作流程:

我们其实是分成了几个层次的,一个是块设备,我们在之前已经知道了,应用程序对块设备的读写请求被放放入队列里面,也就是说块设备对请求作了优化。而我们从s3c2410_nand_add_partition函数分析出来,mtdblock_add_mtd里面注册了这个队列,那么请求就可以放在这个队列里面,并且这个函数里面还分配的磁盘并且注册了磁盘。下面还差一步,那就是对硬件的操作,它在哪里呢?它就在nand_scan旗下的函数里面实现,里面定义了一些读写函数以及擦除函数,可以对硬件进行操作。其实这个框架和我们之前用内存模拟磁盘的框架式一致的,不过这里比较复杂,而且用了分层的概念。

不过这里面有几个结构体我们还是要说一下的:

struct nand_chip:用于描述芯片参数

struct mtd_info:定义了大量的MTD设备信息以及操作函数

关于字符设备驱动程序就比较简单了:

在nand_scan旗下的函数里面完成了注册,并设置了操作函数,那样就可以对nandflash进行操作了。


关键字:块设备驱动  nandflash  基本框架 引用地址:块设备驱动程序之nandflash——基本框架

上一篇:DMA通道的使用
下一篇:使用Jtag烧写uboot,以及bootdelay=0的解决办法

推荐阅读最新更新时间:2024-03-16 15:23

s3c2440裸机-nandflash编程(一. nandflash原理及结构简介)
1.nandflash的原理图如下: 引脚属性见下表: 引脚名称 引脚功能 IO0~IO7 数据输入输出(命令、地址、数据共用数据总线) CLE 命令使能 ALE 地址使能 /CE 芯片使能(片选) /RE 读使能 /WE 写使能 R/B 就绪/忙输出信号(低电平表示操作还在进行中,高电平表示操作完成) 2.nandflash内部存储结构 nandflash内部存储结构如下: 我们常见的Nand Flash,内部只有一个chip,每个chip只有一个plane。但也有些复杂的,容量更大的Nand Flash,内部有多个chip,每个chip有多个plane,这类的Nand Flash,其实就是多了一
[单片机]
s3c2440裸机-<font color='red'>nandflash</font>编程(一. <font color='red'>nandflash</font>原理及结构简介)
一步步写STM32 OS【四】OS基本框架
一、上篇回顾 上一篇文章中,我们完成了两个任务使用PendSV实现了互相切换的功能,下面我们接着其思路往下做。这次我们完成OS基本框架,即实现一个非抢占式(已经调度的进程执行完成,然后根据优先级调度等待的进程)的任务调度系统,至于抢占式的,就留给大家思考了。上次代码中Task_Switch实现了两个任务的切换,代码如下: void Task_Switch() { if(g_OS_Tcb_CurP == &TCB_1) g_OS_Tcb_HighRdyP=&TCB_2; else g_OS_Tcb_HighRdyP=&TCB_1; OSCtxSw(); } 我们把要切换任务指针付给跟_OS_Tcb_High
[单片机]
一步步写STM32 OS【四】OS<font color='red'>基本</font><font color='red'>框架</font>
S3C2410扩展NandFlash
1. NandFlash接口电路 2. NandFlash接口信号 * NandFlash接口信号较少; * 数据宽度只有8Bit,没有地址总线。地址和数据总线复用,串行读取; 信号名称 信号描述 IO 数据总线 CE# 片选信号(Chip Select),低电平有效 WE# 写有效(Write Enable),低电平表示当前总线操作是写操作 RE# 读有效(Read Enable),低电平表示当前总线操作是读操作 CLE 命令锁存(Command Latch Enable)信号,写
[单片机]
S3C2440裸机------NandFlash操作原理
1.Nandflash操作原理 下图是原理图中NandFlash和S3C2440的连接图, 问1. 原理图上NAND FLASH和S3C2440之间只有数据线, 怎么传输地址? 答1.在DATA0~DATA7上既传输数据,又传输地址 当ALE为高电平时传输的是地址, 问2. 从NAND FLASH芯片手册可知,要操作NAND FLASH需要先发出命令 怎么传入命令? 答2.在DATA0~DATA7上既传输数据,又传输地址,也传输命令 当ALE为高电平时传输的是地址, 当CLE为高电平时传输的是命令 当ALE和CLE都为低电平时传输的是数据 问3. 数据线既接到NAND FLASH,也
[单片机]
S3C2440裸机------<font color='red'>NandFlash</font>操作原理
S3C2440 设备驱动框架详细分析
本节目的: 通过分析2.6内核下的块设备驱动框架,知道如何来写驱动 1、之前我们学的都是字符设备驱动,先来回忆一下 字符设备驱动: 当我们的应用层读写(read()/write())字符设备驱动时,是按字节/字符来读写数据的,期间没有任何缓存区,因为数据量小,不能随机读取数据,例如:按键、LED、鼠标、键盘等。 2、接下来本届开始学习块设备驱动 块设备: 块设备是i/o设备中的一类,当我们的应用层对该设备读写时,是按扇区大小来读写数据,若读写的数据小于扇区的大小,就会需要缓存区,可以随机读写设备的任意位置处的数据,例如 普通文件(*txt,*.c等),硬盘,U盘,SD卡 3、块设备结构: 段(S
[单片机]
S3C2440 <font color='red'>块</font><font color='red'>设备驱动</font>之<font color='red'>框架</font>详细分析
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved