uClinux for bf561中的中断处理(1):中断初始化

本文详细解析了uClinux操作系统在bf561平台上的中断初始化过程,包括中断向量表的配置、中断优先级的设置等内容。介绍了关键函数如init_IRQ的作用及内部实现细节。
 
  
在uClinux初始化的过程中,就会配置好相应的中断向量表,并根据用户的配置来设置外部中断的优先级。
/* init/main.c */
asmlinkage void __init start_kernel(void)
{
       sort_main_extable();
       trap_init();
       rcu_init();
       init_IRQ();
       pidhash_init();
       init_timers();
       hrtimers_init();
       softirq_init();
       timekeeping_init();
       time_init();
}
其中的trap_init函数只是简单地设置了中断3(Exception)的中断向量(trap,汇编代码),实际上在后面的init_IRQ函数中又设置了一道。其作用是防止rcu_init出错时可以捕捉到。需要注意的是,此时uClinux还没有打开中断,即IMASK还是bf561复位以后的默认值,但是在复位后Exception中断默认是打开的,因此才有可能捕捉到rcu_init的异常。
init_IRQ是一个主要的中断初始化函数,包括中断向量的写入,中断优先级的配置等等。不过很奇怪的是,init_IRQ居然不处理中断1,即Reset中断!
bf561支持64个外部中断,后4个保留,其余60个可以通过宏来控制它们的优先级,这些宏的值可以介于[7-15]之间,uClinux将根据这60个值来配置SIC_IAR。
#define CONFIG_IRQ_PLL_WAKEUP        7
#define CONFIG_IRQ_DMA1_ERROR              7
#define CONFIG_IRQ_DMA2_ERROR              7
#define CONFIG_IRQ_IMDMA_ERROR           7
#define CONFIG_IRQ_PPI0_ERROR         7
#define CONFIG_IRQ_PPI1_ERROR         7
#define CONFIG_IRQ_SPORT0_ERROR           7
#define CONFIG_IRQ_SPORT1_ERROR           7
 
#define CONFIG_IRQ_SPI_ERROR           7
#define CONFIG_IRQ_UART_ERROR        7
#define CONFIG_IRQ_RESERVED_ERROR      7
#define CONFIG_IRQ_DMA1_0                7
#define CONFIG_IRQ_DMA1_1                7
#define CONFIG_IRQ_DMA1_2                7
#define CONFIG_IRQ_DMA1_3                7
#define CONFIG_IRQ_DMA1_4                7
 
#define CONFIG_IRQ_DMA1_5                7
#define CONFIG_IRQ_DMA1_6                7
#define CONFIG_IRQ_DMA1_7                7
#define CONFIG_IRQ_DMA1_8                7
#define CONFIG_IRQ_DMA1_9                7
#define CONFIG_IRQ_DMA1_10               7
#define CONFIG_IRQ_DMA1_11               7
#define CONFIG_IRQ_DMA2_0                7
 
#define CONFIG_IRQ_DMA2_1                7
#define CONFIG_IRQ_DMA2_2                7
#define CONFIG_IRQ_DMA2_3                7
#define CONFIG_IRQ_DMA2_4                7
#define CONFIG_IRQ_DMA2_5                7
#define CONFIG_IRQ_DMA2_6                7
#define CONFIG_IRQ_DMA2_7                7
#define CONFIG_IRQ_DMA2_8                7
 
#define CONFIG_IRQ_DMA2_9                7
#define CONFIG_IRQ_DMA2_10               7
#define CONFIG_IRQ_DMA2_11               7
#define CONFIG_IRQ_TIMER0                 7
#define CONFIG_IRQ_TIMER1                 7
#define CONFIG_IRQ_TIMER2                 7
#define CONFIG_IRQ_TIMER3                 7
#define CONFIG_IRQ_TIMER4                 7
 
#define CONFIG_IRQ_TIMER5                 7
#define CONFIG_IRQ_TIMER6                 7
#define CONFIG_IRQ_TIMER7                 7
#define CONFIG_IRQ_TIMER8                 7
#define CONFIG_IRQ_TIMER9                 7
#define CONFIG_IRQ_TIMER10               7
#define CONFIG_IRQ_TIMER11               7
#define CONFIG_IRQ_PROG0_INTA         7
 
#define CONFIG_IRQ_PROG0_INTB         7
#define CONFIG_IRQ_PROG1_INTA         7
#define CONFIG_IRQ_PROG1_INTB         7
#define CONFIG_IRQ_PROG2_INTA         7
#define CONFIG_IRQ_PROG2_INTB         7
#define CONFIG_IRQ_DMA1_WRRD0             7
#define CONFIG_IRQ_DMA1_WRRD1             7
#define CONFIG_IRQ_DMA2_WRRD0             7
 
#define CONFIG_IRQ_DMA2_WRRD1             7
#define CONFIG_IRQ_IMDMA_WRRD0           7
#define CONFIG_IRQ_IMDMA_WRRD1           7
#define CONFIG_IRQ_WDTIMER                    7
下表简要列出了各个中断处理的功能,如无特别说明,其入口均位于arch/blackfin/mach-common/interrupt.s文件中。
中断
入口
功能
EMU
evt_emulation
保存当前各寄存器的值
调用irq_panic输出这些值并终止运行
RST
未处理
 
NMI
evt_evt2
保存寄存器的值
调用asm_do_IRQ(arch/blackfin/mach-kernel/irqchip.c)
恢复寄存器的值并从发生异常的位置继续执行
EVX
trap
此入口代码位于arch/blackfin/mach-common/entry.s。
它将根据SEQSTAT_EXCAUSE寄存器中的异常原因调用_extable中提供的回调函数,在entry.s中定义了64个入口,主要是以下几个处理函数:
ex_syscall:/* 0x00 – Linux系统调用异常 */
ex_soft_bp:/* 0x01 – 软件断点异常 */
ex_trap_c:/* 所有未经特殊处理的异常都将由它处理 */
ex_spinlock:/* 0x04 - User Defined */
ex_single_step:/* 0x10 – 单步执行时中断异常 */
ex_dcplb:/* 0x23 – Data CPLB异常 */
ex_icplb:/* 0x2B - Instruction CPLB异常 */
Reserved
保留
 
IVHW
evt_ivhw
保存当前各寄存器的值
调用irq_panic输出这些值并终止运行
IVTMR
evt_timer
全部跳转到__common_int_entry,在此处保存各寄存器的值,然后调用do_irq,再调用return_from_int,最后恢复各寄存器的值并返回到中断之前的位置继续执行。
IVG7
evt_evt7
IVG8
evt_evt8
IVG9
evt_evt9
IVG10
evt_evt10
IVG11
evt_evt11
IVG12
evt_evt12
IVG13
evt_evt13
IVG14
evt14_softirq
此入口代码位于arch/blackfin/mach-common/entry.s。
它将IMASK保存到R0中,并将IMASK设置为0。然后返回到中断之前的位置继续执行。
IVG15
evt_system_call
保存当前各寄存器的值
调用system_call
恢复各寄存器的值并返回到中断之前的位置继续执行
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌云阁主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值