这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 开源硬件 » 芯灵思Sinlinx A33开发板 Linux中断编程 2--- 程序框架

共2条 1/1 1 跳转至

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

助工
2019-02-01 16:28:44     打赏

根据上一个帖子的分析,想要实现按键中断,首先得知道引脚对应的中断号,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。
}




未完待续... ....



院士
2019-02-03 16:32:43     打赏
2楼
持续关注中。。。

共2条 1/1 1 跳转至

回复

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