鼠标驱动之-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 ...
随机推荐
- Hadoop2.0重启脚本
Hadoop2.0重启脚本 方便重启带ha的集群,写了这个脚本 #/bin/bash sh /opt/zookeeper-3.4.5-cdh4.4.0/bin/zkServer.sh restart ...
- 剑指Offer34 数组中的逆序对
/************************************************************************* > File Name: 34_Invers ...
- Table of Contents - jBPM
Getting Started jBPM Installer Eclipse 安装 jBPM 插件 jBPM Core
- MongoDB - The mongo Shell, Data Types in the mongo Shell
MongoDB BSON provides support for additional data types than JSON. Drivers provide native support fo ...
- 如何加密android apk
经过了忙碌的一周终于有时间静下来写点东西了,我们继续介绍android apk防止反编译技术的另一种方法.前两篇我们讲了加壳技术(http://my.oschina.net/u/2323218/blo ...
- ios开发:Core Data概述
Core Data 概述 2005年的四月份,Apple 发布了 OS X 10.4,在这个版本中 Core Data 框架发布了.Core Data本身既不是数据库也不是数据库访问框架.相反,Cor ...
- Difference between ref and out parameters
Original link: http://www.dotnet-tricks.com/Tutorial/csharp/K0Hb060414-Difference-between-ref-and-ou ...
- PCB常用度量衡单位
1英尺=12英寸 1英寸inch=1000密尔mil 1mil=25.4um 1mil=1000uin (mil密耳有时也成英丝) 1um=40uin(有些公司称微英寸为麦,其实是微英寸) 1OZ=2 ...
- 读取XML
public sealed class ConfigManger { public XDocument XmlDocs { set; get; } string path = @"{0}\C ...
- lower_bound和upper_bound
lower_bound:返回大于或等于val的第一个元素位置 upper_bound:返回大于val的第一个元素位置 两个函数用的都是二分查找