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。
附源码
#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);
}