zoukankan      html  css  js  c++  java
  • 20150218【改进】IMX257实现GPIO-IRQ中断按键获取键值驱动程序

    【改进】IMX257实现GPIO-IRQ中断按键获取键值驱动程序

    2015-02-18 李海沿

    一、使用struct pin_desc 管理按键的值

    1.定义结构体

    2.将前面我们申请中断时写的(void *)1修改为 &pins_desc[n]

    在ioctl中,设置中断中修改

    在key_release中释放中修改

    3.在中断程序中利用我们定义的struc pins_desc判断并得到按键的值

    4.得到按键键值后,唤醒程序,在read函数中返回键值

    附上驱动源程序:

      1 /******************************
      2     linux key_query
      3  *****************************/
      4 #include <linux/module.h>
      5 #include <linux/init.h>
      6 #include <linux/kernel.h>
      7 #include <linux/delay.h>
      8 #include <linux/types.h>
      9 #include <linux/ioctl.h>
     10 #include <linux/gpio.h>
     11 #include <linux/fs.h>
     12 #include <linux/device.h>
     13 #include <linux/uaccess.h>
     14 #include <linux/irq.h>
     15 #include <linux/wait.h>
     16 #include <linux/sched.h>//error: 'TASK_INTERRUPTIBLE' undeclared 
     17 #include <linux/interrupt.h>
     18 
     19 #include "mx257_gpio.h"
     20 #include "mx25_pins.h"
     21 #include "iomux.h"
     22 
     23 #define Driver_NAME "key_interrupt"
     24 #define DEVICE_NAME "key_interrupt"
     25 
     26 #define GPIO2_21    MX25_PIN_CLKO
     27 #define GPIO3_15    MX25_PIN_EXT_ARMCLK
     28 #define GPIO2_10    MX25_PIN_A24
     29 #define GPIO2_11    MX25_PIN_A25
     30 #define GPIO2_8     MX25_PIN_A22
     31 #define GPIO2_9     MX25_PIN_A23
     32 #define GPIO2_6     MX25_PIN_A20
     33 #define GPIO2_7     MX25_PIN_A21
     34 //command
     35 #define key_input     0
     36 #define version        1
     37 //定义各个按键按下的键值
     38 struct pin_desc{
     39     unsigned int pin;
     40     unsigned int key_val;
     41 };
     42 //当按键按下时,键值分别为 以下值
     43 struct pin_desc pins_desc[8] = {
     44     {GPIO2_6,    0x01},
     45     {GPIO2_7,    0x02},
     46     {GPIO2_8,    0x03},
     47     {GPIO2_9,    0x04},
     48     {GPIO2_10,    0x05},
     49     {GPIO2_11,    0x06},
     50     {GPIO2_21,    0x07},
     51     {GPIO3_15,    0x08},
     52 };
     53 //定义一个全局变量,用于保存按下的键值
     54 static unsigned int key_val;
     55 
     56 //interrupt head
     57 static DECLARE_WAIT_QUEUE_HEAD(key_interrupt_wait);
     58 static volatile unsigned char ev_press;  
     59 
     60 static int major=0;
     61 
     62 //auto to create device node
     63 static struct class *drv_class = NULL;
     64 static struct class_device *drv_class_dev = NULL;
     65 
     66 
     67 /* 应用程序对设备文件/dev/key_query执行open(...)时,
     68  * 就会调用key_open函数*/
     69 static int key_open(struct inode *inode, struct file *file)
     70 {
     71     printk("<0>function open!
    
    ");
     72     
     73     return 0;
     74 }
     75 
     76 /* 中断程序key_irq */
     77 static irqreturn_t key_irq(int irq, void *dev_id)
     78 {
     79     struct pin_desc * pindesc = (struct pin_desc *)dev_id;
     80     //发生了中断
     81     //printk("<0>function interrupt key_irq!
    
    ");
     82     //获取按键键值
     83     if(gpio_get_value(IOMUX_TO_GPIO(pindesc->pin))){
     84         /* 按下 */
     85         key_val = pindesc->key_val;
     86     }else{
     87         key_val = 0x80 | pindesc->key_val;
     88     }
     89     printk("<0>get key 0x%x",key_val);    
     90     ev_press = 1;
     91     wake_up_interruptible(&key_interrupt_wait);
     92 
     93     return IRQ_RETVAL(IRQ_HANDLED);
     94 }
     95 
     96 
     97 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
     98 {
     99     int ret;
    100     //如果按键没有按下,没有中断,休眠
    101     wait_event_interruptible(key_interrupt_wait,ev_press);
    102 
    103     ret = copy_to_user(buff,&key_val,sizeof(key_val));
    104     if(ret){
    105         ;
    106     }
    107     ev_press = 0;
    108     return sizeof(key_val);
    109 
    110     //int cnt=0;
    111     //unsigned char key_vals[8];
    112 
    113     /*
    114     // reading the pins value
    115     key_vals[0] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_6)) ? 1 : 0;
    116     key_vals[1] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_7)) ? 1 : 0;
    117     key_vals[2] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_8)) ? 1 : 0;
    118     key_vals[3] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_9)) ? 1 : 0;
    119     key_vals[4] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_10)) ? 1 : 0;
    120     key_vals[5] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_11)) ? 1 : 0;
    121     key_vals[6] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_21)) ? 1 : 0;
    122     key_vals[7] = gpio_get_value(IOMUX_TO_GPIO(GPIO3_15)) ? 1 : 0;
    123     
    124     //printk("<0>%04d key pressed: %d %d %d %d %d %d %d %d
    ",cnt++,key_vals[0],key_vals[1],key_vals[2],key_vals[3],key_vals[4],key_vals[5],key_vals[6],key_vals[7]); 
    125     */
    126 }
    127 
    128 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
    129 {
    130     printk("<0>function write!
    
    ");
    131     
    132     return 1;
    133 }
    134 
    135 static int  key_release(struct inode *inode, struct file *filp)
    136 {
    137     printk("<0>function release!
    
    ");
    138     //释放中断
    139     free_irq(IOMUX_TO_IRQ(GPIO2_21),  &pins_desc[6]);
    140     //free_irq(IOMUX_TO_IRQ(GPIO3_15),&pins_desc[7]);
    141     free_irq(IOMUX_TO_IRQ(GPIO2_11),  &pins_desc[5]);
    142     free_irq(IOMUX_TO_IRQ(GPIO2_10),  &pins_desc[4]);
    143     free_irq(IOMUX_TO_IRQ(GPIO2_9),   &pins_desc[3]);
    144     //free_irq(IOMUX_TO_IRQ(GPIO2_8), &pins_desc[2]);
    145     free_irq(IOMUX_TO_IRQ(GPIO2_7),   &pins_desc[1]);
    146     free_irq(IOMUX_TO_IRQ(GPIO2_6),   &pins_desc[0]);
    147     return 0;
    148 }
    149 
    150 static int key_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)
    151 {
    152     int ret;
    153     printk("<0>function ioctl!
    
    ");
    154     switch (command) {
    155         case key_input:    
    156             //设置所有的引脚为输入
    157             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_21));
    158             gpio_direction_input(IOMUX_TO_GPIO(GPIO3_15));
    159             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_10));
    160             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_11));
    161             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_8));
    162             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_9));
    163             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_6));
    164             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_7));
    165             printk("<0>have setting all pins to gpio input mod !
    ");
    166             //设置GPIO引脚为上拉模式
    167             mxc_iomux_set_pad(GPIO2_6, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
    168             mxc_iomux_set_pad(GPIO2_7, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
    169             //mxc_iomux_set_pad(GPIO2_8, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
    170             mxc_iomux_set_pad(GPIO2_9, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
    171             mxc_iomux_set_pad(GPIO2_10, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
    172             mxc_iomux_set_pad(GPIO2_11, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
    173             mxc_iomux_set_pad(GPIO2_21, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
    174             //mxc_iomux_set_pad(GPIO3_15, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
    175 
    176             //设置GPIO引脚中断  ,下降沿触发
    177             request_irq(IOMUX_TO_IRQ(GPIO2_6), key_irq, IRQF_TRIGGER_FALLING, "key_GPIO2_6", &pins_desc[0]);
    178             request_irq(IOMUX_TO_IRQ(GPIO2_7), key_irq, IRQF_TRIGGER_FALLING, "key_GPIO2_7", &pins_desc[1]);
    179             request_irq(IOMUX_TO_IRQ(GPIO2_9), key_irq, IRQF_TRIGGER_FALLING, "key_GPIO2_9", &pins_desc[3]);
    180             request_irq(IOMUX_TO_IRQ(GPIO2_10), key_irq, IRQF_TRIGGER_FALLING, "key_GPIO2_10", &pins_desc[4]);
    181             request_irq(IOMUX_TO_IRQ(GPIO2_11), key_irq, IRQF_TRIGGER_FALLING, "key_GPIO2_11", &pins_desc[5]);
    182             request_irq(IOMUX_TO_IRQ(GPIO2_21), key_irq, IRQF_TRIGGER_FALLING, "key_GPIO2_21", &pins_desc[6]);
    183             //request_irq(IOMUX_TO_IRQ(GPIO3_15), key_irq, IRQF_TRIGGER_FALLING, "key_GPIO3_15", &pins_desc[7]);
    184             //request_irq(IOMUX_TO_IRQ(GPIO2_8), key_irq, IRQF_TRIGGER_FALLING, "key_GPIO2_8", &pins_desc[2]);
    185             printk("<0>have setting all pins to gpio interrupt mod by IRQF_TRIGGER_FALLING !
    ");
    186 
    187             break;
    188         case version:
    189             printk("<0>hello,the version is 0.1.0
    
    ");
    190             break;
    191         default:
    192               printk("<0>command error 
    ");
    193             printk("<0>ioctl(fd, (unsigned int)command, (unsigned long) arg;
    ");
    194             printk("<0>command: <key_input> <version>
    
    ");
    195             return -1;
    196     }
    197     return 0;    
    198 }
    199 
    200 /* 这个结构是字符设备驱动程序的核心
    201  * 当应用程序操作设备文件时所调用的open、read、write等函数,
    202  * 最终会调用这个结构中指定的对应函数
    203  */
    204 static struct file_operations key_fops = {
    205     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
    206     .open   =   key_open,     
    207     .read    =    key_read,       
    208     .write    =    key_write,       
    209     .release=   key_release,
    210     .ioctl  =   key_ioctl,    
    211 };
    212     
    213 /*
    214  * 执行insmod命令时就会调用这个函数 
    215  */
    216 static int __init  key_irq_init(void)
    217 {
    218     printk("<0>
    Hello,this is %s module!
    
    ",Driver_NAME);
    219     //register and mknod
    220     major = register_chrdev(0,Driver_NAME,&key_fops);
    221     drv_class = class_create(THIS_MODULE,Driver_NAME);
    222     drv_class_dev = device_create(drv_class,NULL,MKDEV(major,0),NULL,DEVICE_NAME);    /*/dev/key_query*/
    223 
    224     //set all pins to GPIO mod  ALF5
    225     mxc_request_iomux(GPIO2_21, MUX_CONFIG_ALT5);
    226     mxc_request_iomux(GPIO3_15, MUX_CONFIG_ALT5);
    227       mxc_request_iomux(GPIO2_10, MUX_CONFIG_ALT5);
    228        mxc_request_iomux(GPIO2_11, MUX_CONFIG_ALT5);
    229     mxc_request_iomux(GPIO2_8, MUX_CONFIG_ALT5);
    230     mxc_request_iomux(GPIO2_9, MUX_CONFIG_ALT5);
    231     mxc_request_iomux(GPIO2_6, MUX_CONFIG_ALT5);
    232     mxc_request_iomux(GPIO2_7, MUX_CONFIG_ALT5);
    233     //request IOMUX GPIO
    234     gpio_request(IOMUX_TO_GPIO(GPIO2_21), "GPIO2_21");
    235      gpio_request(IOMUX_TO_GPIO(GPIO3_15), "GPIO3_15");
    236      gpio_request(IOMUX_TO_GPIO(GPIO2_10), "GPIO2_10");
    237        gpio_request(IOMUX_TO_GPIO(GPIO2_11), "GPIO2_11");
    238     gpio_request(IOMUX_TO_GPIO(GPIO2_8), "GPIO2_8");
    239      gpio_request(IOMUX_TO_GPIO(GPIO2_9), "GPIO2_9");
    240       gpio_request(IOMUX_TO_GPIO(GPIO2_6), "GPIO2_6");
    241     gpio_request(IOMUX_TO_GPIO(GPIO2_7), "GPIO2_7");
    242     
    243     return 0;
    244 }
    245 
    246 /*
    247  * 执行rmmod命令时就会调用这个函数 
    248  */
    249 static void __exit key_irq_exit(void)
    250 {
    251     printk("<0>
    Goodbye,%s!
    
    ",Driver_NAME);
    252 
    253     unregister_chrdev(major,Driver_NAME);
    254     device_unregister(drv_class_dev);
    255     class_destroy(drv_class);
    256 
    257     /* free gpios */
    258     mxc_free_iomux(GPIO2_21, MUX_CONFIG_ALT5);
    259     mxc_free_iomux(GPIO3_15, MUX_CONFIG_ALT5);
    260     mxc_free_iomux(GPIO2_10, MUX_CONFIG_ALT5);
    261     mxc_free_iomux(GPIO2_11, MUX_CONFIG_ALT5);
    262     mxc_free_iomux(GPIO2_8, MUX_CONFIG_ALT5);
    263     mxc_free_iomux(GPIO2_9, MUX_CONFIG_ALT5);
    264     mxc_free_iomux(GPIO2_6, MUX_CONFIG_ALT5);
    265     mxc_free_iomux(GPIO2_7, MUX_CONFIG_ALT5);
    266 
    267     gpio_free(IOMUX_TO_GPIO(GPIO2_21));
    268     gpio_free(IOMUX_TO_GPIO(GPIO3_15));
    269     gpio_free(IOMUX_TO_GPIO(GPIO2_10));
    270     gpio_free(IOMUX_TO_GPIO(GPIO2_11));
    271     gpio_free(IOMUX_TO_GPIO(GPIO2_8));
    272     gpio_free(IOMUX_TO_GPIO(GPIO2_9));
    273     gpio_free(IOMUX_TO_GPIO(GPIO2_6));
    274     gpio_free(IOMUX_TO_GPIO(GPIO2_7));
    275 
    276 }
    277 /* 这两行指定驱动程序的初始化函数和卸载函数 */
    278 module_init(key_irq_init);
    279 module_exit(key_irq_exit);
    280 
    281 /* 描述驱动程序的一些信息,不是必须的 */
    282 MODULE_AUTHOR("Lover雪");
    283 MODULE_VERSION("0.1.0");
    284 MODULE_DESCRIPTION("IMX257 key Driver");
    285 MODULE_LICENSE("GPL");
    View Code

    附上应用程序代码:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <unistd.h>
     4 #include <sys/types.h>
     5 #include <sys/stat.h>
     6 #include <fcntl.h>
     7 #include <termios.h>
     8 #include <errno.h>
     9 #include <limits.h>
    10 #include <asm/ioctls.h>
    11 #include <time.h>
    12 #include <pthread.h>
    13 
    14 #include "mx257_gpio.h"
    15 
    16 #define key_input     0
    17 #define version       1
    18 
    19 
    20 int main(int argc, char **argv)
    21 {
    22     int fd;
    23     int i=0,cnt=0;
    24     unsigned char key_val[1];
    25     
    26     fd = open("/dev/key_interrupt",O_RDWR);
    27     if(fd < 0){
    28         printf("can't open !!!
    ");
    29     }
    30     ioctl(fd,version,NULL);
    31     ioctl(fd,key_input,NULL);
    32     while(1){
    33         read(fd,key_val,sizeof(key_val));
    34         printf("%04d key pressed: 0x%x
    ",cnt++,key_val[0]);    
    35     }
    36     return 0;
    37 }
    View Code

    结果如图所用 insmod key_interrupt.ko

    后台运行应用程序 ./test/key_test &

    查看中断 cat /proc/interrupts

    ps,查看我们后台的进程号,使用kill函数时,驱动程序会自动进入release函数,释放中断号。

  • 相关阅读:
    Cocos2d-x之Vector<T>
    Cocos2d-x之Array
    Cocos2d-x之Value
    Cocos2d-x之String
    Cocos2d-x中使用的数据容器类
    Cocos2d-x之Action
    Cocos2d-x之定时器
    Cocos2d-x之MessageBox
    Cocos2d-x之Log输出机制
    Cocos2d-x之事件处理机制
  • 原文地址:https://www.cnblogs.com/lihaiyan/p/4295957.html
Copyright © 2011-2022 走看看