wbybyb
驱动牛犊
驱动牛犊
  • 注册日期2007-01-16
  • 最后登录2008-03-06
  • 粉丝0
  • 关注0
  • 积分120分
  • 威望13点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
阅读:4521回复:4

在uboot的运行状态下,如何响应外部硬件的中断?

楼主#
更多 发布于:2008-01-17 21:05
如何在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。多谢!
hunbalo
驱动牛犊
驱动牛犊
  • 注册日期2004-04-21
  • 最后登录2020-10-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望124点
  • 贡献值0点
  • 好评度85点
  • 原创分1分
  • 专家分0分
  • 社区居民
沙发#
发布于: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中断处理要求的向量设置这些都得好好处理。
wbybyb
驱动牛犊
驱动牛犊
  • 注册日期2007-01-16
  • 最后登录2008-03-06
  • 粉丝0
  • 关注0
  • 积分120分
  • 威望13点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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),结果都没一点反应。
hunbalo
驱动牛犊
驱动牛犊
  • 注册日期2004-04-21
  • 最后登录2020-10-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望124点
  • 贡献值0点
  • 好评度85点
  • 原创分1分
  • 专家分0分
  • 社区居民
地板#
发布于:2008-01-29 14:40
不知道你的hw中断是映射到哪个向量上的, 这个得手册的具体说明
确认HW中断打开.
wbybyb
驱动牛犊
驱动牛犊
  • 注册日期2007-01-16
  • 最后登录2008-03-06
  • 粉丝0
  • 关注0
  • 积分120分
  • 威望13点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-01-29 20:46
因为我手头资料不全,不知道gpio21脚对应哪个中断号。但是,在linux kernel状态下都可以响应这个中断,在uboot下应该也是可以的噻。我在kernel下,是用的53这个号,即request_irq (53, my_irq, 0, "test", NULL)。为什么在uboot下设置这个中断向量表没有任何反应?
游客

返回顶部