注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

zhouhaigang.love的博客

喜欢冬日黄昏那冻住的山

 
 
 

日志

 
 

2011年08月04日  

2011-08-04 10:36:59|  分类: linux开发 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

-- include/linux/interrupt.h --

 29 #define IRQF_TRIGGER_NONE         0x00000000
 30 #define IRQF_TRIGGER_RISING       0x00000001
 31 #define IRQF_TRIGGER_FALLING    0x00000002
 32 #define IRQF_TRIGGER_HIGH          0x00000004
 33 #define IRQF_TRIGGER_LOW          0x00000008
 34 #define IRQF_TRIGGER_MASK   (IRQF_TRIGGER_HIGH   | IRQF_TRIGGER_LOW   | \
 35                              IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING )
 36 #define IRQF_TRIGGER_PROBE      0x00000010
 37
 38 /*
 39  * These flags used only by the kernel as part of the
 40  * irq handling routines.
 41  *
 42  * IRQF_DISABLED      - keep irqs disabled when calling the action handler
 43  * IRQF_SAMPLE_RANDOM - irq is used to feed the random generator
 44  * IRQF_SHARED        - allow sharing the irq among several devices
 45  * IRQF_PROBE_SHARED  - set by callers when they expect sharing mismatches to occur
 46  * IRQF_TIMER         - Flag to mark this interrupt as timer interrupt
 47  * IRQF_PERCPU        - Interrupt is per cpu
 48  * IRQF_NOBALANCING   - Flag to exclude this interrupt from irq balancing
 49  * IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is
 50  *                registered first in an shared interrupt is considered for
 51  *                performance reasons)
 52  * IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished.
 53  *                Used by threaded interrupts which need to keep the
 54  *                irq line disabled until the threaded handler has been run.
 55  * IRQF_NO_SUSPEND    - Do not disable this IRQ during suspend
 56  *
 57  */
 58 #define IRQF_DISABLED                0x00000020
 59 #define IRQF_SAMPLE_RANDOM  0x00000040
 60 #define IRQF_SHARED                   0x00000080
 61 #define IRQF_PROBE_SHARED     0x00000100
 62 #define __IRQF_TIMER                  0x00000200
 63 #define IRQF_PERCPU                   0x00000400
 64 #define IRQF_NOBALANCING         0x00000800
 65 #define IRQF_IRQPOLL                  0x00001000
 66 #define IRQF_ONESHOT                0x00002000
 67 #define IRQF_NO_SUSPEND          0x00004000
 68
 69 #define IRQF_TIMER      (__IRQF_TIMER | IRQF_NO_SUSPEND)

-------------------------------------------------------------------------------


#include <linux/interrupt.h>

 

-- request_irq --

static irqreturn_t irq_handler(int data,void *dev_id)
{
    printk("<0>the data is :%d\n",data);     //data对应的是相应的中断号
    printk("<0>in the interrupt handler function\n");
    return IRQ_NONE; // 函数返回,返回值类型为irqreturn_t类型,可取值为IRQ_NONE、IRQ_HANDLED,此处两者皆可
}

static int irq=10;      //定义中断号,并初始化为10
static int __init enable_disable_irq_init(void)
{
    int result=0;
    printk("<0>into enable_disable_irq_init\n");

    result=request_irq(irq, irq_handler, IRQF_DISABLED, "A_New_Device", NULL);
    disable_irq(irq);     //调用disable_irq()函数,使中断的深度增加1
    enable_irq (irq);     //调用enable_irq()函数,使中断的深度减少1,同时触发中断处理函数执行

    printk("<0>the result of the request_irq is: %d\n",result);
    printk("<0>out enable_disable_irq_init\n");
    return 0;
}

static void __exit enable_disable_irq_exit(void)
{
    free_irq(irq,NULL);  //释放中断
    printk("<0>Goodbye enable_disable_irq\n");
    return;
}

 

[239118.042834] into enable_disable_irq_init
[239118.042858] the data is :10
[239118.042860] in the interrupt handler function
[239118.042863] the result of the request_irq is: 0
[239118.042865] out enable_disable_irq_init


-------------------------------------------------------------------------------

-- request_threaded_irq --


//自定义中断处理函数
static irqreturn_t irq_handler(int data,void *dev_id)
{
    printk("<0>the data is :%d\n",data);
    printk("<0>in the interrupt handler function\n");
    return IRQ_WAKE_THREAD;     //触发中断线程函数执行
}

//自定义中断线程处理函数
static irqreturn_t irq_thread_fn(int data,void *dev_id)
{
    printk("<0>the data is :%d\n",data);
    printk("<0>in the interrupt thread function\n");
    return IRQ_HANDLED;
}


static int irq=10;

static int __init request_threaded_irq_init(void)
{
    int result=0;
    printk("<0>into request_threaded_irq_init\n");

    result =request_threaded_irq ( irqirq_handlerirq_thread_fn,  IRQF_DISABLED,  "A_New_Device",  NULL );

    printk("<0>the result of the request_threaded_irq is: %d\n",result);
    disable_irq(irq);
    enable_irq(irq);
    printk("<0>out request_threaded_irq_init\n");
    return 0; 
}

 

[  452.170490] into request_threaded_irq_init
[  452.170540] the result of the request_threaded_irq is: 0
[  452.170546] out request_threaded_irq_init
[  452.170549] the data is :10
[  452.170552] in the interrupt handler function
[  452.171156] the data is :10
[  452.171159] in the interrupt thread function


-------------------------------------------------------------------------------

-- setup_irq --


#include <linux/interrupt.h>
#include<linux/irq.h>


static irqreturn_t irq_handler(int data,void *dev_id)
{
    printk("<0>the data is :%d\n",data);
    printk("<0>in the interrupt handler function\n");
    return IRQ_NONE;
}

static int irq=10;

static struct irqaction  act =
{
    .irq=10,
    .handler=irq_handler,
    .flags=IRQF_DISABLED,
    .name="A_New_Device",
    .dev_id=NULL
};

static int __init setup_irq_init(void)
{
    int result=0;
    printk("<0>into setup_irq_init\n");
    result=setup_irq(irq,&act);  //调用函数setup_irq()完成申请中断
    printk("the result of the setup_irq is: %d\n",result);
    printk("<0>out setup_irq_init\n");
    return 0;
}

 

[  148.822895] into setup_irq_init
[  148.822914] the result of the setup_irq is: 0
[  148.822916] out setup_irq_init


-------------------------------------------------------------------------------

 

tasklet:

#include <linux/interrupt.h>

 

static unsigned long data=10;
static struct tasklet_struct   tasklet;


/* struct tasklet_struct
 * {
 *    struct tasklet_struct *next;
 *    unsigned long   state;
 *    atomic_t        count;
 *    void (*func)(unsigned long);
 *    unsigned long   data;
 * }
 *
 */


static void irq_tasklet_action(unsigned long data)
{
    printk("<0>The state of the tasklet is :%ld\n",(&tasklet)->state);
    printk("<0>tasklet running. by author\n");
    return;
}

static int  __init tasklet_init_init(void)
{
    printk("<0>into tasklet_init_init\n");
    printk("<0>the data value of the tasklet is :%ld\n",tasklet.data);
    if(tasklet.func==NULL)
    {  
        printk("<0>the tasklet has not been initialized\n");
    }

    //初始化一个struct tasklet_struct 变量,即申请一个 "软中断变量"
    tasklet_init(&tasklet,  irq_tasklet_action,  data);

    printk("<0>the data value of the tasklet is :%ld\n",tasklet.data);
    if(tasklet.func==NULL)
    {  
        printk("<0>the tasklet has not been initialized\n");
    }  
    else
    {  
        printk("<0>the tasklet has been initialized\n");
    }  
    printk("<0>out tasklet_init_init\n");
    return 0; 
}

 

[323876.838974] into tasklet_init_init
[323876.838978] the data value of the tasklet is :0
[323876.838980] the tasklet has not been initialized
[323876.838983] the data value of the tasklet is :10
[323876.838985] the tasklet has been initialized
[323876.838987] out tasklet_init_init


-------------------------------------------------------------------------------


-- tasklet_disable --

 

static unsigned long data=0;
static struct tasklet_struct  tasklet;

                                
static void irq_tasklet_action(unsigned long data)
{  
    printk("<0>tasklet running.\n");
    return;
}  
 
 
static int __init tasklet_enable_disable_init(void)
{
    printk("<0>into tasklet_enable_disable_init\n");

    tasklet_init(&tasklet,  irq_tasklet_action,data);     //初始化一个struct tasklet_struct 变量    
    tasklet_schedule(&tasklet);                   //把软件中断放入后台线程

#if 0
 udelay(85); /*80 ~ 85*/    //一个有意思的傻瓜试验, udelay参数为 85~80之间,出现执行tasklet_disable是否来的急的问题。
#endif


    printk("<0>the count value of the tasklet before tasklet_disable is:%d\n",tasklet.count);
    tasklet_disable(&tasklet);                   //调用tasklet_disable()使tasklet对应的处理函数不能执行
    if(atomic_read(&(tasklet.count)) != 0)       //测试当前的count的值
        printk("<0>tasklet is disabled.\n");    

    printk("<0>the count value of the tasklet after tasklet_disable is:%d\n",tasklet.count);
    tasklet_enable(&tasklet);                    //调用函数tasklet_enable()使能tasklet
    if(atomic_read(&(tasklet.count))==0)
        printk("<0>tasklet is enabled\n");    
 
    printk("<0>the count value of the tasklet after tasklet_enable is:%d\n",tasklet.count);
    tasklet_kill(&tasklet);                      //等待tasklet被调度,之后再continue...
    printk("<0>out tasklet_enable_disable_init\n");
    return 0;
}

 

 

[324257.627847] into tasklet_enable_disable_init
[324257.627855] the count value of the tasklet before tasklet_disable is:0
[324257.627857] tasklet is disabled.
[324257.627860] the count value of the tasklet after tasklet_disable is:1
[324257.627862] tasklet is enabled
[324257.627864] the count value of the tasklet after tasklet_enable is:0
[324257.627870] tasklet running. by author
[324257.627874] out tasklet_enable_disable_init


-------------------------------------------------------------------------------


static unsigned long data=0;
static struct tasklet_struct tasklet;


static void irq_tasklet_action(unsigned long data)
{
    printk("<0>in the irq_tasklet_action the state of the tasklet is :%ld\n",(&tasklet)->state);
    printk("<0>tasklet running.\n");
    return;
}

static int  __init tasklet_kill_init(void)
{
    printk("<0>into tasklet_kill_init\n");
    tasklet_init(&tasklet,irq_tasklet_action,data); //初始化一个struct tasklet_struct 变量,即申请一个软中断变量
    printk("<0>the state of the tasklet after tasklet_init is :%ld\n",(&tasklet)->state); //显示软中断状态
   tasklet_schedule(&tasklet);    //将中断变量放入软中断执行队列
    printk("<0>the state of the tasklet after tasklet_schedule is :%ld\n",(&tasklet)->state);  //显示中断当前状态

   tasklet_kill(&tasklet);        //杀死中断,恢复先前的状态; 等待tasklet函数处理完成。
    printk("<0>the state of the tasklet after tasklet_kill is :%ld\n",(&tasklet)->state);   //显示杀死之后的中断状态    
    printk("<0>out tasklet_kill_init\n");
    return 0; 
}

 

[326135.035535] into tasklet_kill_init
[326135.035540] the state of the tasklet after tasklet_init is :0
[326135.035545] the state of the tasklet after tasklet_schedule is :1
[326135.035550] in the irq_tasklet_action the state of the tasklet is :2
[326135.035553] tasklet running.
[326135.035557] the state of the tasklet after tasklet_kill is :0
[326135.035559] out tasklet_kill_init


-------------------------------------------------------------------------------


-- tasklet_trylock --


static struct tasklet_struct tasklet;


static void irq_tasklet_action(unsigned long data)
{
    int result=-1;
    printk("<0>tasklet running.\n");
    printk("<0>in irq_tasklet_action the state of the tasklet is :%ld\n",(&tasklet)->state);  //显示当前中断的状态
    result=tasklet_trylock(&tasklet);                           //给中断加锁
    if(result==0)                                                          //显示加锁结果
        printk("<0>tasklet_trylock failed\n");
    else
        printk("<0>tasklet_trylock success\n");
    printk("<0>out irq_tasklet_action\n");
    return;
}

static int  __init tasklet_trylock_unlock_init(void)
{
    int result=-1;
    printk("<0>into tasklet_trylock_unlock_init\n");
    tasklet_init(&tasklet,irq_tasklet_action,data);   //初始化软中断变量
    tasklet_schedule(&tasklet);                              //将软中断变量加入中断队列
    printk("<0>the state of the tasklet before tasklet_trylock is :%ld\n",tasklet.state);  //显示中断状态

    result=tasklet_trylock(&tasklet);            //对中断加锁

    if(result==0)                                           //显示加锁结果
        printk("<0>tasklet_trylock failed\n");
    else
        printk("<0>tasklet_trylock success\n");
    printk("<0>the state of the tasklet after tasklet_trylock is :%ld\n",tasklet.state);

    tasklet_unlock(&tasklet);                         //对中断解锁
    printk("<0>the state of the tasklet after tasklet_unlock is :%ld\n",tasklet.state);

    tasklet_kill(&tasklet);                           //杀死中断,恢复未调度之前的状态
    printk("<0>out tasklet_trylock_unlock_init\n");
    return 0;
}

 


[327351.547559] into tasklet_trylock_unlock_init
[327351.547566] the state of the tasklet before tasklet_trylock is :1
[327351.547568] tasklet_trylock success
[327351.547571] the state of the tasklet after tasklet_trylock is :3
[327351.547573] the state of the tasklet after tasklet_unlock is :1
[327351.547578] tasklet running.
[327351.547581] in irq_tasklet_action the state of the tasklet is :2
[327351.547583] tasklet_trylock failed
[327351.547585] out irq_tasklet_action
[327351.547589] out tasklet_trylock_unlock_init

  评论这张
 
阅读(334)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017