基于ARM A53开发板,使用按键中断及中断底半部实现《led灯状态取反》的驱动


#include <linux/init.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/gpio.h>
#include<linux/interrupt.h>

 //GIPO口的初始化

#define GPIO(m,n) m*32+n
#define GPIOA28 GPIO(0,28)
#define GPIOB12 GPIO(1,12)
#define GPIOE13 GPIO(4,13)

#define GPIOB8 GPIO(1,8)
#define GPIOB16 GPIO(1,16)

int irqno[2] = {GPIOB8,GPIOB16};


int gpiono[] = {GPIOA28,GPIOB12,GPIOE13};

 //延时工作队列定义结构体

struct delayed_work dwork;

//中断底板部处理函数 延时

void myfunc(struct work_struct *work){

printk("%s : %s : %d\n",__FILE__,__func__,__LINE__);
schedule_delayed_work(&dwork,msecs_to_jiffies(1000));
}

//中断处理函数
irqreturn_t my_irq_handler(int irq, void *dev){

//红灯GPIO口状态获取、取反、及设置回填

int red_statu = gpio_get_value(GPIOA28);
red_statu = red_statu ? 0:1;
gpio_set_value(GPIOA28,red_statu);

//调用执行中断底板部处理函数

schedule_delayed_work(&dwork,0);
return IRQ_HANDLED;

}

 

//入口初始化函数

static int __init work_timer_init(void){

int i,ret;

//释放系统占用的gpio口

for(i=0; i<ARRAY_SIZE(gpiono); i++){
gpio_free(gpiono[i]);
}
//申请GPIO口(本实验只用红灯)
for(i = 0;i<ARRAY_SIZE(gpiono);i++){

ret = gpio_request(gpiono[i],NULL);
if(ret){
printk("gpio_request %d error",gpiono[i]);
return ret;
}

//输出方向
gpio_direction_output(gpiono[i],0);
}

//中断申请  两个按键
for(i=0;i<ARRAY_SIZE(irqno);i++){
ret = request_irq(gpio_to_irq(irqno[i]),my_irq_handler, IRQF_TRIGGER_FALLING,NULL, NULL);
if(ret){
printk("request_irq error");
return ret;
}
}
//延时工作队列初始化对象
INIT_DELAYED_WORK(&dwork,myfunc);

return 0;

}

//出口注销申请资源
static void __exit work_timer_exit(void){

int i;
for(i=0; i<ARRAY_SIZE(gpiono); i++){
gpio_free(gpiono[i]);
}
for(i=0;i<ARRAY_SIZE(irqno);i++)
{
free_irq(gpio_to_irq(irqno[i]), NULL);
}
cancel_delayed_work_sync(&dwork);

}

module_init(work_timer_init);
module_exit(work_timer_exit);
MODULE_LICENSE("GPL");

 

posted @ 2019-09-09 20:16  灰机12321  阅读(410)  评论(0编辑  收藏  举报