前段时间一工程师向我咨询了一个问题,问我为什么他的MCU KEIL工程代码里没有找到__disable_irq() 和 __enable_irq()的具体定义,是不是有问题。 __disable_irq() 和 __enable_irq() 是所谓的intrinsic函数,编译器自动识别并替换为相关的指令,它们其实是编译器的一部分,实际的定义位于arm_compat.h 文件中 这说明__disable_irq()只是禁止CPU去响应中断,没有真正的去屏蔽中断的触发,当中断发生后,相应的寄存器会将中断标志置位,在__enable_irq()开启中断后,由于相应的中断标志没有清空 实际测试如果在调用__disable_irq()后、__enable_irq()之前的这3s时间内按下按键,并不会进入中断翻转LED,虽然这时中断标志位已经产生了。 但是调用__enable_irq()之后就会立刻进入到中断服务函数中。
unsigned *)0x4a000008) //Interrupt mask control #define rPRIORITY (*(volatile unsigned *)0x4a00000c) //IRQ _ISR_STARTADDRESS+0x10)) #define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14)) #define pISR_IRQ
本节学习下什么是irq domain, 以及irq domain的作用。 linux内核为了应对此问题,引入了IRQ-domain的概念 irq-domain的引入相当于一个中断控制器就是一个irq-domain。就是一个中断区域。 利用树状的结构可以充分的利用irq数目,而且每一个irq-domain区域可以自己去管理自己interrupt的特性 IRQ-Domain的作用 咋们通过/proc/interrupt的值来看下irq-domain *irq_to_desc(unsigned int irq) { return radix_tree_lookup(&irq_desc_tree, irq); } struct irq_desc *irq_to_desc(unsigned int irq) { return (irq < NR_IRQS) ?
__disable_irq_nosync(irq)) 416 synchronize_irq(irq); 417 } 372 static int __disable_irq_nosync desc->irq_data.chip->irq_disable(&desc->irq_data); 221 irq_state_set_masked(desc); 222 } –>chip->irq_mask –>chip->irq_ack –> handle_irq_event (就是调用irq_handler的处理) –>chip-> irq_unmask 具体可以参考蜗窝上的文章 ->irq_mask(&desc->irq_data); if (desc->irq_data.chip->irq_ack) desc->irq_data.chip ->irq_ack(&desc->irq_data); } irq_state_set_masked(desc); } 该函数中调用的就是chip中的irq_mask和irq_ack
EXPORT声明一个符号Default_IRQ_ISR可以被其它文件引用 Default_IRQ_ISR ;定义一个Default_IRQ_ISR,并且啥也不干 B . ;B Default_IRQ_ISR代表啥都不干(因为上面对Default_IRQ_ISR中的操作定义就是啥都没干) EINT1_Handle B Default_IRQ_ISR B Default_IRQ_ISR TICK_Handle B Default_IRQ_ISR WDT_AC97_Handle B Default_IRQ_ISR Default_IRQ_ISR ISR_SDI_Handle B Default_IRQ_ISR ISR_SPI0_Handle B Default_IRQ_ISR ISR_UART1 B Default_IRQ_ISR ISR_ADC_Handle B Default_IRQ_ISR IRQ_Handler PROC EXPORT IRQ_Handler
EXPORT声明一个符号Default_IRQ_ISR可以被其它文件引用 Default_IRQ_ISR ;定义一个Default_IRQ_ISR,并且啥也不干 B . ;B Default_IRQ_ISR代表啥都不干(因为上面对Default_IRQ_ISR中的操作定义就是啥都没干) EINT1_Handle B Default_IRQ_ISR _Handle B Default_IRQ_ISR ISR_UART2_Handle B Default_IRQ_ISR ISR_LCD_Handle B Default_IRQ_ISR Default_IRQ_ISR ISR_DMA3_Handle B Default_IRQ_ISR ISR_SDI_Handle B Default_IRQ_ISR ISR_SPI0 B Default_IRQ_ISR ISR_ADC_Handle B Default_IRQ_ISR IRQ_Handler PROC EXPORT IRQ_Handler
Interrupt mode control INTMSK EQU 0x4a000008 ;Interrupt mask control PRIORITY EQU 0x4a00000c ;IRQ SUB_STACK_SIZE EQU 128 ;定义变量子栈大小 STACK_BASE EQU (0x00001000) ;定义栈的基址 IRQStack_BASE EQU STACK_BASE ;定义IRQ
EXPORT声明一个符号Default_IRQ_ISR可以被其它文件引用 Default_IRQ_ISR ;定义一个Default_IRQ_ISR,并且啥也不干 B . ;B Default_IRQ_ISR代表啥都不干(因为上面对Default_IRQ_ISR中的操作定义就是啥都没干) EINT1_Handle B Default_IRQ_ISR B Default_IRQ_ISR TICK_Handle B Default_IRQ_ISR WDT_AC97_Handle B Default_IRQ_ISR Default_IRQ_ISR ISR_TIMER3_Handle B Default_IRQ_ISR ISR_TIMER4_Handle B Default_IRQ_ISR ISR_UART2 Default_IRQ_ISR ISR_SDI_Handle B Default_IRQ_ISR ISR_SPI0_Handle B Default_IRQ_ISR ISR_UART1
SUB_STACK_SIZE EQU 128 ;定义变量子栈大小 STACK_BASE EQU (0x00001000) ;定义栈的基址 IRQStack_BASE EQU STACK_BASE ;定义IRQ unsigned *)0x4a000008) //Interrupt mask control #define rPRIORITY (*(volatile unsigned *)0x4a00000c) //IRQ _ISR_STARTADDRESS+0x10)) #define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14)) #define pISR_IRQ
Interrupt mode control INTMSK EQU 0x4a000008 ;Interrupt mask control PRIORITY EQU 0x4a00000c ;IRQ
EXPORT声明一个符号Default_IRQ_ISR可以被其它文件引用 Default_IRQ_ISR ;定义一个Default_IRQ_ISR,并且啥也不干 B . ;B Default_IRQ_ISR代表啥都不干(因为上面对Default_IRQ_ISR中的操作定义就是啥都没干) EINT1_Handle B Default_IRQ_ISR Default_IRQ_ISR ISR_UART2_Handle B Default_IRQ_ISR ISR_LCD_Handle B Default_IRQ_ISR ISR_DMA0 B Default_IRQ_ISR ISR_USBH_Handle B Default_IRQ_ISR ISR_IIC_Handle B Default_IRQ_ISR Default_IRQ_ISR ISR_ADC_Handle B Default_IRQ_ISR IRQ_Handler PROC EXPORT IRQ_Handler
EXPORT声明一个符号Default_IRQ_ISR可以被其它文件引用 Default_IRQ_ISR ;定义一个Default_IRQ_ISR,并且啥也不干 B . Default_IRQ_ISR TICK_Handle B Default_IRQ_ISR WDT_AC97_Handle B Default_IRQ_ISR ISR_TIMER0 Default_IRQ_ISR ISR_LCD_Handle B Default_IRQ_ISR ISR_DMA0_Handle B Default_IRQ_ISR ISR_DMA1 B Default_IRQ_ISR ISR_IIC_Handle B Default_IRQ_ISR ISR_UART0_Handle B Default_IRQ_ISR B Default_IRQ_ISR ISR_ADC_Handle B Default_IRQ_ISR IRQ_Handler PROC EXPORT IRQ_Handler
Interrupt mode control INTMSK EQU 0x4a000008 ;Interrupt mask control PRIORITY EQU 0x4a00000c ;IRQ
SUB_STACK_SIZE EQU 128 ;定义变量子栈大小 STACK_BASE EQU (0x00001000) ;定义栈的基址 IRQStack_BASE EQU STACK_BASE ;定义IRQ unsigned *)0x4a000008) //Interrupt mask control #define rPRIORITY (*(volatile unsigned *)0x4a00000c) //IRQ _ISR_STARTADDRESS+0x10)) #define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14)) #define pISR_IRQ
Interrupt mode control INTMSK EQU 0x4a000008 ;Interrupt mask control PRIORITY EQU 0x4a00000c ;IRQ SUB_STACK_SIZE EQU 128 ;定义变量子栈大小 STACK_BASE EQU (0x00001000) ;定义栈的基址 IRQStack_BASE EQU STACK_BASE ;定义IRQ
Interrupt mode control INTMSK EQU 0x4a000008 ;Interrupt mask control PRIORITY EQU 0x4a00000c ;IRQ SUB_STACK_SIZE EQU 128 ;定义变量子栈大小 STACK_BASE EQU (0x00001000) ;定义栈的基址 IRQStack_BASE EQU STACK_BASE ;定义IRQ
unsigned *)0x4a000008) //Interrupt mask control #define rPRIORITY (*(volatile unsigned *)0x4a00000c) //IRQ _ISR_STARTADDRESS+0x10)) #define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14)) #define pISR_IRQ
本节目标: 分析request_irq()如何申请注册中断,free_irq()如何注销中断 1.request_irq()位于kernel/irq/ manage .c,函数原型如下: int retval = setup_irq(irq, action); // 进入setup_irq(irq, action),设置irq_ desc[irq]->action if 型action,然后把参数都赋给这个action,最后进入setup_irq(irq, action)设置irq_ desc[irq]->action 1.2我们来看看setup_irq(irq, action irq_desc *desc = irq_desc + irq; //根据中断号找到irq_ desc[irq] ... ... ()是注册中断,同样的卸载中断的函数是free_irq() free_irq()也位于kernel/irq/ manage .c,函数原型如下: free_irq(unsigned int irq, void
Interrupt mode control INTMSK EQU 0x4a000008 ;Interrupt mask control PRIORITY EQU 0x4a00000c ;IRQ SUB_STACK_SIZE EQU 128 ;定义变量子栈大小 STACK_BASE EQU (0x00001000) ;定义栈的基址 IRQStack_BASE EQU STACK_BASE ;定义IRQ unsigned *)0x4a000008) //Interrupt mask control #define rPRIORITY (*(volatile unsigned *)0x4a00000c) //IRQ
unsigned *)0x4a000008) //Interrupt mask control #define rPRIORITY (*(volatile unsigned *)0x4a00000c) //IRQ _ISR_STARTADDRESS+0x10)) #define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14)) #define pISR_IRQ