Linux SPI FLASH DRIVER

来源:互联网 发布:淘宝banner模特素材 编辑:程序博客网 时间:2024/05/20 01:12

 

昨天刚刚把spi flash driver调通,今天准备写一些东西做为这么一段时间对spi flash driver的一种总结,和备份吧。

 

分三个部分讲:

1、  mtd 总体框架。

2、  spi 的总体框架。

3、  数据传输的流程。

 

1、  mtd 总体框架

mtdMemory Technology Device)是linux专门为linux移动存储设备设计的一套框架,方便程序员开发。他主要他为四个层次依次为:设备节点、MTD设备层、MTD原始设备层和硬件驱动层。

A、Flash硬件驱动层:硬件驱动层负责驱动Flash硬件。

B、MTD原始设备:原始设备层有两部分组成,一部分是MTD原始设备的通用代码,另一部分是各个特定的Flash的数据,例如分区。

C、MTD设备层:基于MTD原始设备,linux系统可以定义出MTD的块设备(主设备号31)和字符设备(设备号90)。

D、设备节点:通过mknod在/dev子目录下建立MTD字符设备节点(主设备号为90)和MTD块设备节点(主设备号为31),通过访问此设备节点即可访问MTD字符设备和块设备。

E、根文件系统:在Bootloader中将JFFS(或JFFS2)的文件系统映像jffs.image(或jffs2.img)烧到flash的某一个分区中,在/arch/arm/mach-your/arch.c文件的your_fixup函数中将该分区作为根文件系统挂载。 

F、文件系统:内核启动后,通过mount命令可以将flash中的其余分区作为文件系统挂载到mountpoint上。

 

         Mtd 的代码在kernel/driver/mtd/下面。

 

我们先看看文件夹

./ubi

./nand

./devices

./chips

./onenand

./lpddr

./tests

./maps

 

其中nand onenand下面关于nand flash driver硬件驱动层的一些代码,基中包括nand通用的代码和nand硬件相关的代码,具体可以看网上博文《基于MTDNAND驱动开发》一文。

Chips maps是合在一起使用的,chips层属于通用代码,它包涵了RAM/ROM/Flash chip drivers,而maps则是对具体的chip地址和驱动进行映射使硬件工作。

 

Device 里面则是很多特定的存储设备的driver,kernel解释为Self-contained MTD device drivers。里面的m25p80.c则是对大部spi flash 进行了支持。

 

在看mtd代码时主要需要关注这几个文件mtdcore.cmtdblock.cmtdchar.cmtdpart.c

它们几个是属于mtd中间的层的代码也就是上面所说的原始设备层。他们最主要的工作是接收能过add_mtd_device注册来的mtd设备,并为它们向系统注册block,char设备,并为这些设备管理分区,所以你会看到启动后的系统/dev文件夹里面有mtdblock0,mtd0ro,mtd0等设备节点。mtdblock0是块设备,mtd0ro是只读字符设备,mtd0可读写字符设备,这几个节点都指向同一个设备,只是功能不同而已,其中的0代表对mtd设备的编号。

2、  spi 的总体框架。

Spi 驱动在/driver/spi里面,我们看看里面的文件

里面虽然看似有很多文件其实你只需要关注的只有一个spi.c,他也是一个中间层的代码,创建spi总线和管理所有的spi设备,并他们提供接口函数。

需要关注在有三个注册函数:spi_register_masterspi_register_driver spi_register_board_info

他们三个是一个经典的三角关系,

spi_register_master spi注册一个controller, spi_register_board_infospi注册一个具体的设备,spicontroller通过(master->bus_num != bi->bus_num)进行匹配,如果匹配成功spi才会向系统spi总线注册一个spi device。这时候mtd m25p80.c 层那边会通过spi_register_driver向系统spi总线driver, m25p80.里面有个名叫m25p_ids的设备列表,如果匹配成功就可以下一部的相关操作了。

 

3、  数据传输的流程

不管你是通过mtdblock0,mtd0ro,mtd0中的那一种设备节点,它们最终都会调用mtd_readmtd_write来访问spi flash。下面以mtd_read为例来说明调用过程。

mtd_read -->mtd->write-->m25p80_write

到了m25p80.c之后, m25p80.c层会调用spi.c层的接口函数spi数据传输,主要有以下几个spi_syncspi_asyncspi_writespi_readspi_write_then_read等几个函数。数据会通过          struct spi_message          struct spi_transfer两个结构体对数据进行包装。

spi_transfer 会放在spi_message-> transfe里面上面几个接口函数最终都会调用master->transfer(spi, message);把数据传输到spi master里面,master收到数据后就可以通过操作寄存器和spi flash进行通信了。

 

 

在调试过程需要注意的是spi flash地址的宽度有3个字节和4字节的区分,m25p80.c会通过的m25p_addr2cmd进行地址的映射,在编写驱动的时候需要区分一下。

原创粉丝点击