如何在uboot的运行状态下(此时linux kernel还未运行),响应外部按键产生的gpio中断,使uboot重启或做其他工作?在linux kernel运行状态下我已实现此功能,只要调用request_irq()注册一个中断就行了。但在uboot里似乎没有这样的函数和机制,该怎样把gpio产生的中断和我自己定义的中断服务程序关联起来?我的uboot版本是1.1.4,系统是AR9130 SoC,MIPS 24K 32-bit cpu 400MHz。
联系信箱:wb51job@163.com。多谢!
刚才没有看到你的cpu型号,就以arm为例,思想都差不多
在我的映像中,uboot似乎不支持中断,因为对一个loader来说, 没必要搞的太复杂。分析了一下代码,以PXA系列CPU为例。
看一下汇编的代码
.globl _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
中断向量都设置了,
再看这一段代码
#ifdef CONFIG_USE_IRQ
.align 5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs
.align 5
fiq:
get_fiq_stack
irq_save_user_regs /* someone ought to write a more */
bl do_fiq /* effiction fiq_save_user_regs */
irq_restore_user_regs
#else
.align 5
irq:
get_bad_stack
bad_save_user_regs
bl do_irq
.align 5
fiq:
get_bad_stack
bad_save_user_regs
bl do_fiq
#endif
我们看看当配置为中断方式时是怎么执行的,do_irq的代码在interrupts.c中
void do_irq (struct pt_regs *pt_regs)
{
printf ("interrupt request\n");
show_regs (pt_regs);
bad_mode ();
}
void bad_mode (void)
{
panic ("Resetting CPU ...\n");
reset_cpu (0);
}
还有
#ifdef CONFIG_USE_IRQ
/* enable IRQ/FIQ interrupts */
void enable_interrupts (void)
{
#error: interrupts not implemented yet
}
/*
* disable IRQ/FIQ interrupts
* returns true if interrupts had been enabled before we disabled them
*/
int disable_interrupts (void)
{
#error: interrupts not implemented yet
}
#else
void enable_interrupts (void)
{
return;
}
int disable_interrupts (void)
{
return 0;
}
#endif
估计如果在pxa 270上,配置为中断方式会编译不过去。
但是这是不是就说明在uboot下就不能支持中断了呢,写过单片机程序的人都知道怎么在没有调度的情况下处理中断,把pxa270当成一个大单片机来裸奔就可以了。
如果不用把uboot拷贝到RAM中执行,理解起来比价简单,在do_irq中实现你的中断处理代码就行,和单片机程序别无而样。
但是如果拷贝到RAM中执行,又使能了mmu的时候,就要相当的小心了。链接的地址,cpu中断处理要求的向量设置这些都得好好处理。