linux 的中断使用总结


分为两部分:顶半部底半部


顶半部用于执行时间短和需要立刻响应的必要中断,而底半部则执行时间上相对长和响应上可以延缓的程序,以便提高并发性。


PIC( Programmable Interrupt Controller
 高级可编程中断控制器(APIC)


中断查看:
jaho@ARX-II:~$ cat /proc/interrupts 

中断序号   中断次数  可编程中断控制器  设备名称(request_irq的dev_name字段)
           CPU0       CPU1       
  0:    9089869   11999244   IO-APIC-edge      timer
  1:        899         45             IO-APIC-edge      i8042
  8:          0          1                IO-APIC-edge      rtc0
  9:       2963        525           IO-APIC-fasteoi   acpi
 12:       5875      11372        IO-APIC-edge      i8042
 16:      12970      25385       IO-APIC-fasteoi   uhci_hcd:usb6
 17:         10         12             IO-APIC-fasteoi   uhci_hcd:usb7
 18:          0          0               IO-APIC-fasteoi   uhci_hcd:usb8
 19:     217422     193605     IO-APIC-fasteoi   ehci_hcd:usb2
 20:          0          0               IO-APIC-fasteoi   uhci_hcd:usb3
 21:          0          0               IO-APIC-fasteoi   uhci_hcd:usb4
 22:          0          0               IO-APIC-fasteoi   uhci_hcd:usb5
 23:         95         25             IO-APIC-fasteoi   ehci_hcd:usb1
 40:          0          0               PCI-MSI-edge      PCIe PME, pciehp
 41:          0          0               PCI-MSI-edge      PCIe PME, pciehp
 42:          0          0               PCI-MSI-edge      PCIe PME, pciehp
 43:          8          9               PCI-MSI-edge      mei
 44:    1422333       5821      PCI-MSI-edge      ahci
 45:        683        126           PCI-MSI-edge      eth0

。。。。。。




硬中断

request_irq();

note:
中断号可以在应的Irqs.h中获得, platform设备的中断号可以从platform_ resource 中获得

禁止和使能:



软中断(低半部,顶半部(硬中断)执行完时)


1.
tasklet (用软中断实现的)(参考:drivers\mxc\security\sahara2\Sah_interrupt_handler.c)
note执行于软中断上下文,属于原子上下文,不允许休眠

禁止和使能: loal_bh_disable()        local_bh_enable()

                                         tasklet 名称          软中断回调
DECLARE_TASKLET( BH_tasksah_Intr_Bottom_Half, (unsigned long)&reset_flag);

static void  sah_Intr_Bottom_Half(unsigned long reset_flag)  

int sah_Intr_Init(wait_queue_head_t * wait_queue)    //硬中断申请  
{
...........
                                                                   中断回调
result =  request_irq(SAHARA_IRQ,  sah_Intr_Top_Half, 0, SAHARA_NAME, NULL);
...........
}

// 硬中断函数
static irqreturn_t  sah_Intr_Top_Half(int irq, void *dev_id)
{
#if defined(DIAG_DRV_INTERRUPT) && defined(DIAG_DURING_INTERRUPT)
LOG_KDIAG("Top half of Sahara's interrupt handler called.");
#endif

interrupt_count++;
reset_flag = sah_Handle_Interrupt(sah_HW_Read_Status());

/* Schedule the Bottom Half of the Interrupt. */
tasklet_schedule(&BH_task);// 对应的中断函数在适当时候将被执行

/* To get rid of the unused parameter warnings. */
irq = 0;
dev_id = NULL;
return IRQ_RETVAL(1);
}



2.
工作队列(参考:drivers\usb\musb\Musb_core.c)
note执行于内核线程上下文
在linux2.6.36后出现cmwq自动维护工作队列的线程池
以提高并发性。之前是在work内核线程中执行。


//定义工作队列和关联函数

struct work_struct xxx_wq

void  xxx_do_work(struct work_struct *work);

//中断处理底半部
void  xxx_do_work (struct work_struct *work)
{
............
}

// 中断处理顶半部
irqreturn_t   xxx_interrupt(int irq, void *dev_id)
{
    .....
    schedule_work(&xxx_wq);
    .....
    return IRQ_HANDLED;
}

// 设备驱动模块加载

int xxx_int(void)
{
     // 申请中断
    reuqest_irq(xxx_irq, xxx_interrupt, 0, "xxx", NULL);
    // 初始化队列
    INIT_WORK(&xxx_wqxxx_do_work);
    .................
}

 // 设备模块卸载


void xxx_exit(void)
{
    ........
    //释放中断
    free_irq(xxx_irq, xxx_interrupt);
    .........
}




3.
软中断(softirq)(一般不用。。。。)
note:执行与原子上下文,不能休眠
禁止和使能: loal_bh_disable()        local_bh_enable()


注册:open_softirq()
触发:raise_softirq()


4.

threaded_irq(参考:driver\rtc\Rtc-ab8500.c  & driver\hwmon\Lis3lv02d.c


request_threaded_irq(unsigned int irq, irq_handler_t handler,

              irq_handler_t thread_fn, unsigned long irqflags,

              const char *devname, void *dev_id)

devm_request_threaded_irq()


handler 对应的中断函数执行完后,如果返回值是IRQ_WAKE_THREAD内核会分配新的线程处理这个 thread_fn函数



中断共享


申请中断时添加标志:IRQF_SHARED

类似于共用一条中断线,当中断到来时需要在中断处理函数中做判断处理


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






参考:linux设备驱动详解 &互联网

































































你可能感兴趣的:(linux设备驱动)