正点原子第五十八章 Linux input子系统实验 文档之外(没提到的部分)

发布时间 2023-07-17 18:11:23作者: FBshark

使用 input 子系统,不需要分配设备号、注册设备、创建类等等工作。

也就是不需要以下的代码。

    //1. 由系统分配设备号
    if(Key_Struct.major != 0)
    {
        Key_Struct.devid= MKDEV(Key_Struct.major, 0);
        register_chrdev_region(Key_Struct.devid, DEV_CNT, DEV_NAME);
    }
    else    //major == 0
    {
        alloc_chrdev_region(&(Key_Struct.devid),0,DEV_CNT,DEV_NAME);
        Key_Struct.major = MAJOR(Key_Struct.devid);
        Key_Struct.minor = MINOR(Key_Struct.devid);
    }
    printk("new key major:%d; minor:%d\r\n", Key_Struct.major, Key_Struct.minor);
    
    //2. 注册设备
    Key_Struct.cdev.owner = THIS_MODULE;
    cdev_init(&(Key_Struct.cdev), &my_fops);
    cdev_add(&(Key_Struct.cdev), Key_Struct.devid, DEV_CNT);

    //3. 设置自动装载节点
    //创建类
    Key_Struct.class = class_create(THIS_MODULE, DEV_NAME);
    if (IS_ERR(Key_Struct.class)) {
        return PTR_ERR(Key_Struct.class);
    }
    //创建设备
    Key_Struct.device = device_create(Key_Struct.class, NULL, Key_Struct.devid, NULL, DEV_NAME);
    if (IS_ERR(Key_Struct.device)) {
        return PTR_ERR(Key_Struct.device);
    }
View Code

但这段代码还有很重要的部分:

比如给设备取了名字(例如 fireled),然后应用程序才能通过 /dev/fireled 调用驱动程序;

再比如注册设备过程中 cdev_init(&(Key_Struct.cdev), &my_fops); 将 my_fops 和设备联系起来;

现在这段代码被申请、初始化、注册 input_dev 结构体所取代,那么上面的两种情况如何解决呢?

情况1:没了名字(设备路径)怎么办?

文档中有写(P1406)

 当我们向 Linux内核成功注册 input_dev设备以后,会在 /dev/input目录下生成一
个名为“ eventX(X=0….n)”的文件,这个 /dev/input/eventX就是对应的 input设备文件。

也就是说  /dev/input/eventX 就是我们应用程序使用驱动时的路径。

当然,input_dev 结构体也有 name 成员,可以将原来的名字在初始化的时候,放在这个成员里面。

#define INPUT_DEV_NAME            "firekey_input"
.....
typedef struct
{
    struct input_dev * indevp; /* 输入子系统设备结构体指针*/
}DevStruct;
DevStruct Key_Struct;

...... Key_Struct.indevp
->name = INPUT_DEV_NAME;

 

情况2:原来的 fops 结构体怎么办?

在应用程序中,一定有 read\write 等函数,现在 fops 与设备没联系,该怎么办呢?

答案是:其实驱动程序中把 fops 部分全删掉也没事。 我的猜想是 input_event 这个结构体代替了驱动中 xxx_read() 函数的作用。

例如应用程序如下,经过实验,在使用 input 子系统之后,即使驱动程序中没有相应的 xxx_read 函数,该应用程序仍然能正常运行。

1 static struct input_event myevt;  //定义input_event 结构体
 
3 int main(int argc, char *argv[])
4 {
     ....
6     read(fd, &myevt, sizeof(myevt));
     ...
8 }