SylixOS驱动统计打开次数
在上一节我们说驱动被打开的次数是由驱动开发者维护的,其实在设备实例数据结构中就有一个成员表示设备被打开的次数:
typedef struct { LW_LIST_LINE DEVHDR_lineManage; /* 设备头管理链表 */ UINT16 DEVHDR_usDrvNum; /* 主设备号 */ UINT16 DEVHDR_usDevNum; /* 子设备号 */ PCHAR DEVHDR_pcName; /* 设备名称 */ UCHAR DEVHDR_ucType; /* 设备 dirent d_type */ atomic_t DEVHDR_atomicOpenNum; /* 打开的次数 */ PVOID DEVHDR_pvReserve; /* 保留 */ } LW_DEV_HDR;
DEVHDR_atomicOpenNum 就表示设备打开的次数,在open的时候调用LW_DEV_INC_USE_COUNT 接口增加打开次数,这是一个inline函数,函数原型:
static LW_INLINE INT LW_DEV_INC_USE_COUNT(PLW_DEV_HDR pdevhdrHdr) { return ((pdevhdrHdr) ? (API_AtomicInc(&pdevhdrHdr->DEVHDR_atomicOpenNum)) : (PX_ERROR)); }
可以看出就是通过原子增加计数的接口API_AtomicInc 增加了打开次数。同样的,在close的时候调用LW_DEV_DEC_USE_COUNT 接口减少打开次数,函数原型:
static LW_INLINE INT LW_DEV_DEC_USE_COUNT(PLW_DEV_HDR pdevhdrHdr) { return ((pdevhdrHdr) ? (API_AtomicDec(&pdevhdrHdr->DEVHDR_atomicOpenNum)) : (PX_ERROR)); }
可以看出其调用了原子减少计数的接口API_AtomicDec 减少了打开次数。
在驱动的open和close函数中分别添加这两个接口后我们来看看设备的打开次数是不是确实会改变。加载驱动后在命令行open两次“/dev/demo”之后,使用devs 查看驱动的打开次数:
[root@sylixos:/root]# devs device show (minor device) >> drv dev open name 37 0 2 /dev/demo 36 1 0 /dev/input/xmse 36 0 0 /dev/input/xkbd 35 0 0 /dev/netbd 34 0 0 /dev/netbr 33 0 0 /dev/net/vnd 32 0 0 /dev/socket 31 0 0 /dev/netevent 24 0 0 /ram 29 0 1 /dev/input/touch0 30 0 0 /dev/fb0 23 0 0 /media/sdcard0 10 0 0 /dev/blk/sdcard-0 27 0 0 /yaffs2 18 0 1 /dev/ttyS0 15 1 0 /dev/urandom 15 0 0 /dev/random 14 0 0 /dev/shm 13 0 0 /proc 12 0 1 /dev/hotplug 11 0 0 /dev/epollfd 9 0 0 /dev/gpiofd 8 0 0 /dev/signalfd 7 0 0 /dev/hstimerfd 6 0 0 /dev/timerfd 5 0 0 /dev/semfd 4 0 0 /dev/bmsg 3 0 0 /dev/eventfd 1 0 0 /dev/zero 0 0 0 /dev/null 2 0 0 / [root@sylixos:/root]#
可以看到37号驱动的open次数确实是两次,这时close一个刚刚打开的设备文件后再次查看信息:
[root@sylixos:/root]# devs device show (minor device) >> drv dev open name 37 0 1 /dev/demo 36 1 0 /dev/input/xmse 36 0 0 /dev/input/xkbd 35 0 0 /dev/netbd 34 0 0 /dev/netbr 33 0 0 /dev/net/vnd 32 0 0 /dev/socket 31 0 0 /dev/netevent 24 0 0 /ram 29 0 1 /dev/input/touch0 30 0 0 /dev/fb0 23 0 0 /media/sdcard0 10 0 0 /dev/blk/sdcard-0 27 0 0 /yaffs2 18 0 1 /dev/ttyS0 15 1 0 /dev/urandom 15 0 0 /dev/random 14 0 0 /dev/shm 13 0 0 /proc 12 0 1 /dev/hotplug 11 0 0 /dev/epollfd 9 0 0 /dev/gpiofd 8 0 0 /dev/signalfd 7 0 0 /dev/hstimerfd 6 0 0 /dev/timerfd 5 0 0 /dev/semfd 4 0 0 /dev/bmsg 3 0 0 /dev/eventfd 1 0 0 /dev/zero 0 0 0 /dev/null 2 0 0 / [root@sylixos:/root]#
可以看到37号驱动的open次数变成了1。
附源码
driver_demo6源码:
#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); LW_DEV_INC_USE_COUNT(dev); return (long)dev; } static int demo_close(LW_DEV_HDR *dev) { printk("%s.\r\n", __func__); LW_DEV_DEC_USE_COUNT(dev); 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); }
2021年9月16日 15:17 1F
写的真好,认真学习了。