1、概述
本文档主要介绍SylixOS中字符设备驱动框架,适用于在SylixOS集成开发环境下进行字符设备驱动开发的学习。
注:文中xxx是指具体设备名,编写对应驱动时,自行命名(如RTC、COMPASS等)。
2、SylixOS字符设备驱动简介
字符设备是指只能以字节为单位进行读写的设备,读取数据需按照先后顺序,不能随机读取设备内存中某一数据。常见的字符设备如:鼠标、键盘、串口等。
在SylixOS中,每个字符设备都会在/dev目录下对应一个设备文件,用户程序可通过设备文件(或设备节点)来使用驱动程序进行字符设备的读写、IO控制等操作。
3、SylixOS字符设备驱动框架
3.1字符设备驱动模型
在SylixOS中,使用PLW_xxx_DEV结构体来描述字符设备,该结构体由LW_DEV_HDR和PLW_xxx_FUNCS两个成员组成。其中,LW_DEV_HDR为设备头,包含设备管理链表、驱动程序索引号、设备名、设备类型、设备打开次数等,PLW_xxx_FUNCS是指对应设备的操作函数集(如设备打开、关闭、读写、IO控制等)。其字符设备驱动模型如图 3.1所示。
图 3.1字符设备驱动模型
以下对驱动模型中各模块进行解析。
3.2驱动函数安装
如图 3.1所示,步骤①~②,调用__xxxDrvInstall函数安装设备驱动函数,通过系统API函数API_IosDrvInstall注册设备驱动程序,包括设备创建、删除、打开、关闭、读写、IO控制等,该函数返回该设备的驱动函数索引号_G_ixxxDrvNum,用于创建设备时关联具体的设备操作函数集。具体流程如程序清单 3.1所示。
程序清单 3.1驱动函数安装
INT __xxxDrvInstall (VOID) { /* * 注册设备驱动程序,获取驱动程序索引号 */ _G_ixxxDrvNum = iosDrvInstall( __xxxCreate, /* 驱动程序中的创建函数 */ __xxxDelete, /* 驱动程序中的删除函数 */ __xxxOpen, /* 驱动程序中的打开函数 */ __xxxClose, /* 驱动程序中的关闭函数 */ __xxxRead, /* 驱动程序中的读函数 */ __xxxWrite, /* 驱动程序中的写函数 */ __xxxIoctl); /* 驱动程序中的IO控制函数 */ DRIVER_LICENSE(_G_ixxxDrvNum, "GPL->Ver 2.0"); DRIVER_AUTHOR(_G_ixxxDrvNum, "xx.xx.xx"); DRIVER_DESCRIPTION(_G_ixxxDrvNum, "hardware xxx."); return ((_G_ixxxDrvNum > 0) ? (ERROR_NONE) : (PX_ERROR)); }
3.3字符设备创建
如图 3.1所示,步骤③~④,调用函数__xxxDevCreate创建设备,传入参数为设备操作函数集__xxxDevFuncs,将该操作函数集赋给设备结构体成员PLW_xxx_FUNCS进行管理。然后通过系统API函数API_IosDevAddEx将该设备添加进内核设备管理链表,并将该设备与上小节中获取的设备驱动程序索引号相关联。具体流程如程序清单 3.2所示。
程序清单 3.2字符设备创建
INT __xxxDevCreate (PLW_xxx_FUNCS pxxxfuncs) { PLW_xxx_DEV pxxxdev; if (pxxxfuncs == LW_NULL) { _ErrorHandle(EINVAL); return (PX_ERROR); } if (_G_ixxxDrvNum <= 0) { _DebugHandle(__ERRORMESSAGE_LEVEL, "no driver.\r\n"); _ErrorHandle(ERROR_IO_NO_DRIVER); return (PX_ERROR); } pxxxdev = (PLW_xxx_DEV)__SHEAP_ALLOC(sizeof(LW_xxx_DEV)); if (pxxxdev == LW_NULL) { _DebugHandle(__ERRORMESSAGE_LEVEL, "system low memory.\r\n"); _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY); return (PX_ERROR); } lib_bzero(pxxxdev, sizeof(LW_xxx_DEV)); pxxxdev->xxxDEV_pxxxfuncs = pxxxfuncs; /* * 向系统中添加一个设备 (可以设置设备的 mode) */ if (iosDevAddEx(&pxxxdev->xxxDEV_devhdr, __LW_xxx_DEV_NAME, _G_ixxxDrvNum, DT_CHR) != ERROR_NONE) { __SHEAP_FREE((PVOID)pxxxdev); return (PX_ERROR); } return (ERROR_NONE); }
3.4模块加载和卸载
如图 3.1所示,步骤⑤~⑥,字符设备驱动编写完成后,经IDE编译并将生成的驱动模块部署到板卡上,然后通过modulereg和moduleunreg命令可以进行驱动模块的加载和卸载。如图 3.2所示,详细操作请参照《RealEvo_IDE使用手册》。
图 3.2驱动模块加载和卸载操作说明
3.5应用层调用
如图 3.1所示,步骤⑦~⑨,应用层可以通过open函数,打开/dev目录下对应的设备节点,通过匹配设备名和设备驱动程序索引号,获得该设备的管理结构,之后对该设备的读写和IO控制即可以调用到管理结构内具体的设备操作函数,实现硬件操作。用户程序的编写具体参照《SylixOS应用开发手册》。
原文地址:http://11178899.blog.51cto.com/11168899/1934369