以beagle为例:
在初始化阶段,boot_card函数中,会调用bsp_start():
void boot_card(
const char *cmdline
)
{
rtems_interrupt_level bsp_isr_level;
/*
* Make sure interrupts are disabled.
*/
(void) bsp_isr_level;
rtems_interrupt_disable( bsp_isr_level );
bsp_boot_cmdline = cmdline;
/*
* Invoke Board Support Package initialization routine written in C.
*/
bsp_start();
该函数在beagle/startup/bspstart.c中:
void bsp_start(void)
{
#if IS_DM3730
const char* type = "dm3730-based";
#endif
#if IS_AM335X
const char* type = "am335x-based";
#endif
bsp_interrupt_initialize();
}
会调用bsp_interrupt_initialize函数,该函数在libbsp/shared/src/irq-generic.c中:
void bsp_interrupt_initialize(void)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
size_t i = 0;
/* Initialize handler table */
for (i = 0; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
bsp_interrupt_handler_table [i].handler = bsp_interrupt_handler_empty;
bsp_interrupt_handler_table [i].arg = (void *) i;
}
sc = bsp_interrupt_facility_initialize();
if (sc != RTEMS_SUCCESSFUL) {
bsp_fatal(BSP_FATAL_INTERRUPT_INITIALIZATION);
}
bsp_interrupt_set_initialized();
}
首先初始化handler表,然后调用bsp_interrupt_facility_initialize函数,该函数就对应具体的板子bsp中,对于beagle,函数在beagle/irq.c中:
rtems_status_code bsp_interrupt_facility_initialize(void)
{
int i;
uint32_t intc_ilrx;
/* AM335X TRM 6.2.1 Initialization Sequence */
mmio_write(omap_intr.base + OMAP3_INTCPS_SYSCONFIG, OMAP3_SYSCONFIG_AUTOIDLE);
mmio_write(omap_intr.base + OMAP3_INTCPS_IDLE, 0);
/* priority 0 to all IRQs */
for(intc_ilrx = 0x100; intc_ilrx <= 0x2fc; intc_ilrx += 4) {
mmio_write(omap_intr.base + intc_ilrx, 0);
}
/* Mask all interrupts */
for(i = BSP_INTERRUPT_VECTOR_MIN; i <= BSP_INTERRUPT_VECTOR_MAX; i++)
bsp_interrupt_vector_disable(i);
/* Install generic interrupt handler */
arm_cp15_set_exception_handler(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt);
arm_cp15_set_vector_base_address(bsp_vector_table_begin);
return RTEMS_SUCCESSFUL;
}
该函数是对beagle的中断向量进行初始化,首先是屏蔽所有中断,然后安装ARM的处理句柄handler。
bsp_interrupt_vector_disable函数如下:
void bsp_interrupt_vector_disable(rtems_vector_number vector)
{
uint32_t mask, cur;
uint32_t mir_reg = omap_get_mir_reg(vector, &mask);
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
cur = mmio_read(omap_intr.base + mir_reg);
mmio_write(omap_intr.base + mir_reg, cur | mask);
flush_data_cache();
}
这里要注意:bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
该函数用来判断输入的vector是否合理,也是保护interrupt server的128这个虚拟vector不会被disable。
void bsp_interrupt_dispatch(void)
{
const uint32_t reg = mmio_read(omap_intr.base + OMAP3_INTCPS_SIR_IRQ);
if ((reg & OMAP3_INTR_SPURIOUSIRQ_MASK) != OMAP3_INTR_SPURIOUSIRQ_MASK) {
const rtems_vector_number irq = reg & OMAP3_INTR_ACTIVEIRQ_MASK;
bsp_interrupt_handler_dispatch(irq);
} else {
/* Ignore spurious interrupts. We'll still ACK it so new interrupts
can be generated. */
}
omap_irq_ack();
}
函数作用:找到中断源irq,然后调用bsp_interrupt_handler_dispatch处理相应的irq。