3 FLASH驱动程序开发
3.1 Linux系统下的驱动程序
Linux系统将所有的设备都看作具体的文件,通过文件系统对设备进行管理。所以在Linux架构中,和设备相关的处理分成两层:文件系统层和设备驱动层。设备驱动层用来屏蔽具体设备的细节,文件系统层向用户提供一组统一的接口。这种设备管理方法可以很好的实现设备无关性,使Linux系统可以随着外部设备的发展进行扩展,比如要添加一个设备,只要根据该硬件设备特性向文件系统提供一组接口,应用程序通过系统调用接口来访问设备。
Linux系统里将FLASH设备归属到MTD设备下管理,相对于常规块设备驱动程序,MTD设备驱动程序能更好的支持和管理闪存。具体讲,基于MTD的 FLAsH驱动程序,对上层可以很好的支持JFFS(针对NorFLASH)和YAFFS(针对NandFLASH)等文件系统,对下层FLASH的读写,擦除,坏块处理都能进行很好的管理,它在硬件设备和上层文件系统间提供一个抽象接口。
3.2 FLASH驱动程序开发流程
FLASH驱动程序有两种编程方式。一种是直接编程进内核(Kernel),另一种是编程成模块(Modules),如果编程进内核,会增加内核的大小,还要改动内核源文件,不能动态卸载,不利于调试,所以FLASH驱动编程采用模块化方式较好。
FLASH驱动开发流程要经过四步:模块化设计,编译,加载,调用验证。如图4所示。
3.2.1 驱动程序的模块化设计
构成FLASH驱动程序的所有子程序,要进行模块化设计,必须加入两个函数:入口函数module init()和出口函数module_exit()。在执行程序时module_init()会调用int_init cfi probe_init(void),负责初始化MTD芯片,同时这个函数还调用register_mtd_chip_driver(),将cfi_chipdrv加入至 MTD驱动器列表chip_drvs_list中。初始化成功返回0,否则返回负值。实现代码为:
另一个函数module_exit()执行时,会调用staticvoid_exit cfi_probe_exit(void),负责清除MTD芯片驱动工作。同时这个函数还调用unregister_mtd_chip_driver(),将cfi_chipdrv从MTD芯片驱动器列表chip_drvs_list中删除。实现代码为:
|
其中:-O指定代码优化的级别;-D内核模块必须按照特殊定义的参数进行编译,这些参数跟在选项-D后;MODULE通知头文件要给出适当的内核模块定义;-KERNEL-通知头文件形成的目标代码在内核态运行。得到的文件*.O就是一个FLASH驱动程序的目标文件,这样FLAsH驱动程序编译好。编译好的模块*.O放在/lib/roodules/2.4.18/misc下,然后用dep-mod-a使此模块成为可加载模块。 3.2.3 驱动程序的加载 加载模块要用到两个命令:insmod(加载),rmmod(卸载)。加载时,module_init()函数被调用,这个函数向系统设备表登记 FLAsH设备。卸载时,module_exit()函数被调用,它释放FLASH设备在系统设备表中占有的表项。注册成功后就可以用mknod命令将 FLASH设备映射为一个特别文件,其他程序使用FLASH设备时,只要对此文件进行操作就行。Linux在/dev目录中为每个设备建立了一个文件,用 ls-1命令列出函数返回值,若小于O,表示注册失败;否则表示注册成功。注册以后,Linux将FLAsH设备名与主、次设备号联系起来。当对 FLASH访问时,Linux通过请求访问FLASH设备名得到主、次设备号;然后把此访问发送到FLASH设备驱动,FLASH驱动再根据次设备号调用不同的函数。 3.2.4 驱动程序的调用验证 模块加载到内核后,然后就要调用验证。在Linux根目录下有dev子目录,这里面是节点名,这些结点是通过mknod建立的,里面有MTD字符设备节点和MTD块设备节点,通过访问这些节点来访问设备驱动程序。Open一般是设备节点上的第一个操作,访问设备时其实就是系统调用open()函数,然后 open()函数打开设备准备进行I/O操作,该函数注册进mtd_fops结构中。 上面就是NorFLASH和NandFLASH驱动程序架构,具体开发驱动程序时,就要填充架构里的程序代码,来完成驱动程序。这个框架中有一个函数表,具体到Linux系统里,需要提供一个结构来向系统说明FLASH驱动程序所提供的一组入口点,这个结构就是fop函数表。 FLASH驱动程序运行时,向内核注册,告诉系统fop函数表是跟FLASH驱动程序相关联的。当用户去访问驱动程序时,系统就告诉文件系统的管理程序,调用fop函数表就可以,然后调用函数表里的函数,完成用户要求。当从设备来收发数据时,系统不是调用read(),write()这两个函数,fop结构里没这两个函数,而是要用到一个函数blk_init_queue(),这个函数向上注册了一个请求处理函数request,对FLASH设备的读取和发送数据,都是从请求队列发出一个请求,请求调用请求处理函数,由请求处理函数执行具体的读写操作。设计驱动程序90%工作来完成fop函数表及re- quest函数,10%完成驱动程序中的一些函数接口。完成了这些函数加上上面的FLASH驱动程序架构就构成了完整的FLASH驱动程序。
4 结 语 基于Samsung公司的s3c2410处理器平台,分析和设计NorFLASH和NandFLASH的接口和驱动,详细介绍两种FLASH的硬件结构、性能差异、读写时序、以及驱动开发。NorFLASH和NandFLASH因其在存储数据和程序以及性价比方面的优势,占据的存储器市场份额越来越多,并在嵌入式系统中得到广泛应用。
|