IT技术互动交流平台

arm板子使用GPIO-keys驱动方法及测试程序

来源:牛蹄印章博客  发布日期:2012-09-17 09:12:50

Linux 内核下的 drivers/input/keyboard/gpio_keys.c实现了一个体系结构无关的GPIO按键驱动,使用此按键驱动,只需在arch/arm/mach-s3c2410/mach-smdk2410.c中定义相关的数据即可。驱动的实现非常简单,但是较适合于实现独立式按键驱动,且按键所接端口为中断引脚,如本书硬件平台矩阵按键对应的EINT0,EINT2,EINT11,EINT19中断对应的引脚。如果是矩阵按键,相应代码的改动较大,不宜提倡。

假设在S3C2410开发平台上, 使用GPG3,GPG11,GPF0,GPF2实现了DOWN、ENTER、HOME、POWER四个按键,该法实现驱动程序首先在头文件位置键入以下头文件:

 

#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <asm/arch/regs-gpio.h>//S3C2410各个端口定义

然后在mach-smdk2410.c中键入按键的定义信息:

static struct gpio_keys_button s3c2410_buttons [ ] = {
{
.gpio = S3C2410_GPG3,
.code = KEY_DOWN,
.desc = "Down" ,
.active_low = 1,
},

{
.gpio = S3C2410_GPG11,
.code = KEY_ENTER,
.desc = "Enter " ,
.active_low = 1,
},

{
.gpio = S3C2410_GPF0,
.code = KEY_HOME,
.desc = "Home" ,
.active_low = 1,
},

{
.gpio = S3C2410_GPF2,
.code = KEY_POWER,
.desc = "Power " ,
.active_low = 1,
},
};

static struct gpio_keys_platform_data s3c2410_button_data = {
.buttons = s3c2410_buttons,
.nbuttons = ARRAY_SIZE(s3c2410_buttons) ,
};

static struct platform_device s3c2410_device_button = {
     .name = "gpio-keys",
     .id =-1,
     .dev = {
     .platform_data = &s3c2410_button_data,
}
};

其中
n   gpio是连接按键的IO管脚。
n   code是这个按键上报的键值, 在input.h中定义。
n   desc是按键的name。
n   active_low为1是表示低电平触发。 www.it165.net
将“&s3c2410_device_button,”语句填入 struct platform_device *s3c2410_devices[]数组,作为该数组的一个成员。

 

static struct platform_device *smdk2410_devices[] __initdata = {
     &s3c_device_usb,
     &s3c_device_lcd,
     &s3c_device_wdt,
     &s3c_device_i2c,
     &s3c_device_iis,
     &s3c_device_rtc,
     &s3c_device_ts,
     &s3c2410_device_button,};

编译内核时选择:

Device Drivers >

Input device support >

[*] Keyboards

<*> GPIO Buttons

如果要修改按键对应的GPIO和键值,只需要简单的修改s3c2410_buttons[]数组中的内容。

这样在内核的启动过程中,会发现如下的提示:

input: gpio-keys as /class/input/input0

同时在文件系统dev目录下有event0设备节点,event1是触摸屏节点,对gpio-keys按键的访问可以通过event0来完成。


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <time.h>
#include <fcntl.h>
#include <linux/input.h>
int main(int argc, char **argv)
{
     int key_state;
     int fd;
     int ret;
     int code;
     struct input_event buf;
     int repeat_param[2];
     fd = open("/dev/input/event0", O_RDONLY);
     if (fd < 0) 
     {
         printf("Open gpio-keys failed.\n");
         return -1;
  }
  else
  {
     printf("Open gpio-keys success.\n");
  }
     repeat_param[0]=500;//ms重复按键第一次间隔
     repeat_param[1]=66;//ms重复按键后续间隔
     ret = ioctl(fd,EVIOCSREP,(int *)repeat_param);//设置重复按键参数
     if(ret != 0)
         {
                   printf("set repeat_param fail!\n");
         }
     else
         {
                printf("set repeat_param ok.\n");
         }

     while(1)
     {
         ret = read(fd,&buf,sizeof(struct input_event));
         if(ret <= 0)
              {
                   printf("read fail!\n");
                   return -1;
              }

       code = buf.code;
       key_state = buf.value;
       switch(code)
       {
          case KEY_DOWN:
              code = '1';
              break;
          case KEY_ENTER:
              code = '2';
              break;
          case KEY_HOME:
              code = '3';
              break;
          case KEY_POWER:
              code = '4';
              break;
          default:
              code = 0;
              break;
       }

       if(code!=0)
          {
           printf("Key_%c state= %d.\n",code,key_state);
         }
     }
     close(fd);
     printf("Key test finished.\n");  
     return 0;
}

上述按键驱动涉及到Linux内核的platform设备驱动模型相关知识,读者可自行参考相关内容。

延伸阅读:

Tag标签: arm板子   GPIO-keys驱动  
  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规