鼠标驱动之-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 ...
随机推荐
- HDU 1087 Super Jumping! Jumping! Jumping! (DP)
C - Super Jumping! Jumping! Jumping! Time Limit:1000MS Memory Limit:32768KB 64bit IO Format: ...
- 剑指Offer22 判断数组是否为某二叉搜索树的后序遍历
/************************************************************************* > File Name: 22_Sequen ...
- TCP/IP TIME_WAIT状态
百度运维部二面面试官问我这个 我直接懵逼了 TIME_WAIT状态是通信双方简历TCP连接后, 主动关闭的一方就会进入TIME_WAIT状态 1.client向server发送FIN(M),clien ...
- javascript-函数的参数和return语句
× 目录 [1]参数 [2]Arguments对象 [3]函数重载 [4]return 语句 ------------------------------------- 一.参数(最多25个) 可以动 ...
- 多线程的练习----妖,等待唤醒,代码重构,lock到condition
× 目录 [1]需求 [2]妖的出现和解决 [3]等待唤醒 [4]代码重构 [5]改成Lock Condition ------------------------------------- 1,需求 ...
- ContentProvider使用
package activity.cyq.contentprovidertenderer; import android.content.ContentProvider; import android ...
- 使用runtime给类动态添加方法并调用 - class_addMethod
上手开发 iOS 一段时间后,我发现并不能只着眼于完成需求,利用闲暇之余多研究其他的开发技巧,才能在有限时间内提升自己水平.当然,“其他开发技巧”这个命题对于任何一个开发领域都感觉不找边际,而对于我来 ...
- iOS-Andriod百度地图仿百度外卖-饿了么-选择我的地址-POI检索/
http://zanderzhang.gitcafe.io/2015/09/19/iOS-Andriod百度地图仿百度外卖-饿了么-选择我的地址-POI检索/ 百度外卖选择送货地址: 饿了么选择送货地 ...
- org.springframework.util.Assert
方法入参检测工具类 Web 应用在接受表单提交的数据后都需要对其进行合法性检查,如果表单数据不合法,请求将被驳回. 类似的,当我们在编写类的方法时,也常常需要对方法入参进行合 法性检查,如果入参不符合 ...
- U-Boot--配置过程分析
arm核:arm920t 2410 uboot版本:u-boot1.1.6 通过readme可以知道配置执行make smdk2410_config命令. 顶层Makefile : smdk24 ...