SylixOS 字符设备驱动简介
本章内容详见《SylixOS设备驱动程序开发》
字符设备是指只能以字节为单位进行读写,读取数据需按照先后顺序,不能随机读取设备内存中某一数据的设备。
常见的字符设备如:鼠标、键盘、串口等。
在 SylixOS 中,每个字符设备都会在/dev 目录下对应一个设备文件,用户程序可通过设备文件(或设备节点)来进行字符设备的读写、IO 控制等操作。
SylixOS 中,字符设备驱动类型分为三类:
1、LW_DRV_TYPE_ORIG(原始设备驱动,兼容 VxWorks);
2、LW_DRV_TYPE_SOCKET(SOCKET 型设备驱动程序);
3、LW_DRV_TYPE_NEW_1(NEW_1 型设备驱动程序)。
其中,LW_DRV_TYPE_ORIG 和 LW_DRV_TYPE_NEW_1
驱动类型分别对应 SylixOS 中 I/O 系统结构中的 ORIG 型驱动结构和 NEW_1 型驱动结构。
NEW_1 型驱动结构在 ORIG 型驱动结构的基础上增加了文件访问权限、文件记录锁等功能。
SylixOS 中字符设备驱动框架主要包括字符设备驱动注册、设备创建及管理。
SylixOS 字符设备驱动框架
SylixOS 中字符设备驱动框架主要包括字符设备驱动注册、设备创建及管理。
1、字符设备驱动安装
字符设备驱动安装接口相关信息位于“libsylixos/SylixOS/system/ioLib/ioSys.c”文件中, SylixOS 为驱动安装提供了三组接口。驱动安装函数主要作用是在内核驱动程序表中找到空闲位置,并注册对应的驱动程序。
函数 API_IosDrvInstall 原型分析:
~ 此函数成功返回驱动程序索引号 iDrvNum,失败返回 PX_ERROR;
~参数 pfuncCreate 是驱动程序中的建立函数 (如果非符号链接, 则不可更改 name 参数内容);
~参数 pfuncDelete 是驱动程序中的删除函数;
~参数 pfuncOpen 是驱动程序中的打开函数 (如果非符号链接, 则不可更改 name 参数内容);
~参数 pfuncClose 是驱动程序中的关闭函数;
~参数 pfuncRead 是驱动程序中的读函数;
~参数 pfuncWrite 是驱动程序中的写函数;
~参数 pfuncIoctl 是驱动程序中的 IO 控制函数。
函数 API_IosDrvInstallEx 原型分析:
~此函数成功返回驱动程序索引号 iDrvNum,失败返回 PX_ERROR;
~参数 pfileop 是驱动程序中设备文件操作块。 设备文件操作块 file_operations 详细描述如下:
#include <SylixOS.h>
typedef struct file_operations {
struct module *owner;
long (*fo_create)();
int (*fo_release)();
long (*fo_open)();
int (*fo_close)();
ssize_t (*fo_read)();
ssize_t (*fo_read_ex)();
ssize_t (*fo_write)();
ssize_t (*fo_write_ex)();
int (*fo_ioctl)();
int (*fo_select)();
int (*fo_lock)();
off_t (*fo_lseek)();
int (*fo_fstat)();
int (*fo_lstat)();
int (*fo_symlink)();
ssize_t (*fo_readlink)();
int (*fo_mmap)();
int (*fo_unmap)();
ULONG fo_pad[16];
} FILE_OPERATIONS;
fo_create:设备创建函数;
fo_release:设备释放函数;
fo_open:设备打开操作函数;
fo_close:设备关闭函数;
fo_read(ex):读设备(扩展)函数;
fo_write(ex):写设备(扩展)函数;
fo_ioctl:设备控制函数;
fo_select:select 功能函数;
fo_lock:lock 功能函数;
fo_lseek:lseek 功能函数;
fo_fstat:fstat 功能函数;
fo_lstat:lstat 功能函数;
fo_symlink:建立链接文件;
fo_readlink:读取链接文件;
fo_mmap:文件映射;
fo_unmap:映射结束;
fo_pad:保留项。
函数 API_IosDrvInstallEx2 原型分析:
~此函数成功返回驱动程序索引号 iDrvNum,失败返回 PX_ERROR;
~参数 pfileop 是驱动程序中设备文件操作块;
~参数 iType 是设备驱动类型。
字符设备的创建及管理
每个具体的字符设备控制块根据各设备特点由驱动开发者自行封装,但其中都应包含一个设备头,
且设备头为设备控制块第一个成员,用来对该设备进行管理。设备头结构体 LW_DEV_HDR 详细描述如下:
#include <SylixOS.h>
typedef struct {
LW_LIST_LINE DEVHDR_lineManage; /* 设备头管理链表 */
UINT16 DEVHDR_usDrvNum; /* 设备驱动程序索引号 */
PCHAR DEVHDR_pcName; /* 设备名称 */
UCHAR DEVHDR_ucType; /* 设备 dirent d_type */
atomic_t DEVHDR_atomicOpenNum; /* 打开的次数 */
PVOID DEVHDR_pvReserve; /* 保留 */
} LW_DEV_HDR;
DEVHDR_lineManage:设备头管理链表,可将其链入系统中设备管理链表;
DEVHDR_usDrvNum:设备驱动程序索引号;
DEVHDR_pcName:设别名称;
DEVHDR_ucType:设备类型,字符设备默认选择 DT_CHR 类型;
DEVHDR_atomicOpenNum:设备打开次数;
DEVHDR_pvReserve:保留项。
根据具体设备的设备头,调用 API_IosDevAdd 或者 API_IosDevAddEx 将设备添加进设 备管理链表进行管理。
设备添加函数位于“libsylixos/SylixOS/system/ioLib/ioSys.c”文件中。
设备添加函数详细介绍如下:
函数 API_IosDevAdd 原型分析:
此函数成功返回 ERROR_NONE,失败返回 PX_ERROR;
参数 pdevhdrHdr 是设备头指针;
参数 pcName 是设备名;
参数 iDrvNum 是驱动程序索引号,该索引号即为 10.2.1 小节字符设备驱动安装函 数返回值。
函数 API_IosDevAdd 原型分析:
此函数成功返回 ERROR_NONE,失败返回 PX_ERROR;
参数 pdevhdrHdr 是设备头指针;
参数 pcName 是设备名;
参数 iDrvNum 是驱动程序索引号,该索引号即为 10.2.1 小节字符设备驱动安装函数返回值;
参数 ucType 是设备类型,如字符设备选择 DT_CHR 类型。
调用上述两个函数即可将设备添加进设备头管理链表中进行管理。
应用程序根据设备名 打开设备,通过设备名和驱动程序索引号在链表中找到对应的设备控制块,
获取到设备驱动函数,最终即可对设备进行读写和 I/O 控制等操作。