嵌入式LINUX驱动开发(中断处理函数)
程序员文章站
2023-12-30 10:34:28
嵌入式LINUX驱动学习之7中断相关(一)中断处理函数一、函数、头文件及说明二、编译举例:一、函数、头文件及说明//头文件位置:include/linux/interrupt.hextern int __must_checkrequest_threaded_irq(unsigned int irq, irq_handler_t handler,\ irq_handler_t thread_fn,\ unsigned...
嵌入式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;
本文地址:https://blog.csdn.net/weixin_47273317/article/details/107908456
推荐阅读
-
嵌入式Linux开发: 编写EEPROM驱动_采用杂项字符设备框架
-
字符设备驱动开发 Linux 设备号 字符设备驱动开发步骤 open 函数调用流程 设备号的组成 设备号的分配 Linux 应用程序对驱动程序的调用 字符设备注册与注销 实现设备的具体操作函数
-
linux驱动开发之输入子系统编程(一)使用工作队列实现中断下半部
-
linux 驱动开发之平台设备驱动设备树 input子系统的使用:按键中断驱动
-
linux驱动开发中常用函数copy_from_user open read write详解
-
嵌入式Linux驱动(LED驱动开发测试)
-
嵌入式linux-ARM体系结构及接口技术,ARM中断机制,外部中断的配置,协处理器指令修改异常向量表起始地址,清中断标志
-
【Linux 驱动】第十章 中断处理
-
嵌入式软件开发之------浅析linux驱动模型(五)I2C驱动
-
嵌入式Linux驱动开发(一)——字符设备驱动框架入门