查看: 3789|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2016-4-14 10:16
  • 签到天数: 9 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2019-2-1 16:30:34 | 显示全部楼层 |阅读模式
    分享到:
    根据上一个帖子的分析,想要实现按键中断,首先得知道引脚对应的中断号,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。
    }




    未完待续... ....


    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-19 20:27 , Processed in 0.105189 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.