中断

中断

1 概述:

  Linux 的中断处理分为顶半部和底半部,顶半部完成尽可能少得的比较紧急的功能,往往只是简单的完成“登记中断”的工作,

  就是就是将底半部处理程序挂到该设备的底半部处理队列中去。但是,也不能僵化的认为linux设备驱动中的中断处理一定分

  为两个半部,如果中断要处理的工作本身就很少,则完全可以在顶半部全部完成。查看/proc/interrupts文件可以获得系统

  中断的统计信息。

2 中断编程:

  1 申请和释放中断

    (1) 申请irq

      int request_irq (unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, 

                void *dev_id)

      irq 是要申请的中断号,handler是向系统登记的中断处理函数,irq_flags是中断处理的属性,可以指定中断的触发

      方式机处理方式。dev_id 在中断共享时会用到,一般设置为这个设备的结构体或者NULL.

    (2) 释放irq

      void free_irq (unsigned int irq, void *dev_id); 参数定义与request_irq()相同。

   2 使能和屏蔽中断

     (1) 屏蔽:void disable_irq (int irq);

         void disable_irq_nosync (ing irq);//立即返回

         void enable_irq (int irq);

         #define local_irq_save (flags)//屏蔽本cpu所有

         void local_irq_disable (void) //屏蔽本cpu所有中断

     (2) 恢复中断

      #define local_irq_restore (flags)

      void local_irq_enable (void);

  3 底半部机制--实现机制主要有tasklet, 工作队列 和 软中断。

    (1) tasklet

      void my_tasklet_func (unsigned long);

      DECLARE_TASKLET (my_tasklet, my_tasklet_func, data);

      /*定义一个tasklet结构my_tasklet, 与my_tasklet_func(data)函数相关联*/

      tasklet_schedule (&my_tasklet);

      /*使系统在适当的时候调度tasklet注册的函数*/

    (2)工作队列

      struct work_struct my_wq;

      void my_wq_func (unsigned long);

      INIT_WORK (&my_wq, (void(*)(void *))my_wq_func, NULL);

      /*初始化工作队列并将其与处理函数绑定*/

      schedule_work (&my_wq); /*调度工作队列执行*/

    (3)软中断(与通常说的软中断(软件指令引发的中断),比如arm的swi是完全不同的概念)

      在linux内核中,用softirq_action结构体表征一个软中断,这个结构体包含软中断处理函数指针和传递给该

      函数的参数。使用open_softirq()函数可以注册软中断对应的处理函数,而raise_softirq()函数可以触发一

      个软中断。

      软中断和tasklet 运行与软中断上下文,仍属于原子上下文的一种,而工作队列则运行与进程上下文。因此,

      软中断和tasklet处理函数中不能睡眠,而工作队列处理函数中允许睡眠。

      local_bh_disable() 和 local_bh_enable()是内核中用于禁止和使能软中断和tasklet底半部机制的函数。

3 实例--s3c2410实时钟中断

  参考linux模块,在/drivers/rtc/rtc-s3c.c 和/drivers/rtc/interface.c文件中。

posted @ 2018-09-06 15:51  恩赐解脱ゞ  阅读(122)  评论(0编辑  收藏  举报