当前位置: 首页 > article >正文

14_input子系统my_touch_device,my_touch_handlerLinux内核模块

01_basicLinux内核模块_the kernel was built by:x86 64-linux-gnu-gcc-12(ub-CSDN博客文章浏览阅读678次,点赞3次,收藏3次。环境ID=ubuntuMakefilemodules:clean:basic.creturn 0;运行效果。_the kernel was built by:x86 64-linux-gnu-gcc-12(ubuntu 12.3.0-1ubuntu1~22.04https://blog.csdn.net/m0_37132481/article/details/136157384环境

root@T:/media/sf_D_DRIVE/kmodule/14_input_dev# cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
root@T:/media/sf_D_DRIVE/kmodule/14_input_dev#
 

 my_touch_device.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/cdev.h>
#include <uapi/linux/major.h>

#define TAG "HELLO# "

static struct input_dev *my_input_touch;

static int my_touch_device_init(void)
{
 int err;
 printk(TAG "%s called\n", __func__);

 /* input device */
 my_input_touch = input_allocate_device();

 set_bit(EV_KEY, my_input_touch->evbit);
 set_bit(KEY_Q, my_input_touch->keybit);

 my_input_touch->name = "don't care";
 /* for device match handler */
 my_input_touch->id.product = 666;

 err = input_register_device(my_input_touch);
 return 0;
}
static void my_touch_device_exit(void)
{
 printk(TAG "%s called\n", __func__);
 input_unregister_device(my_input_touch);
}

module_init(my_touch_device_init);
module_exit(my_touch_device_exit);
MODULE_LICENSE("GPL");

 my_touch_handler.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/cdev.h>
#include <uapi/linux/major.h>

#define TAG "HELLO# "

struct my_touch
{
 struct input_handle handle;
 struct device dev;
 struct cdev cdev;
 struct class *class;
};

struct my_client
{
 char touchdata[10];
 struct my_touch *mytc;
};

static void my_event(struct input_handle *handle, unsigned int type,
                           unsigned int code, int value)
{
 printk(TAG "%s called, type,code,value=%u,%u,%d\n", __func__, type, code, value);
}

static int my_cdev_open(struct inode *inode, struct file *file)
{
 struct my_touch *mytc = container_of(inode->i_cdev, struct my_touch, cdev);
 struct my_client *client = kzalloc(sizeof(struct my_client), GFP_KERNEL);

        printk(TAG "%s called\n", __func__);
 client->mytc = mytc;
 file->private_data = client;

        return 0;
}
static int my_cdev_release(struct inode *inode, struct file *file)
{
 struct my_client *client = file->private_data;

        printk(TAG "%s called\n", __func__);
 kfree(client);
        return 0;
}

static ssize_t my_cdev_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
 struct my_client *client = file->private_data;

 // simulate hardware report
 input_report_key(client->mytc->handle.dev, KEY_Q, 1);
 input_report_key(client->mytc->handle.dev, KEY_Q, 0);
 input_sync(client->mytc->handle.dev);

        printk(TAG "%s called\n", __func__);

        return simple_read_from_buffer(buf, size, ppos, client->touchdata, sizeof(client->touchdata));
}
static ssize_t my_cdev_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos)
{
 struct my_client *client = file->private_data;

        printk(TAG "%s called\n", __func__);
        /* in case of echo command */
        if(size > sizeof(client->touchdata))
        {
                return -EINVAL;
        }
        else
        {
                /* nothing to do */
        }
        return simple_write_to_buffer(client->touchdata, sizeof(client->touchdata), ppos, buf, size);
}
static const struct file_operations my_cdev_fops = {
        .owner          = THIS_MODULE,
        .open           = my_cdev_open,
        .release        = my_cdev_release,
 .read           = my_cdev_read,
 .write          = my_cdev_write,
};

static int my_connect(struct input_handler *handler,
                                          struct input_dev *dev,
                                          const struct input_device_id *id)
{
 int err;
 int minor;
 struct my_touch *mytc;

 printk(TAG "%s called\n", __func__);
 mytc = kzalloc(sizeof(struct my_touch), GFP_KERNEL);

 mytc->handle.dev = input_get_device(dev);
 mytc->handle.handler = handler;
 mytc->handle.private = mytc;
 err = input_register_handle(&mytc->handle);
 err = input_open_device(&mytc->handle);

 minor = input_get_new_minor(0, 0, true);
 device_initialize(&mytc->dev);
 /* let udev create file /dev/input/mytouch%d */
 dev_set_name(&mytc->dev, "mytouch%d", minor);
 mytc->dev.devt = MKDEV(INPUT_MAJOR, minor);;
 mytc->dev.class = &input_class;
 cdev_init(&mytc->cdev, &my_cdev_fops);
 /* create file /sys/dev/char/13:MONOR */
 err = cdev_device_add(&mytc->cdev, &mytc->dev);

 return 0;
}
static void my_disconnect(struct input_handle *handle)
{
 struct my_touch *mytc = handle->private;

 printk(TAG "%s called\n", __func__);
 input_close_device(&mytc->handle);
 input_unregister_handle(&mytc->handle);
 cdev_device_del(&mytc->cdev, &mytc->dev);
 input_free_minor(MINOR(mytc->dev.devt));
 kfree(mytc);
}

static const struct input_device_id my_ids[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_PRODUCT,
  .product = 666,
        },
        { },
};

static struct input_handler my_handler = {
        .event =        my_event,
        .connect =      my_connect,
        .disconnect =   my_disconnect,
        .name =         "my_handler",
        .id_table =     my_ids,
};



static int my_touch_handler_init(void)
{
 int err;
 printk(TAG "%s called\n", __func__);

 /* input handler */
 err = input_register_handler(&my_handler);

 return 0;
}
static void my_touch_handler_exit(void)
{
 printk(TAG "%s called\n", __func__);
 input_unregister_handler(&my_handler);
}

module_init(my_touch_handler_init);
module_exit(my_touch_handler_exit);
MODULE_LICENSE("GPL");

效果

 

 


http://www.kler.cn/a/312189.html

相关文章:

  • 深度学习-神经网络基础-激活函数与参数初始化(weight, bias)
  • 深入Zookeeper节点操作:高级功能与最佳实践
  • string接口的深度理解(内附思维导图)
  • python之正则表达式总结
  • 数据结构-图的概念
  • Day40 | 动态规划 :完全背包应用 组合总和IV(类比爬楼梯)
  • Android 将EasyPermissions进一步封装,使得动态权限申请更加简明
  • Java 23、JDK 23正式发布!
  • C++之第十二课
  • 红日药业携手实在智能,构建RPA数字员工平台满足业务一体化需求 | 实在RPA案例
  • Java 多态(难)
  • VS运行程序时报错--无法定位程序输入点
  • Gitlab学习(007 gitlab项目操作)
  • 电影《祝你幸福!》观后感
  • 梧桐数据库(WuTongDB):SQL Server Query Optimizer 简介
  • OSPFv3协议几类LSA介绍
  • 【图像压缩与重构】基于标准+改进BP神经网络
  • Linux实操笔记2 Ubuntu安装Nginx的不同方法
  • python检测keycloak证书连接报错问题
  • 基于多域名,通过云运营商弹性负载,Nginx配置等基于的多租户系统部署
  • 有没有通过倾斜摄影文件直接导出DSM/DOM的文件软件?
  • npm发布插件超级简单版
  • django分发路由
  • alias 后门从入门到应急响应
  • 百度移动刷下拉词工具:快速出下拉词的技术分析
  • 肥胖成因:饮食之外,消耗吸收慢是关键因素