zoukankan      html  css  js  c++  java
  • 中断处理中tasklet与工作队列的使用

          在编写含有中断的程序中,少不了中断的申请(request_irq)及中断释放(free_irq),当然少不了对中断的处理,常用的中断处理方法有tasklet,工作队列以及软中断,其中tasklet和工作队列的使用法方类似,定义一个结构和一个处理函数,然后将结构与处理函数联系起来就可以了,下面通过2个例子说明:

    tasklet的使用:

    #include<linux/kernel.h>
    #include<linux/module.h>
    #include<linux/init.h>
    #include<linux/interrupt.h>

    static int irq;          //中断号
    static char *devname;    //设备名
    static struct tasklet_struct mytasklet;   //tasklet结构体
    module_param(irq,int,0644);            
    module_param(devname,charp,0644);

    struct myirq
    {
            int devid;
    };

    struct myirq mydev={1119};

    static void mytasklet_handler(unsigned long data)   //tasklet处理函数
    {
            printk("tasklet is working\n");
    }

    static irqreturn_t myirq_handler(int irq,void *dev)  //中断处理函数
    {
        struct myirq mydev;
        static int count =0 ;
        mydev=*(struct myirq*)dev;
        printk("key:%d\n",count+1);
        printk("devid %d isr is working\n",mydev.devid);
        printk("botoom half will be working\n");
        tasklet_init(&mytasklet,mytasklet_handler,0);  //初始化tasklet将tasklet结构与tasklet处理函数建立联系
        tasklet_schedule(&mytasklet);                   //调用tasklet
        printk("isr is leaving\n");
        count++;
        return IRQ_HANDLED;
    }

    static int __init myirq_init()       
    {
           printk(KERN_NOTICE "MODULE is working...\n");
           if(request_irq(irq,myirq_handler,IRQF_SHARED,devname,&mydev)!=0)   //申请中断
            {
                printk("%s request irq %d faild\n",devname,irq);
                return -1;
            }
            printk("%s request irq %d success \n",devname,irq);
            return 0;
    }

    static int __exit myirq_exit()
    {
            printk("module is leaving\n");
            free_irq(irq,&mydev);       //释放中断
            return 0;
    }

    module_init(myirq_init);
    module_exit(myirq_exit);
    MODULE_LICENSE("GPL");

    工作队列使用:

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

    static int irq;
    static char *devname;
    static struct work_struct mywork;
    module_param(irq,int,0644);
    module_param(devname,charp,0644);

    struct myirq
    {
        int devid;
    };

    struct myirq mydev={1119};

    static void mywork_handler(void *data)
    {
        printk("work is working\n");
    }

    static irqreturn_t myirq_handler(int irq,void *dev)
    {
        struct myirq mydev;
        static int count =0 ;
        mydev=*(struct myirq*)dev;
        printk("key:%d\n",count+1);
        printk("devid %d isr is working\n",mydev.devid);
        printk("botoom half will be working\n");
        INIT_WORK(&mywork,mywork_handler);
        schedule_work(&mywork);
        printk("isr is leaving\n");
        count++;
        return IRQ_HANDLED;
    }

    static int __init myirq_init()
    {
       printk(KERN_NOTICE "MODULE is working...\n");
       if(request_irq(irq,myirq_handler,IRQF_SHARED,devname,&mydev)!=0)
       {
           printk("%s request irq %d faild\n",devname,irq);
           return -1;
       }
       printk("%s request irq %d success \n",devname,irq);
       return 0;
    }

    static int __exit myirq_exit()
    {
        printk("module is leaving\n");
        free_irq(irq,&mydev);
        return 0;
    }

    module_init(myirq_init);
    module_exit(myirq_exit);
    MODULE_LICENSE("GPL");

    只是简单的例子,说明使用方法而已,没有什么意义。

  • 相关阅读:
    最佳实践丨三种典型场景下的云上虚拟IDC(私有池)选购指南
    总渲染时长超3亿核小时,阿里云助力《白蛇2:青蛇劫起》提升视效
    阿里云成为首个通过“虚拟化云平台性能测试(大规模)”的云厂商
    AI性能提升2-3倍!搭载 NVIDIA A10 GPU的阿里云gn7i服务器开启邀测
    最佳实践丨阿里云ECI如何助力西软构建酒店行业多租户高弹性PaaS平台?
    暑期大放“价”,轻量应用服务器9元包月!
    报名通道开启!原生安全二倍速:探秘基础设施的内生“免疫系统"
    40万奖金等你来挑战!阿里云ECS Cloudbuild开发者大赛重磅开启
    Ubuntu安装桌面环境
    tinkphp3.0 execl导出问题
  • 原文地址:https://www.cnblogs.com/276815076/p/1847778.html
Copyright © 2011-2022 走看看