首先需要了解sys节点和linux驱动编程的知识,在linux内核<linux/>下有着对应的实现。本例实现创建sys节点,外围程序通过input子系统控制鼠标位置。

第一步编写驱动代码,创建sys节点:

    1. #include <linux/module.h>
    2. #include <linux/platform_device.h>
    3. #include <linux/slab.h>
    4. #include <linux/input.h>
    5. #include <linux/kthread.h>
    6. #include <linux/semaphore.h>
    7. struct v_dev{
    8. struct platform_device *p_dev;
    9. struct input_dev *input;
    10. int x;
    11. int y;
    12. struct task_struct *run_thread;
    13. struct semaphore sem;
    14. };
    15. struct v_dev *vmouse_dev = NULL;
    16. static ssize_t write_pos(struct device *dev, struct device_attribute *attr,
    17. const char *buf, size_t count)
    18. {
    19. int x,y;
    20. sscanf(buf,"%d%d",&x,&y);
    21. vmouse_dev->x = x;
    22. vmouse_dev->y =y;
    23. //post 信号量
    24. up(&vmouse_dev->sem);
    25. return count;
    26. }
    27. static ssize_t show_pos(struct device *dev, struct device_attribute *attr,
    28. char *buf){
    29. return sprintf(buf,"(%d,%d)\n",vmouse_dev->x,vmouse_dev->y);
    30. }
    31. DEVICE_ATTR(pos,0644,show_pos,write_pos);
    32. static int vmouse_thread(void *data)
    33. {
    34. int x,y;
    35. struct v_dev *vmouse_dev = (struct v_dev*)data;
    36. struct semaphore *sema = &(vmouse_dev->sem);
    37. printk(KERN_INFO "vmouse thread running\n");
    38. while(1){
    39. //等待信号量
    40. while((down_interruptible(sema)) == -EINTR){} ;
    41. x = vmouse_dev->x;
    42. y = vmouse_dev->y;
    43. input_report_abs(vmouse_dev->input,ABS_X,x);
    44. input_report_abs(vmouse_dev->input,ABS_Y,y);
    45. input_sync(vmouse_dev->input);
    46. printk("vmouse thread report\n");
    47. }
    48. return 0;
    49. }
    50. static int vmouse_probe(struct platform_device *pdev)
    51. {
    52. int ret = -1;
    53. printk("%s debug \n",__func__);
    54. if(vmouse_dev->p_dev == pdev){
    55. printk("platform device is same\n");
    56. }
    57. vmouse_dev->input = input_allocate_device();
    58. if(!(vmouse_dev->input)){
    59. printk("%s request input deivce error\n",__func__);
    60. goto alloc_input;
    61. }
    62. vmouse_dev->input->name = "vmouse";
    63. set_bit(EV_ABS,vmouse_dev->input->evbit);
    64. input_set_abs_params(vmouse_dev->input, ABS_X, -1024, 1024, 0, 0);
    65. input_set_abs_params(vmouse_dev->input, ABS_Y, -1024, 1024, 0, 0);
    66. ret = input_register_device(vmouse_dev->input);
    67. if(ret < 0){
    68. printk("%s register input device error\n",__func__);
    69. goto input_register;
    70. }
    71. device_create_file(&pdev->dev,&dev_attr_pos);
    72. //初始化信号量,在线程中要用到
    73. sema_init(&(vmouse_dev->sem),0);
    74. vmouse_dev->run_thread = kthread_run(vmouse_thread,vmouse_dev,"vmouse_thread");
    75. return 0;
    76. input_register:
    77. input_free_device(vmouse_dev->input);
    78. alloc_input:
    79. kfree(vmouse_dev);
    80. return ret;
    81. }
    82. static struct platform_driver vmouse_driver = {
    83. .probe = vmouse_probe,
    84. .driver = {
    85. .owner = THIS_MODULE,
    86. .name = "v_mouse",
    87. },
    88. };
    89. static int __init vmouse_init(void)
    90. {
    91. int ret =-1;
    92. printk("%s\n", __func__);
    93. vmouse_dev = kzalloc(sizeof(struct v_dev),GFP_KERNEL);
    94. if(vmouse_dev == NULL){
    95. printk("%s alloc memory  error\n",__func__);
    96. return -ENOMEM;
    97. }
    98. vmouse_dev->p_dev= platform_device_register_simple("v_mouse",-1,NULL,0);
    99. if(!(vmouse_dev->p_dev)){
    100. printk("%s register platform device error\n",__func__);
    101. return ret;
    102. }
    103. ret = platform_driver_register(&vmouse_driver);
    104. if(ret < 0){
    105. printk("%s register driver error\n",__func__);
    106. return ret;
    107. }
    108. return 0;
    109. }
    110. static void __exit vmouse_exit(void)
    111. {
    112. printk("%s\n", __func__);
    113. if(vmouse_dev->input != NULL){
    114. input_unregister_device(vmouse_dev->input);
    115. }
    116. printk("%s debug__1\n",__func__);
    117. if(vmouse_dev != NULL){
    118. platform_device_unregister(vmouse_dev->p_dev);
    119. }
    120. printk("%s debug__2\n",__func__);
    121. platform_driver_unregister(&vmouse_driver);
    122. printk("%s debug__3\n",__func__);
    123. kfree(vmouse_dev);
    124. printk("%s debug__4\n",__func__);
    125. }
    126. module_init(vmouse_init);
    127. module_exit(vmouse_exit);
    128. MODULE_LICENSE("GPL");
    129. MODULE_AUTHOR("oracleloyal@gmail.com“);
    130. 编写makefile:
    131. 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
    132. 在当前makefile路径下执行make
    133. sudo insmod **.ko
    134. 加载驱动---会在/sys/devices/platform下出现节点,并且/dev/input下会出先对应的可读写的节点。
    135. 驱动的卸载sudo rmmod modules
    136. 编写测试程序:
      1. #include <fcntl.h>
      2. #include <linux/input.h>
      3. #include <stdio.h>
      4. //要看自己的节点了  ---》特别注意去看自己多出的到底是哪个节点这里需要改动哦
      5. #define EVENT_DEV "/dev/input/event5"
      6. int main(void)
      7. {
      8. struct input_event ev;
      9. int count,x,y;
      10. int fd = open(EVENT_DEV, O_RDWR);
      11. if(fd < 0){
      12. printf("open %s failed\n",EVENT_DEV);
      13. return 0;
      14. }
      15. while(1){
      16. count = read(fd, &ev,sizeof(struct input_event));
      17. if(EV_ABS == ev.type){
      18. if(ev.code == ABS_X){
      19. x = ev.value;
      20. }else if(ev.code == ABS_Y){
      21. y = ev.value;
      22. }
      23. printf("position: x=%d, y=%d\n",x,y);
      24. }else if(EV_SYN == ev.type){
      25. puts("sync!");
      26. }
      27. }
      28. return 0;
      29. }
      30. 先运行应用程序:./test_sys  
        在另一个终端执行:echo "90 90" >/sys/devices/platform/v_mouse/pos

        你就会看到你input设备上报的坐标,打印信息如下:

        position: x=90, y=0
        position: x=90, y=90
        sync!

      31. 完毕!

鼠标驱动之-sys节点-input子系统的更多相关文章

  1. 基于input子系统的sensor驱动调试(二)

    继上一篇:http://www.cnblogs.com/linhaostudy/p/8303628.html#_label1_1 一.驱动流程解析: 1.模块加载: static struct of_ ...

  2. 【驱动】input子系统整体流程全面分析(触摸屏驱动为例)【转】

    转自:http://www.cnblogs.com/lcw/p/3294356.html input输入子系统整体流程 input子系统在内核中的实现,包括输入子系统(Input Core),事件处理 ...

  3. input子系统驱动学习之中的一个

        刚開始学习linux这门课就被分配编写一个设备的input子系统驱动.这对我的确有点困难.只是实际的操作中发现困难远比我想象的要大的多.本以为依照老师课上的步骤就行非常快的完毕这项任务.后来发 ...

  4. input子系统分析

    ------------------------------------------ 本文系本站原创,欢迎转载! 转载请注明出处:http://ericxiao.cublog.cn/ -------- ...

  5. linux input输入子系统分析《四》:input子系统整体流程全面分析

    1      input输入子系统整体流程 本节分析input子系统在内核中的实现,包括输入子系统(Input Core),事件处理层(Event Handler)和设备驱动层.由于上节代码讲解了设备 ...

  6. Linux usb子系统(一) _写一个usb鼠标驱动

    USB总线是一种典型的热插拔的总线标准,由于其优异的性能几乎成为了当下大小设备中的标配. USB的驱动可以分为3类:SoC的USB控制器的驱动,主机端USB设备的驱动,设备上的USB Gadget驱动 ...

  7. 【驱动】input子系统全面分析

    初识linux输入子系统 linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(InputC ...

  8. Linux 驱动框架---input子系统

    input 子系统也是作为内核的一个字符设备模块存在的,所以他也是字符设备自然也会有字符设备的文件接口.input子系统的注册过程主要分为两步,先注册了一个input class然后再注册一个字符设备 ...

  9. 基于input子系统的sensor驱动调试(一)

    要想弄明白世界的本质,就要追根溯源:代码也是一样的道理: 最近调试几个sensor驱动,alps sensor驱动.compass sensor驱动.G-sensor驱动都是一样的架构: 一.基于in ...

随机推荐

  1. Kinect For Windows V2开发日志三:简单的深度读取

    代码示例: #include <Kinect.h> #include <iostream> using namespace std; int main(void) { IKin ...

  2. 第五节 关于SpringMVC中Ajax的配置和应用[下午]

    成熟,不是学会表达,而是学会咽下,当你一点一点学会克制住很多东西,才能驾驭好人生. 还有一周,祥云19就算结算了,一个半月的相处希望,胖先生算一个合格的老师 小白,小蔡,2婷婷,小猴,小恒,小崔,小龙 ...

  3. IOS iphone 4inch上应用没有全屏,上下有黑边(转)

    在编写IOS应用程序的过程中,我一直都是使用iPhone Retina(3.5-inch)模拟器测试的,一切显示正常,切图如下: 我在应用开发中,采用的是纯代码实现.公司提供了一部iPhone4s,我 ...

  4. 【转】loadrunner场景对性能测试策略的映射

    性能测试策略 LoadRunner性能测试场景 压力测试 面向目标测试场景+忽略think time 负载测试 手工测试场景+同步点+think time+虚拟IP+带宽模拟…… 并发测试 同步点+多 ...

  5. CSS hacker(兼容IE6、7、8)

    <meta http-equiv="X-UA-Compatible"  content="IE=edge,chrome=1">这行代码是永远以最新的 ...

  6. ASP.NET Ajax简单的无刷新分页

    最近练习了一些AJAX无刷新分页,写得比较简单,性能不知道怎么样,求大神指点,如有更好的分页提供,欢迎交流! 发话不多说了,直接上代码! 首先从网上下了一个JS分页,感觉挺好用的 (function( ...

  7. 浅谈.NET Micro Framework性能优化 转自 软件中国

    .NET Micro Framework的可剪裁性,高定执行,和天生对硬件高集成度都让它的前途一片光明.当然,它现在还很年轻,就发布的SDK v3.0来看,它还有很长的路要走. 废话不说,就这几个月我 ...

  8. Sql Server CTE递归

    WITH cte AS ( SELECT a.FNUMBER,a.FMATERIALID AS MainId,b.FMATERIALID AS ChileID,CAST(b.FMATERIALID A ...

  9. Java之奇偶组合

    写一个函数,将已知数组的奇数项组合成一个新的数组,在函数中调用该数组,并且输出新数组的内容. 定义一个数组,该数组为{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 ...

  10. spring3+struts2+hibernate3整合出现的问题,No mapping found for dependency [type=java.lang.String, name='struts.objectFactory.spring.enableAopSupport']

    七月 11, 2016 3:49:24 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin警告: [SetPropertiesRule ...