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");

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

  • 相关阅读:
    UVa 1451 Average (斜率优化)
    POJ 1160 Post Office (四边形不等式优化DP)
    HDU 3507 Print Article (斜率DP)
    LightOJ 1427 Substring Frequency (II) (AC自动机)
    UVa 10245 The Closest Pair Problem (分治)
    POJ 1741 Tree (树分治)
    HDU 3487 Play with Chain (Splay)
    POJ 2828 Buy Tickets (线段树)
    HDU 3723 Delta Wave (高精度+calelan数)
    UVa 1625 Color Length (DP)
  • 原文地址:https://www.cnblogs.com/276815076/p/1847778.html
Copyright © 2011-2022 走看看