鼠标驱动之-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 ...
随机推荐
- JAVA数字证书制作生成
1.加密算法 为了网络通讯中的报文安全,一般需要对报文进行加密,目前常用的加密算法有: 非对称加密算法:又称公钥加密算法,如RSA.DSA/DSS,最常用的就是RSA算法(算法公开,可自行百度了解算法 ...
- nginx lua mysql redis设置
最近公司网站改版,程序和数据库全部用新版,旧版的数据要导入,旧网站的30万条数据url要全部重定向到新版网站,正好前段时间在学习nginx+lua+mysql+memcache(redis),找资料真 ...
- POJ 1287 Networking (最小生成树)
Networking Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit S ...
- 在网页中制作icon图标
用字体在网页中画icon图标 第一步:获取字体资源IconMoon网站https://icomoon.io iconMoon中有很多免费小图标可用,还能设置下载图标的使用属性(通过网站中设立的按钮pr ...
- 跟我一起学习ASP.NET 4.5 MVC4.0(六)(转)
这一系列文章跨度有点大,由于最近忙于其他事情,没有更新,今天重新安装了下Win8系统,VS2012和SQLServer 2012,顺便抽空继续一篇.随着VS2012 RC版本的放出,ASP.NET M ...
- C#完全无客户端访问Oracle
网上太多的C#无客户端访问oracle案例,经我测试无一成功,特将我在oracle官网上和自己琢磨总结,终于成功,废话不多说,直接上项目. 一,准备条件 (由于我这里是用的控制台程序来测试的,所以将上 ...
- jQuer中 height scrollTop
jQuery(window).height()代表了当前可见区域的大小,而jQuery(document).height()则代表了整个文档的高度,可视具体情况使用. 注意当浏览器窗口大小改变时(如最 ...
- WinDbg配置与下载 (转载)
WinDbg配置和使用基础 WinDbg是微软发布的一款相当优秀的源码级(source-level)调试工具,可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件. 1. Win ...
- QA在网站建设中的作用
在网站建设项目中,有一个团队负责产品测试并识别产品中的缺陷是很有意义的.问题在于,不应该只依赖这个团队来发现所有的缺陷,就像航空公司不能只依靠空乘人员确保飞机安全一样.这个观点的核心是一个简单的事实, ...
- iOS数据持久化(三)
#pragma mark - Core Data stack /** * @synthesize 关联成员变量和属性 */ @synthesize managedObjectContext = _ma ...