SylixOS下的驱动分为ORIG 和 NEW_1 两种类型,本次分享的是NEW_1 型驱动示例
字符驱动框架
字符驱动就是驱动先写好代码用结构体进行保存函数,并用全局年变量来标识这个驱动,后面添加设备时候,设备可用这个全局变量找打驱动,设备的参数作为参数进入到函数运行。
分为几个步骤:
- 安装驱动
- 注册设备
- 使用设备
安装驱动
static LONG __Open (PLW_DEV_HDR pDevHdr, PCHAR pcName, INT iFlags, INT iMode)
{
PLW_FD_NODE pFdNode;
BOOL bIsNew;
DEV* pdev = (DEV*)pDevHdr;
if (LW_NULL == pcName) {
_ErrorHandle(ERROR_IO_NO_DEVICE_NAME_IN_PATH);
return (PX_ERROR);
} else {
pFdNode = API_IosFdNodeAdd(&pdev ->fdNodeHeader, (dev_t)pdev , 0,
iFlags, iMode, 0, 0, 0, LW_NULL, &bIsNew);
if (LW_NULL == pFdNode) {
return (PX_ERROR);
}
if (1 == LW_DEV_INC_USE_COUNT(&pdev ->devHdr)) {
return ((LONG)pFdNode);
}
}
/*
* 如果设备打开失败进行如下操作
*/
if (pFdNode) {
API_IosFdNodeDec(&pdev ->fdNodeHeader, pFdNode, LW_NULL);
pFdNode = LW_NULL;
}
LW_DEV_DEC_USE_COUNT(&pdev ->devHdr);
return (PX_ERROR);
}
static INT __Close (PLW_FD_ENTRY pFdEntry)
{
DEV* pdev = (PEMC14_CHAN)pFdEntry->FDENTRY_pdevhdrHdr;
PLW_FD_NODE pFdNode = (PLW_FD_NODE)pFdEntry->FDENTRY_pfdnode;
if (pFdEntry && pFdNode) {
API_IosFdNodeDec(&pdev ->fdNodeHeader, pFdNode, LW_NULL);
LW_DEV_DEC_USE_COUNT(&pdev ->devHdr);
return (ERROR_NONE);
}
return (PX_ERROR);
}
static INT __Ioctl (PLW_FD_ENTRY pFdEntry, INT iCmd, LONG lArg)
{
return (ERROR_NONE);
}
INT DrvInstall (VOID)
{
struct file_operations fileop;
if (_G_DrvNum > 0) {
return (ERROR_NONE);
}
lib_memset(&fileop, 0, sizeof(struct file_operations));
fileop.owner = THIS_MODULE;
fileop.fo_create = __Open;
fileop.fo_open = __Open;
fileop.fo_close = __Close;
fileop.fo_ioctl = __Ioctl;
_G_DrvNum = iosDrvInstallEx2(&fileop, LW_DRV_TYPE_NEW_1);
DRIVER_LICENSE(_G_DrvNum, "xxx");
DRIVER_AUTHOR(_G_DrvNum, "xxx");
DRIVER_DESCRIPTION(_G_DrvNum, "xxx driver.");
return ((_G_DrvNum > 0) ? (ERROR_NONE) : PX_ERROR));
}
_G_DrvNum 用来记录驱动号,设备使用时候用这个获取操作集的函数
注册设备
typedef struct {
LW_DEV_HDR devHdr;
LW_LIST_LINE_HEADER fdNodeHeader;
LW_OBJECT_HANDLE hDevLock;
PCHAR pcIoDevName;
} DEV;
DEV dev;
DEV* pdev;
iosDevAddEx(&pdev->devHdr, pdev->pcIoDevName, _G_DrvNum, DT_CHR))