嵌入式LINUX驱动学习之7中断相关(一)中断处理函数

嵌入式LINUX驱动学习之7中断相关(一)中断处理函数

一、函数、头文件及说明

//头文件位置:include/linux/interrupt.h
extern int __must_check
request_threaded_irq(unsigned int irq, irq_handler_t handler,\
                     irq_handler_t thread_fn,\
                     unsigned long flags, const char *name, void *dev);

static inline int __must_check \
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
            const char *name, void *dev)
{
        return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}
/*
参数:
irq : 中断号,获取外部中断号使用的函数 :
     static inline int gpio_to_irq(unsigned gpio);//头文件位置:include/linux/gpio.h
irq_handler_t : 中断处理函数 :
                typedef irqreturn_t (*irq_handler_t)(int, void *);
                使用方法:
                         static irqretrun_t irq_func(int args,void * argv);//args:全局的整数,argv:全局指针
flags:
      #define IRQF_TRIGGER_NONE       0x00000000             //没有中断
      #define IRQF_TRIGGER_RISING     0x00000001             //上升沿触发
      #define IRQF_TRIGGER_FALLING    0x00000002             //下降沿触发
      #define IRQF_TRIGGER_HIGH       0x00000004             //高电平触发
      #define IRQF_TRIGGER_LOW        0x00000008             //低电平触发
      #define IRQF_TRIGGER_MASK       (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \
                                      IRQF_TRIGGER_RISING |RQF_TRIGGER_FALLING)
      #define IRQF_TRIGGER_PROBE      0x00000010
 dev :向中断处理函数传递的参数     
*/

二、编译举例:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <cfg_type.h>
/*定义按键信息*/
struct btn_srouce{
    char *name;
    int  gpio ;
};
struct btn_srouce btn_info[] = {
    {
        .name = "BTN1",
        .gpio = PAD_GPIO_A +28
    },
    {
        .name = "BTN2",
        .gpio = PAD_GPIO_B +30
    },
    {
        .name = "BTN3",
        .gpio = PAD_GPIO_B +31
    },
    {
        .name = "BTN4",
        .gpio = PAD_GPIO_B +9
    }
};
/*定义LED灯信息*/
struct led_source {
    char *name;
    int  gpio ;
};
struct led_source led_info[] = {
    {
        .name = "LED1",
        .gpio = PAD_GPIO_B +26
    },
    {
        .name = "LED2",
        .gpio = PAD_GPIO_C +12
    },
    {
        .name = "LED3",
        .gpio = PAD_GPIO_C +11
    },
    {
        .name = "LED4",
        .gpio = PAD_GPIO_C +7
    }
};
static int irq;//定义中断号变更 
/*定义中断处理函数*/
static irqreturn_t irq_func(int args,void * argv){
    struct led_source *led_num = (struct led_source *) argv;//保存传递来的的形参地址
    gpio_set_value(led_num->gpio,(1 - gpio_get_value(led_num->gpio)));//获取当前灯的状态信息,当为0时,设置为1,当为1时设置为0;即开/关状态切换
    printk("%s ,当前%s状态为%s\n",__func__,led_num->name,\
          gpio_get_value(led_num->gpio) ? "关" :"开");
    return IRQ_HANDLED; //返回值说明,见附A.1
}

static int btn_led_init(void){
    int i = 0;
    for(; i<ARRAY_SIZE(btn_info);i++){
        /*LED灯初始化*/
        gpio_request(led_info[i].gpio,led_info[i].name);
        gpio_direction_output(led_info[i].gpio,1);
        /*按键初始化*/
        gpio_request(btn_info[i].gpio,btn_info[i].name);
        irq = gpio_to_irq(btn_info[i].gpio);
        request_irq(irq,irq_func,IRQF_TRIGGER_LOW,\
                    btn_info[i].name,&led_info[i]);
    }
    return 0;
}
static void btn_led_exit(void){
    int i = 0;
    for(; i <ARRAY_SIZE(btn_info);i++){
        /*释放LED灯占用的GPIO资源*/
        gpio_set_value(led_info[i].gpio,1);
        gpio_free(led_info[i].gpio);
        /*释放按键占用的GPIO资源*/
        irq = gpio_to_irq(btn_info[i].gpio);
        free_irq(irq,&led_info[i]);
        gpio_set_value(btn_info[i].gpio,1);
        gpio_free(btn_info[i].gpio);
    }
}
module_init(btn_led_init);
module_exit(btn_led_exit);
MODULE_LICENSE("GPL");

附 A.1

//源码位置:include/linux/irqreturn.h
/**
 * enum irqreturn
 * @IRQ_NONE            interrupt was not from this device
 * @IRQ_HANDLED         interrupt was handled by this device
 * @IRQ_WAKE_THREAD     handler requests to wake the handler thread
 */
enum irqreturn {
        IRQ_NONE                = (0 << 0),
        IRQ_HANDLED             = (1 << 0),
        IRQ_WAKE_THREAD         = (1 << 1),
};
typedef enum irqreturn irqreturn_t;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值