SylixOS字符设备驱动开发(六)

本文介绍SylixOS中如何统计设备驱动被打开的次数,包括设备实例数据结构中的打开计数字段及其原子操作函数,并展示了实际操作过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值