根据上一个帖子的分析,想要实现按键中断,首先得知道引脚对应的中断号,LRADC0对应的中断编号#define SUNXI_IRQ_LRADC (SUNXI_GIC_START + 30) /* 62*/
通过static inline int gpio_to_irq(SUNXI_IRQ_LRADC)这个函数确定这个IO上的外部中断编号
程序流程,当引脚电平发生变化触发中断,进入中断函数把按键状态更新,此时在应用程序读相应设备,则可以知道引脚状态
驱动程序框架
#define BTN_MAJOR 255
static struct miscdevice misc = {
.minor = BTN_MAJOR, //次设备号
.name = DEVICE_BUTTON,//设备名
.fops = &dev_fops, //文件操作方法
};
//按键标志,'0'表示没有按键,'1'表示按下了
static char keybuf[1] = {‘0’};
//中断处理函数声明
irqreturn_t key_isr(int irq, void* dev);
//读函数,读取引脚状态
static ssize_t btn_read (struct file *flp, char __user *buff, size_t count, loff_t * off);
//file_operations结构体
static const struct file_operations dev_fops = {
.read = btn_read ,
.owner = THIS_MODULE,
};
//初始化函数
static int __init btn_init(void);
//注销函数
static void __exit btn_exit(void);
首先先看初始化函数static int __init btn_init(void);
static int __init btn_init(void)
{
int ret;
int irq;//中断号
int flags; //触发标志
flags = IRQ_TYPE_EDGE_BOTH; //设置为双边触发
//得到中断号
irq = gpio_to_irq(SUNXI_IRQ_LRADC);
//注册中断
ret = request_irq(irq,key_isr, flags, “key”, NULL);
if(ret < 0)
break;
//如果不是成功,注销已经注册的中断
if(ret < 0) {
irq = gpio_to_irq(SUNXI_IRQ_LRADC);
disable_irq(irq);
free_irq(irq, NULL);
return ret;
}
//注册杂项设备
ret = misc_register(&misc);
printk(KERN_EMERG " Device registered \n ");
return ret;
}
注销函数 static void __exit btn_exit(void);
static void __exit btn_exit(void)
{
int irq;
//注销中断
irq = gpio_to_irq(SUNXI_IRQ_LRADC);
disable_irq(irq);
free_irq(irq, NULL);
//注销杂项设备
misc_deregister(&misc);
printk(KERN_EMERG " Equipment logged out \n");
}
读函数,读取引脚状态 static ssize_t btn_read (struct file *flp, char __user *buff, size_t count, loff_t * off);
static ssize_t tiny4412_read (struct file *flp, char __user *buff, size_t count, loff_t * off)
{
int ret ;
//count为0,直接返回
if(!count) {
return 0;
}
//复制数据到用户空间
ret = copy_to_user(buff, keybuf, count);
if(ret) {
printk("error:copy_to_user\r\n");
return -EFAULT;
}
return count;
}
中断服务函数irqreturn_t key_isr1(int irq, void* dev)
irqreturn_t key_isr1(int irq, void* dev)
{
//存放按键状态
int btn = 0;
btn= !gpio_get_value(SUNXI_IRQ_LRADC );
//把按键状态更新到对应的按缓冲中
keybuf[0] = dn + '0';
//输出按键提示
printk("key %s\r\n", dn ? "down" : "up");
return IRQ_HANDLED;//目前只是实现一个按键的,这个是共享中断的情况才用到, 在中断到来时,会遍历共享此中断的所有中断处理程序, 直到某一个中断服务函数时返回 IRQ_HANDLED。
}
未完待续... ....
共2条
1/1 1 跳转至页
芯灵思Sinlinx A33开发板 Linux中断编程 2--- 程序框架
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |