千锋嵌入式学院最专业的嵌入式培训机构设备驱动程序是介于硬件和嵌入式系统eCos内核之间的软件接口,是一种底层的、专用于某一硬件的软件组件。在eCos系统[1]中,设备驱动程序以包(Package)的形式存在,当需要使用该设备时,通过eCos环境配置工具把该设备驱动程序包加载到内核中,编译后生成一个库文件,用户使用时,只需要打开该设备,直接调用接口API函数即可。设备驱动程序的作用如图1所示[2]。千锋嵌入式学院最专业的嵌入式培训机构在eCos系统中一般把设备分为4类:字符设备、块设备、网络接口、其他设备。SPCE3200是凌阳公司推出的一款32位支持嵌入式系统处理器,其内部具有SD卡控制器,属于块设备类[3]。对SPCE3200内部的SD卡控制器必须编写驱动程序,以便完成SD卡的读写操作。下面将介绍具体实现过程,这里规定SD卡使用“/dev/sd”作为其名称。千锋嵌入式学院最专业的嵌入式培训机构在编写驱动程序前,首先需要为SD卡驱动建立其目录结构。eCos系统要求所有驱动程序均保存在/packages/devs目录下的对应子目录内,按照图2所示在eCos/packages/devs/sd/Spce3200目录下分别建立名为“cdl”、“include”、“current”3个目录,分别用于存放SD卡驱动所需的cdl文件、驱动程序头文件和源程序文件。千锋嵌入式学院最专业的嵌入式培训机构在cdl目录内,首先创建一个叫做“sd_spce3200.cdl”的文件。然后,在src目录内建立一个名为“sd_spce3200.c”驱动程序的源程序,并将名为“sd_card_driver_spce3200.c”的文件复制到src目录内,该文件是凌阳科技提供的针对SPCE3200内部SD卡控制器的基本操作程序。千锋嵌入式学院最专业的嵌入式培训机构组件定义语言CDL(ComponentDefinitionLanguage)是eCos组件框架的一个关键部分。eCos中所有的包都必须具有至少一个CDL脚本对其进行描述[4]。CDL脚本包含了该包中所有配置选项的详细信息,并提供了如何对该包进行编译的信息[5]。这里,在CDL文件的模板框架中添加关于SD卡配置项的代码如下:cdl_packageCYGPKG_DEVS_SD_SPCE3200{display'SDdriverforSPCE3200'include_dircyg/iocompilesd_card_driver_spce3200.ccompile-library=libextras.asd_spce3200.cdescription'SDdriverforSCORESPCE3200'cdl_componentCYGPKG_DEVS_SD_SPCE3200_OPTIONS{display'CompileOptions'千锋嵌入式学院最专业的嵌入式培训机构flavorrnoneno_definecdl_optionCYGDAT_DEVS_SD_SPCE3200_NAME{display'DevicenamefortheSDDriver'flavordatadefault_value{''/dev/sd''}description'Thisoptionspecifiesthenameofthesd-carddevice'}}}千锋嵌入式学院最专业的嵌入式培训机构配置好CDL文件后,便可编写设备I/O函数表宏以及设备表入口宏,分别如下:BLOCK_DEVIO_TABLE(sd_spce3200_handlers,//I/O函数表的标识sd_WriteSector,//SD卡写操作函数sd_ReadSector,//SD卡读操作函数NULL,//选择函数,SD卡驱动不需要支持sd_get_config,//读SD卡配置状态函数sd_set_config//SD卡配置函数);BLOCK_DEVTAB_ENTRY(sd_spce3200_device,//SD卡驱动入口标识千锋嵌入式学院最专业的嵌入式培训机构CYGDAT_DEVS_SD_SPCE3200_NAME,//SD卡驱动的名称,在cdl文件里定义NULL,//SD卡驱动不依赖于其他设备&sd_spce3200_handlers,//SD卡设备I/O函数表标识&SD_Initial,//SD卡初始化函数0,//SD卡查找函数0//SD卡驱动的私有指针);千锋嵌入式学院最专业的嵌入式培训机构接下来需要实现上面提到的几个接口函数,这些函数是上层访问硬件设备的唯一通道。在凌阳科技提供的sd_card_driver_spce3200.c文件中包含了SD卡初始化、读写操作等函数[6],它们分别为:SD卡初始化函数int__SDDrv_SDDrv_Initial__(void)、SD卡扇区写操作函数int_SDDrv_SDDrv_WriteSector_(unsignedintblock,unsignedintblocknum,unsignedchar*outaddr)、SD卡扇区读操作函数int_SDDrv_SDDrv_ReadSector_(unsignedintblock,unsignedintblocknum,unsignedchar*buf)。但这些函数都不是基于操作系统的,而是SD卡的基本操作函数。需要将它们封装成eCos操作系统下的驱动程序。这就需要用到凌阳科技提供的SD卡设备驱动接口函数,包括SD卡设备批量写操作函数sd_WriteSector()、SD卡设备批量读操作函数sd_ReadSector()、SD卡读设备配置状态函数sd_get_config()、千锋嵌入式学院最专业的嵌入式培训机构SD卡设备设置函数sd_set_config()[7]。完整的SD设备驱动源程序文件的代码如下://--------文件名:sd_spce3200.c------------////----------包含相关头文件-------------//#include#include#include#include#include#include#include#include#include#include千锋嵌入式学院最专业的嵌入式培训机构#include#include//-------------驱动函数实现--------------//staticboolsd_init(structcyg_devtab_entry*tab){boolInitResult=true;if(__SDDrv_SDDrv_Initial()==0InitResul=true;elseInitResult=false;returen(InitResult);}千锋嵌入式学院最专业的嵌入式培训机构staticintsd_WriteSector(void*disk,constvoid*buf_arg,cyg_uint32*blocks,cyg_uint32first_block){cyg_intret=ENOERR;ret=__SDDrv_SDDrv_WriteSector__(first_block,*blocks,(cyg_uint8*)buf_arg);(1)returnret;}staticintsd_ReadSector(void*disk,void*buf_arg,cyg_uint32*blocks,cyg_uint32first_block){cyg_int32ret=ENOERR;ret=__SDDrv_SDDrv_ReadSector__(first_block,*blocks,(cyg_uint8*)buf_arg);(1)returnret;}千锋嵌入式学院最专业的嵌入式培训机构staticCyg_ErrNosd_get_config(disk_channel*chan,cyg_uint32key,constvoid*buf,cyg_uint32*len){return-EINVAL;}staticCyg_ErrNosd_set_config(disk_channel*chan,cyg_uint32key,constvoid*buf,cyg_uint32*len){return-EINVAL;}//-------------设备I/O函数表-----------//(略,见前面)//----------设备表入口----------------//(略,见前面)千锋嵌入式学院最专业的嵌入式培训机构在ecos.db中的任意位置加如下程序段:packageCYGPKG_DEVS_SD_SPCE3200{alias{'SDsupportforScoreSPCE3200'}directorydevs/sd/score/spce3200scriptsd_spce3200.cdldescription'ThispackagecontainshardwaresupportfortheSDCardontheScoreSPCE3200EVBoard.'}千锋嵌入式学院最专业的嵌入式培训机构“devs/sd/score/spce3200”指示了SD卡设备驱动的路径,该路径是相对于/packages目录的[8]。此时打开eCos配置工具添加包时,就可以看见SD卡驱动程序组件包已经出现在eCos数据库中,如图3所示。点击“Add”加载到平台上并编译生成一个名为“CIGPRG_DEVS_SD_SPCE3200.ecc”的库文件,即SD卡驱动程序库文件。千锋嵌入式学院最专业的嵌入式培训机构至此,在嵌入式操作系统cCos中成功地创建了一个基于凌阳SPCE3200的SD卡驱动程序。有了该驱动程序,就能正常访问SD卡了。除了通过I/O组件访问硬件设备之外,eCos还提供了FA