鼠标驱动之-sys节点-input子系统
首先需要了解sys节点和linux驱动编程的知识,在linux内核<linux/>下有着对应的实现。本例实现创建sys节点,外围程序通过input子系统控制鼠标位置。
第一步编写驱动代码,创建sys节点:
- #include <linux/module.h>
- #include <linux/platform_device.h>
- #include <linux/slab.h>
- #include <linux/input.h>
- #include <linux/kthread.h>
- #include <linux/semaphore.h>
- struct v_dev{
- struct platform_device *p_dev;
- struct input_dev *input;
- int x;
- int y;
- struct task_struct *run_thread;
- struct semaphore sem;
- };
- struct v_dev *vmouse_dev = NULL;
- static ssize_t write_pos(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
- {
- int x,y;
- sscanf(buf,"%d%d",&x,&y);
- vmouse_dev->x = x;
- vmouse_dev->y =y;
- //post 信号量
- up(&vmouse_dev->sem);
- return count;
- }
- static ssize_t show_pos(struct device *dev, struct device_attribute *attr,
- char *buf){
- return sprintf(buf,"(%d,%d)\n",vmouse_dev->x,vmouse_dev->y);
- }
- DEVICE_ATTR(pos,0644,show_pos,write_pos);
- static int vmouse_thread(void *data)
- {
- int x,y;
- struct v_dev *vmouse_dev = (struct v_dev*)data;
- struct semaphore *sema = &(vmouse_dev->sem);
- printk(KERN_INFO "vmouse thread running\n");
- while(1){
- //等待信号量
- while((down_interruptible(sema)) == -EINTR){} ;
- x = vmouse_dev->x;
- y = vmouse_dev->y;
- input_report_abs(vmouse_dev->input,ABS_X,x);
- input_report_abs(vmouse_dev->input,ABS_Y,y);
- input_sync(vmouse_dev->input);
- printk("vmouse thread report\n");
- }
- return 0;
- }
- static int vmouse_probe(struct platform_device *pdev)
- {
- int ret = -1;
- printk("%s debug \n",__func__);
- if(vmouse_dev->p_dev == pdev){
- printk("platform device is same\n");
- }
- vmouse_dev->input = input_allocate_device();
- if(!(vmouse_dev->input)){
- printk("%s request input deivce error\n",__func__);
- goto alloc_input;
- }
- vmouse_dev->input->name = "vmouse";
- set_bit(EV_ABS,vmouse_dev->input->evbit);
- input_set_abs_params(vmouse_dev->input, ABS_X, -1024, 1024, 0, 0);
- input_set_abs_params(vmouse_dev->input, ABS_Y, -1024, 1024, 0, 0);
- ret = input_register_device(vmouse_dev->input);
- if(ret < 0){
- printk("%s register input device error\n",__func__);
- goto input_register;
- }
- device_create_file(&pdev->dev,&dev_attr_pos);
- //初始化信号量,在线程中要用到
- sema_init(&(vmouse_dev->sem),0);
- vmouse_dev->run_thread = kthread_run(vmouse_thread,vmouse_dev,"vmouse_thread");
- return 0;
- input_register:
- input_free_device(vmouse_dev->input);
- alloc_input:
- kfree(vmouse_dev);
- return ret;
- }
- static struct platform_driver vmouse_driver = {
- .probe = vmouse_probe,
- .driver = {
- .owner = THIS_MODULE,
- .name = "v_mouse",
- },
- };
- static int __init vmouse_init(void)
- {
- int ret =-1;
- printk("%s\n", __func__);
- vmouse_dev = kzalloc(sizeof(struct v_dev),GFP_KERNEL);
- if(vmouse_dev == NULL){
- printk("%s alloc memory error\n",__func__);
- return -ENOMEM;
- }
- vmouse_dev->p_dev= platform_device_register_simple("v_mouse",-1,NULL,0);
- if(!(vmouse_dev->p_dev)){
- printk("%s register platform device error\n",__func__);
- return ret;
- }
- ret = platform_driver_register(&vmouse_driver);
- if(ret < 0){
- printk("%s register driver error\n",__func__);
- return ret;
- }
- return 0;
- }
- static void __exit vmouse_exit(void)
- {
- printk("%s\n", __func__);
- if(vmouse_dev->input != NULL){
- input_unregister_device(vmouse_dev->input);
- }
- printk("%s debug__1\n",__func__);
- if(vmouse_dev != NULL){
- platform_device_unregister(vmouse_dev->p_dev);
- }
- printk("%s debug__2\n",__func__);
- platform_driver_unregister(&vmouse_driver);
- printk("%s debug__3\n",__func__);
- kfree(vmouse_dev);
- printk("%s debug__4\n",__func__);
- }
- module_init(vmouse_init);
- module_exit(vmouse_exit);
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("oracleloyal@gmail.com“);
- 编写makefile:
- 1 ifeq ($(KERNELRELEASE),)
2 #KERNEL_DIR:=/home/archermind/zhaoxi/bsw_ww02_2016/kernel/cht
3 KERNEL_DIR:=/usr/src/linux-headers-3.13.0-32-generic
4 PWD:=$(shell pwd)
5 modules:
6 $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
7 modules_install:
8 $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules_install
9 clean:
10 rm -rf .*.cmd *.ko *.o modules.order Module.symvers *mod.c
11 .PHONY: modules modules_install clean
12 else
13 modules-objs := sys.o
14 obj-m := sys.o
15 endif - 在当前makefile路径下执行make
- sudo insmod **.ko
- 加载驱动---会在/sys/devices/platform下出现节点,并且/dev/input下会出先对应的可读写的节点。
- 驱动的卸载sudo rmmod modules
- 编写测试程序:
- #include <fcntl.h>
- #include <linux/input.h>
- #include <stdio.h>
- //要看自己的节点了 ---》特别注意去看自己多出的到底是哪个节点这里需要改动哦
- #define EVENT_DEV "/dev/input/event5"
- int main(void)
- {
- struct input_event ev;
- int count,x,y;
- int fd = open(EVENT_DEV, O_RDWR);
- if(fd < 0){
- printf("open %s failed\n",EVENT_DEV);
- return 0;
- }
- while(1){
- count = read(fd, &ev,sizeof(struct input_event));
- if(EV_ABS == ev.type){
- if(ev.code == ABS_X){
- x = ev.value;
- }else if(ev.code == ABS_Y){
- y = ev.value;
- }
- printf("position: x=%d, y=%d\n",x,y);
- }else if(EV_SYN == ev.type){
- puts("sync!");
- }
- }
- return 0;
- }
- 先运行应用程序:./test_sys
在另一个终端执行:echo "90 90" >/sys/devices/platform/v_mouse/pos你就会看到你input设备上报的坐标,打印信息如下:
position: x=90, y=0
position: x=90, y=90
sync! - 完毕!
鼠标驱动之-sys节点-input子系统的更多相关文章
- 基于input子系统的sensor驱动调试(二)
继上一篇:http://www.cnblogs.com/linhaostudy/p/8303628.html#_label1_1 一.驱动流程解析: 1.模块加载: static struct of_ ...
- 【驱动】input子系统整体流程全面分析(触摸屏驱动为例)【转】
转自:http://www.cnblogs.com/lcw/p/3294356.html input输入子系统整体流程 input子系统在内核中的实现,包括输入子系统(Input Core),事件处理 ...
- input子系统驱动学习之中的一个
刚開始学习linux这门课就被分配编写一个设备的input子系统驱动.这对我的确有点困难.只是实际的操作中发现困难远比我想象的要大的多.本以为依照老师课上的步骤就行非常快的完毕这项任务.后来发 ...
- input子系统分析
------------------------------------------ 本文系本站原创,欢迎转载! 转载请注明出处:http://ericxiao.cublog.cn/ -------- ...
- linux input输入子系统分析《四》:input子系统整体流程全面分析
1 input输入子系统整体流程 本节分析input子系统在内核中的实现,包括输入子系统(Input Core),事件处理层(Event Handler)和设备驱动层.由于上节代码讲解了设备 ...
- Linux usb子系统(一) _写一个usb鼠标驱动
USB总线是一种典型的热插拔的总线标准,由于其优异的性能几乎成为了当下大小设备中的标配. USB的驱动可以分为3类:SoC的USB控制器的驱动,主机端USB设备的驱动,设备上的USB Gadget驱动 ...
- 【驱动】input子系统全面分析
初识linux输入子系统 linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(InputC ...
- Linux 驱动框架---input子系统
input 子系统也是作为内核的一个字符设备模块存在的,所以他也是字符设备自然也会有字符设备的文件接口.input子系统的注册过程主要分为两步,先注册了一个input class然后再注册一个字符设备 ...
- 基于input子系统的sensor驱动调试(一)
要想弄明白世界的本质,就要追根溯源:代码也是一样的道理: 最近调试几个sensor驱动,alps sensor驱动.compass sensor驱动.G-sensor驱动都是一样的架构: 一.基于in ...
随机推荐
- hg(Mercurial)版本库迁移到git版本库
这几天没事干净搞迁移了,迁移完MVC又迁移版本库,还把工作电脑迁移了一下,开始用Win8.1了.这个迁移主要是因为实在不想在工作电脑上又装git又装hg了,点个右键出来一大堆菜单,况且现在git已经成 ...
- Flips测试类(page43)
测试用例:所用java类: StdOut,StdIn , Counter, StdRandom, public class Flips { public static void main(String ...
- P1111 修复公路
P1111 修复公路 550通过 1.6K提交 题目提供者该用户不存在 标签并查集 难度普及/提高- 提交该题 讨论 题解 记录 题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通 ...
- UEditor上传图片被压缩得模糊的解决方法
UEditor功能很强大,但是有个很不友好的功能:会在使用UEditor上传图片时,如果你的原始图片尺寸过大,就会先自动对图片大小进行压缩,然后将压缩的文件给servlet.也就是说,使用UEdito ...
- JOSN传字符串方法
#region 提示信息 /// <summary> /// 操作失败(无参数) /// </summary> /// <returns></returns& ...
- C#读写日志文本文件
日志为文本文件每列以制表符隔开 行以换行符隔开 本次示例简单实现如下相关功能:1.正写日志文本 最新的日志放后面2.倒写日志文本 最新的日志放前面3.读日志文本内容显示在Label4.读日志文本内容到 ...
- 第七篇、OC_图片的裁剪基于SDWebImage
前期有段时间困扰了我很久一个问题由于工程中的图片数据抓取自不同平台,所以图片的大小尺寸不一定,而放置图片的imageView尺寸是一定的,不作任何处理的话会导致图片拉伸变形,因此找了好久解决办法,现把 ...
- 几款jQuery右键菜单插件
1.jQuery Very Simple ContextMenu Plugin 2.ContextJS Project Page:http://lab.jakiestfu.com/contextjs/ ...
- UI3_UICollectionViewMuti
// AppDelegate.m // UI3_UICollectionViewMuti // // Created by zhangxueming on 15/7/16. // Copyright ...
- UI1_UITabBarController
// // AppDelegate.h // UI1_UITabBarController // // Created by zhangxueming on 15/7/8. // Copyright ...