SylixOS注册驱动和创建设备文件
上一节我们完成了驱动中的open和close函数功能,并使用这两个函数初始化了demo_fops 这个数据结构,现在我们将驱动注册到系统中,在SylixOS中这是通过调用iosDrvInstallEx 接口来实现的,这个接口其实就是API_IosDrvInstallEx 接口的宏定义,用宏重定义为iosDrvInstallEx 是为了和VxWorks的驱动相兼容,在SylixOS中,所有原生接口都是API_xxx 这种格式。
API_IosDrvInstallEx接口的函数原型:
INT API_IosDrvInstallEx (struct file_operations *pfileop);
成功返回一个驱动索引号,失败返回PX_ERROR。在SylixOS中,所有注册的驱动都是存放在一张全局的驱动表(数组)中,每次注册驱动时,都会在当前表中找到一个可用的位置给注册的驱动使用,并返回这个位置在表中的索引(数组下标)。 调用此接口默认创建的是ORIG型驱动。
一般在驱动中会定义一个全局变量用来保存驱动索引号:
int drv_index; int module_init (void) { int ret = 0; drv_index = iosDrvInstallEx(&demo_fops); if (drv_index < 0) { printk("driver install fail.\r\n"); return -1; } return 0; }
这个驱动索引号会在驱动卸载的时候用到,卸载驱动所使用的接口是iosDrvRemove,iosDrvRemove 是API_IosDrvRemove 的宏定义,函数原型:
ULONG API_IosDrvRemove (INT iDrvNum, BOOL bForceClose);
iDrvNum就是驱动注册时的索引号,bForceClose表示是否强制删除驱动。成功返回ERROR_NONE,失败返回错误号。
在linux驱动中我们需要填写驱动所遵守的开源协议以及驱动的作者等信息,同样的,在SylixOS中也可以填入这些信息:
DRIVER_LICENSE(drv_index, "GPL->Ver 2.0"); DRIVER_AUTHOR(drv_index, "GeWenBin"); DRIVER_DESCRIPTION(drv_index, "demo driver.");
驱动注册完成之后,我们就可以创建设备文件,这是通过iosDevAdd 接口实现的,iosDevAdd 是API_IosDevAdd 的宏定义,函数原型:
ULONG API_IosDevAdd (PLW_DEV_HDR pdevhdrHdr, CPCHAR pcName, INT iDrvNum);
pdevhdrHdr就是设备实例变量的地址,pcName是设备文件的名称,比如“/dev/demo”,iDrvNum就是注册驱动时返回的索引号。成功返回ERROR_NONE,失败返回错误码。
删除设备文件使用iosDevDelete接口,iosDevDelete是API_IosDevDelete 的宏定义,函数原型:
VOID API_IosDevDelete (PLW_DEV_HDR pdevhdrHdr);
这个接口只有一个入参,就是设备实例变量的地址。
在驱动模块卸载时,一般是先删除设备文件再卸载设备驱动:
void module_exit (void) { iosDevDelete(&demo_dev); iosDrvRemove(drv_index, TRUE); }
附源码
driver_demo4源码:
#define __SYLIXOS_KERNEL #include <SylixOS.h> #include <module.h> int drv_index; LW_DEV_HDR demo_dev; static long demo_open(LW_DEV_HDR *dev, char *name, int flag, int mode) { printk("%s %s.\r\n", __func__, name); if ((flag & O_ACCMODE) == O_RDONLY) { printk("open read only.\r\n"); } else if ((flag & O_ACCMODE) == O_WRONLY) { printk("open write only.\r\n"); } else { printk("open read/write.\r\n"); } printk("file permission: %o.\r\n", mode); return (long)dev; } static int demo_close(LW_DEV_HDR *dev) { printk("%s.\r\n", __func__); return ERROR_NONE; } static struct file_operations demo_fops = { .owner = THIS_MODULE, .fo_open = demo_open, .fo_close = demo_close, }; int module_init (void) { int ret = 0; drv_index = iosDrvInstallEx(&demo_fops); if (drv_index < 0) { printk("driver install fail.\r\n"); return -1; } DRIVER_LICENSE(drv_index, "GPL->Ver 2.0"); DRIVER_AUTHOR(drv_index, "GeWenBin"); DRIVER_DESCRIPTION(drv_index, "demo driver."); ret = iosDevAdd(&demo_dev, "/dev/demo", drv_index); if (ret != ERROR_NONE) { printk("device add fail.\r\n"); iosDrvRemove(drv_index, TRUE); return -1; } return 0; } void module_exit (void) { iosDevDelete(&demo_dev); iosDrvRemove(drv_index, TRUE); }
2022年4月20日 14:50 1F
创建:先有驱动,后有设备。卸载:先卸载设备,后卸载驱动。
2022年4月27日 23:01 B1
@ 陪丫头长大 祁工掌握了精髓