CubieBoard中文论坛

 找回密码
 立即注册
搜索
热搜: unable
查看: 12194|回复: 8

cubieboard2 gpio模拟keyboard 求教

[复制链接]
发表于 2015-1-21 19:56:53 | 显示全部楼层 |阅读模式
我现在用cubieboard2  PI11引脚外接了一个小button(python  读/sys/class/gpio/xxxx/value   正常,硬件没问题),我想实现按键模拟真实键盘的一个字符‘L’,不需要写测试驱动,直接使用的那种,就像我们电脑的键盘一样。  我现在照着2440的方法做的,但是总是失败。  想请教大家。下面是我2440的做法,我的代码和失败结果。

1.1.2440的链接,我是照着这个修改的
1.2440的链接,我是照着这个修改的

2.结果是:ls /dev/input  出现了一个event1的设备  
但是别的什么反应都没有了。

3.我的script.fex文件的gpio配置如下
  1. [gpio_para]
  2. gpio_used = 1
  3. gpio_num = 2
  4. gpio_pin_1 = port:PI11<0><1><default><default>
  5. gpio_pin_2 = port:PH21<1><default><default><1>
复制代码
4.我的代码
  1. <linux/kernel.h>
  2. #include <linux/fs.h>
  3. #include <linux/init.h>
  4. #include <linux/delay.h>
  5. #include <linux/irq.h>
  6. #include <asm/uaccess.h>
  7. #include <asm/irq.h>
  8. #include <asm/io.h>
  9. #include <linux/module.h>
  10. #include <linux/device.h>                 
  11. #include <linux/interrupt.h>  
  12. #include <linux/poll.h>   
  13. #include <linux/fcntl.h>
  14. #include <linux/input.h>
  15. #include<linux/cdev.h>
  16. #include<linux/wait.h>
  17. #include<mach/irqs.h>
  18. #include<plat/sys_config.h>
  19. #include<mach/system.h>
  20. #include<linux/slab.h>
  21. #include<linux/gpio.h>
  22. #include<asm/gpio.h>

  23. static struct pin_desc{
  24.         int irq;
  25.         unsigned char *name;
  26.         unsigned int pin;
  27.         unsigned int key_val;
  28. };


  29. static struct pin_desc pins_desc[4] = {
  30.                 {0,"K1",1,KEY_L},   
  31. };

  32. static struct pin_desc *irq_pd;
  33. static struct input_dev *buttons_dev;
  34. static struct timer_list buttons_timer;

  35. /* 用户中断处理函数 */
  36. static irqreturn_t buttons_irq(int irq, void *dev_id)
  37. {
  38.         irq_pd = (struct pin_desc *)dev_id;
  39.         
  40.         /* 修改定时器定时时间,定时10ms,即10秒后启动定时器
  41.          * HZ 表示100个jiffies,jiffies的单位为10ms,即HZ = 100*10ms = 1s
  42.          * 这里HZ/100即定时10ms
  43.          */
  44.         mod_timer(&buttons_timer, jiffies + (HZ /100));
  45.         printk(KERN_ALERT "irqreturn_t buttons_irq\n");
  46.         return IRQ_RETVAL(IRQ_HANDLED);
  47. }


  48. /* 定时器处理函数 */
  49. static void buttons_timer_function(unsigned long data)
  50. {
  51.         struct pin_desc *pindesc = irq_pd;
  52.         unsigned int pinval;
  53.         pinval = gpio_get_value(pindesc->pin);

  54.         if(pinval)
  55.         {
  56.                 /* 松开 最后一个参数: 0-松开, 1-按下 */
  57.                 input_event(buttons_dev,EV_KEY,pindesc->key_val,0);
  58.                 input_sync(buttons_dev);
  59.         }
  60.         else
  61.         {
  62.                 /* 按下 */
  63.                 input_event(buttons_dev,EV_KEY,pindesc->key_val,1);
  64.                 input_sync(buttons_dev);
  65.         }
  66.         printk(KERN_ALERT "buttons_timer_function\n");
  67. }

  68. /* 驱动入口函数 */
  69. static int buttons_input_init(void)
  70. {
  71.         int i;
  72.         int a20_irq[4];
  73.         a20_irq[0]=gpio_to_irq(1);

  74.         for(i = 0;i < sizeof(pins_desc)/sizeof(pins_desc[0]);i++)
  75.         {
  76.                 pins_desc[i].irq=a20_irq[i];
  77.         }
  78.         /* 1.分配一个input_dev结构体 */
  79.         buttons_dev = input_allocate_device();

  80.         /* 2.设置 */
  81.         /* 2.1 设置按键能产生哪类事件 */
  82.         set_bit(EV_KEY,buttons_dev->evbit);
  83.         set_bit(EV_REP,buttons_dev->evbit);

  84.         /* 2.2 设置能产生这类操作的哪些事件 */
  85.         set_bit(KEY_L,buttons_dev->keybit);
  86.         
  87.         
  88.         /* 3.注册 */
  89.         input_register_device(buttons_dev);

  90.         
  91.         /* 4.硬件相关的设置 */
  92.         /* 4.1 定时器相关的操作 */
  93.         init_timer(&buttons_timer);
  94.         buttons_timer.function = buttons_timer_function;
  95.         add_timer(&buttons_timer);

  96.         /* 4.2 申请中断 */  
  97.         for(i = 0;i < sizeof(pins_desc)/sizeof(pins_desc[0]);i++)
  98.         {
  99.                 int error=request_irq(pins_desc[i].irq, buttons_irq, IRQ_TYPE_EDGE_BOTH, pins_desc[i].name, &pins_desc[i]);
  100.                 if(error)
  101.                 {
  102.                         printk(KERN_ALERT "request irq error\n");
  103.                 }
  104.         }
  105.         printk(KERN_ALERT "buttons_input_init\n");
  106.         return 0;
  107. }

  108. /* 驱动出口函数 */
  109. static void buttons_input_exit(void)
  110. {
  111.         int i;
  112.         for(i = 0;i < sizeof(pins_desc)/sizeof(pins_desc[0]);i++)
  113.         {
  114.                 free_irq(pins_desc[i].irq, &pins_desc[i]);
  115.         }
  116.         del_timer(&buttons_timer);
  117.         input_unregister_device(buttons_dev);
  118.         input_free_device(buttons_dev);
  119.         printk(KERN_ALERT "buttons_input_exit\n");
  120. }

  121. module_init(buttons_input_init);  //用于修饰入口函数
  122. module_exit(buttons_input_exit);  //用于修饰出口函数        


  123. MODULE_LICENSE("GPL");  //遵循GPL协议
复制代码
回复

使用道具 举报

发表于 2015-1-21 21:05:45 | 显示全部楼层
一点都看不懂,感觉好难,帮顶
回复 支持 反对

使用道具 举报

发表于 2015-1-21 22:15:04 | 显示全部楼层
本帖最后由 jiangdou 于 2015-1-21 22:22 编辑



如果实现"L"按键值,供应用程序使用,,必须驱动上报到/dev/input/event_x

按键值,参考内核linux3.3/include/linux/input.h

#define KEY_L                        38


驱动层,GPIO必须配置成INT,中断模式
按键上报
    input_event(input, type, button->code, bdata->state);   //button->code = 38  .对应就是L按键值
    input_sync(input);
request_irq(irq, buttons_irq, ...)   这里必须注册成功,

或者  cat  /dev/input/event_x

或者读按键程序:
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/ioctl.h>
  4. #include <sys/types.h>
  5. #include <fcntl.h>

  6. #include <linux/input.h>

  7. #define INPUT_DEV "/dev/input/event0"

  8. int main(int argc, char *argv[])
  9. {
  10.         int         devfd;
  11.         struct         input_event input_event;

  12.         devfd = open(INPUT_DEV, O_RDONLY);
  13.         if(devfd <= 0){
  14.                 printf("Open INPUT_DEV Error!\n");
  15.                 return -1;
  16.         }
  17.         while(1){
  18.                 read(devfd, &input_event, sizeof(input_event));
  19.                
  20.                 printf("EventType:");
  21.                 switch(input_event.type){
  22.                         case EV_SYN:
  23.                                 printf("EV_SYN, ");
  24.                                 break;
  25.                         case EV_KEY:
  26.                                 printf("EV_KEY, ");
  27.                                 break;
  28.                         default:
  29.                                 printf("<Others>, ");
  30.                                 break;
  31.                 }
  32.                 printf("EventCode:");
  33.                 switch(input_event.code){
  34.                         case KEY_LEFT:
  35.                                 printf("KEY_LEFT, ");
  36.                                 break;
  37.                         case KEY_RIGHT:
  38.                                 printf("KEY_RIGHT, ");
  39.                                 break;
  40.                         case KEY_UP:
  41.                                 printf("KEY_UP, ");
  42.                                 break;
  43.                         case KEY_DOWN:
  44.                                 printf("KEY_DOWN, ");
  45.                                 break;
  46.                         case KEY_ENTER:
  47.                                 printf("KEY_ENTER, ");
  48.                                 break;
  49.                         case KEY_ESC:
  50.                                 printf("KEY_ESC, ");
  51.                                 break;
  52.                         default:
  53.                                 printf("<Others input_event.code = %d>,",input_event.code);
  54.                                 break;
  55.                 }
  56.                 printf("EventValue:");
  57.                 switch(input_event.value){
  58.                         case 0:
  59.                                 printf("UP.\n");
  60.                                 break;
  61.                         case 1:
  62.                                 printf("DOWN.\n");
  63.                                 break;
  64.                         default:
  65.                                 printf("<Others>.\n");
  66.                                 break;
  67.                 }
  68.         }
  69.         close(devfd);
  70.         return 0;
  71. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2015-1-21 23:13:32 | 显示全部楼层
jiangdou 发表于 2015-1-21 22:15
如果实现"L"按键值,供应用程序使用,,必须驱动上报到/dev/input/event_x

按键值,参考内核linux3.3/in ...

楼上大神都是怎么学习的啊,懂这么多
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-22 08:55:42 | 显示全部楼层
jiangdou 发表于 2015-1-21 22:15
如果实现"L"按键值,供应用程序使用,,必须驱动上报到/dev/input/event_x

按键值,参考内核linux3.3/in ...

您好,谢谢您的回答。
您说的几点我都注意了,是对的。
1.#define KEY_L                        38
我的代码里已经包含input.h了,里面有这个宏
2.驱动层,GPIO必须配置成INT,中断模式
fex文件中gpio_pin_1 = portI11<0><1><default><default>已经设置为INT模式了
代码110行的那个for循环就是中断的
3. input_event(input, type, button->code, bdata->state);   //button->code = 38  .对应就是L按键值input_sync(input);
这两点我的代码也是完全对的
71行:input_event(buttons_dev,EV_KEY,pindesc->key_val,1);
72行:input_sync(buttons_dev);
4.request_irq(irq, buttons_irq, ...)   这里必须注册成功,
这个函数我用printk调试的,完全注册成功的。
代码114-117行就是调试,开发板中我inmod xxx.ko后显示的是注册成功。


请问还有别的地方有问题吗。谢谢。
回复 支持 反对

使用道具 举报

发表于 2015-1-22 11:28:08 | 显示全部楼层
请问有什么报错的log吗?串口有打印吗??   
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-22 11:56:19 | 显示全部楼层
问题已解决,晚上共享出来。 这个驱动搞了六天了。
回复 支持 反对

使用道具 举报

发表于 2015-1-22 16:02:52 | 显示全部楼层
快乐生活 发表于 2015-1-22 11:56
问题已解决,晚上共享出来。 这个驱动搞了六天了。

学习过程分享,十分支持!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-22 20:59:44 | 显示全部楼层
本帖最后由 快乐生活 于 2015-1-22 21:19 编辑

这个帖子的问题已经解决,已经发新帖了。
http://cubie.cc/forum.php?mod=vi ... amp;extra=#pid26550

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|粤ICP备13051116号|cubie.cc---深刻的嵌入式技术讨论社区

GMT+8, 2024-5-5 10:10 , Processed in 0.023795 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2012 Comsenz Inc. | Style by Coxxs

返回顶部