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 reportinput_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");
效果