论坛» DIY与开源设计» 开源硬件

芯灵思Sinlinx A33开发板 Linux中断编程 2--- 程序框架

助工
2019-02-01 16:28 1楼

根据上一个帖子的分析,想要实现按键中断,首先得知道引脚对应的中断号,LRADC0对应的中断编号#define SUNXI_IRQ_LRADC (SUNXI_GIC_START + 30) /* 62*/
通过static inline intgpio_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。
}




未完待续... ....

院士
2019-02-03 16:32 2楼
持续关注中。。。
共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]