阅读:4612回复:4
在uboot的运行状态下,如何响应外部硬件的中断?
如何在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。多谢! |
|
沙发#
发布于:2008-01-29 13:01
刚才没有看到你的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中断处理要求的向量设置这些都得好好处理。 |
|
板凳#
发布于:2008-01-29 14:21
多谢楼上的指点。不过,在MIPS下似乎不太一样。在uboot的start.s文件中,关于中断向量表的代码是这样的:
#define RVECENT(f,n) \ b f; nop #define XVECENT(f,bev) \ b f ; \ li k0,bev .set noreorder .globl _start .text _start: RVECENT(reset,0) /* U-boot entry point */ RVECENT(reset,1) /* software reboot */ RVECENT(romReserved,2) RVECENT(romReserved,3) .... RVECENT(romReserved,63) XVECENT(romExcHandle,0x200) /* bfc00200: R4000 tlbmiss vector */ RVECENT(romReserved,65) RVECENT(romReserved,66) .... RVECENT(romReserved,79) XVECENT(romExcHandle,0x280) /* bfc00280: R4000 xtlbmiss vector */ RVECENT(romReserved,81) .... RVECENT(romReserved,95) XVECENT(romExcHandle,0x300) /* bfc00300: R4000 cache vector */ RVECENT(romReserved,97) .... RVECENT(romReserved,111) XVECENT(romExcHandle,0x380) /* bfc00380: R4000 general vector */ RVECENT(romReserved,113) .... RVECENT(romReserved,127) /* We hope there are no more reserved vectors! * 128 * 8 == 1024 == 0x400 * so this is address R_VEC+0x400 == 0xbfc00400 */ reset: /* * Clearing CP0 registers - WAR for the Linux hang issue */ mtc0 zero, $0 .... /* Exception handlers. */ romReserved: b romReserved romExcHandle: b romExcHandle 我对上面定义的128个中断没看懂是怎么调用的。而且,我尝试过把所有的RVECENT(romReserved, X) 都改成RVECENT(reset, X),结果都没一点反应。 |
|
地板#
发布于:2008-01-29 14:40
不知道你的hw中断是映射到哪个向量上的, 这个得手册的具体说明
确认HW中断打开. |
|
地下室#
发布于:2008-01-29 20:46
因为我手头资料不全,不知道gpio21脚对应哪个中断号。但是,在linux kernel状态下都可以响应这个中断,在uboot下应该也是可以的噻。我在kernel下,是用的53这个号,即request_irq (53, my_irq, 0, "test", NULL)。为什么在uboot下设置这个中断向量表没有任何反应?
|
|