鼠标驱动之-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 ...
随机推荐
- oracle冷备份
windows环境下Oracle数据库冷备份和恢复 1.点击开始菜单的“运行”,输入sqlplus/nolog 2.在弹出的命令行窗口以sysdba身份登陆,要输入:系统用户名/登陆密码@数据库实例名 ...
- angularJs中图表功能(有集成框架)-angular-flot
1.柱状图和折线图的数据格式: $scope.Chart.data = [ { label: "离线", data: [[0, 2]] }, { label: "在线&q ...
- javascript跨域请求RESTful Web Service
跨域请求RESTful Web Service 当我们用js请求RESTful Web Service的时候,通常会出现跨域无法访问的问题,也就是无法正常得到我们要的值.jsonp是个解决问题的方法. ...
- hdu 3111 DLX解数独
思路:裸的DLX解数独.关键是建图,感觉还不如写个dfs直接,DLX写这个的代码很烦. #include<set> #include<map> #include<cmat ...
- CF 335B - Palindrome 区间DP
335B - Palindrome 题目: 给出一个字符串(均有小写字母组成),如果有长度为100的回文子串,输出该子串.否则输出最长的回文子串. 分析: 虽然输入串的长度比较长,但是如果存在单个字母 ...
- 非常棒的 「Sublime Text 配色/主题」与「编程字体」
*标有 CT 的是配色 **主题中调用的字体和相配套的Sublime主程序图标可访问GitHub获取 Afterglow https://github.com/YabataDesign/aftergl ...
- 关于inodes占用100%的问题及解决方法
#df shows no file systems processedPosted by John Quaglieri on 27 July 2012 07:26 AMA df -m command ...
- 六、Android学习笔记_JNI_c调用java代码
1.编写native方法(java2c)和非native方法(c2java): package com.example.provider; public class CallbackJava { // ...
- 【网络收集】获取JavaScript 的时间使用内置的Date函数完成
var mydate = new Date(); mydate.getYear(); //获取当前年份(2位) mydate.getFullYear(); //获取完整的年份(4位,1970-???? ...
- SQL 复制订阅 异常后 强制删除
最近做数据库同步备份工作,将 主库 通过SQLService 自带的 [复制] 订阅出去后,因为 订阅方(从库) 发生异常,主库 无法确定 从库的订阅,就想清理了,订阅重新做同步,结果.....主库上 ...