在u-boot内进入低功耗模式,在中断时唤醒

时间:2012-10-17 15:17:40

标签: embedded arm interrupt u-boot arm9

我尝试实现低功耗"深度睡眠"按下按钮进入uboot的功能。按下按钮由linux处理,并设置了一个魔术代码,使u-boot知道保持睡眠不重启"

    printf ("\nDisable interrupts to restore them later\n");
    rupts = disable_interrupts();
    printf ("\nEnable interrupts to enable magic wakeup later\n");
    enable_interrupts();
    printf ("\nSuspending. Press button to restart\n");

    while(probe_button()/*gpio probe*/){
#if 1
            //FIXME recheck if that one actually needs an unmasked interrupt or any is ok
            __asm__ __volatile__(
                            "mcr p15, 0, %0, c7, c0, 4\n" /* read cp15 */
                            "mov %0, %0"
                            : "=r" (tmp)
                            :
                            : "memory"
            );
#else
            udelay (10000);
#endif
    }
    if (rupts) {
            printf ("\nRe-Enabling interrupts\n");
            enable_interrupts();
    }

不幸的是,无论是否使用热旋转,功耗都不会发生变化(功耗测量与芯片相关)。除此之外,如果我使用Wait-For-Interrupt CP15指令,它永远不会被唤醒。该按钮连接到其中一个GPIO。该平台是基于Marvell Kirkwood ARM9EJ-S的。

我手动启用了一些CONFIG_IRQ_*,并为arch_init_irq()以及do_irq()创建了实施,我认为存在问题。

根据CP15指令文档,它应该足以触发中断(无论是否被屏蔽!)。

除了上面的代码之外,谁能告诉我我做错了什么或需要做什么?

提前多多感谢!

1 个答案:

答案 0 :(得分:1)

我不确定这是否是你的aproach没有用于省电但你的内联汇编不正确的唯一原因。根据这个article你需要执行:

MOV R0, #0
MCR p15, 0, r0, c7, c0, 4

但你的内联汇编

        __asm__ __volatile__(
                        "mcr p15, 0, %0, c7, c0, 4\n" /* read cp15 */
                        "mov %0, %0"
                        : "=r" (tmp)
                        :
                        : "memory"
        );

产生

   0:   ee073f90    mcr 15, 0, r3, cr7, cr0, {4}
   4:   e1a03003    mov r3, r3
   8:   e12fff1e    bx  lr

我不确定你的意图是什么,但mov r3, r3没有任何效果。因此,您使用随机值进行协处理器调用。您还需要在mcr调用之前设置r3(mcr的ARM源寄存器)。顺便提一句,将“记忆”放入clobber列表it means

  
    

...将导致GCC不在汇编器指令的寄存器中保持缓存的内存值,而不是优化存储器或加载到该内存。

  

试试这一行,

asm("MOV R0, #0\n MCR p15, 0, r0, c7, c0, 4" : : : "r0");

它产生

   c:   e3a00000    mov r0, #0  ; 0x0
  10:   ee070f90    mcr 15, 0, r0, cr7, cr0, {4}

一般来说,为了省电,我建议在ARM的网站上使用article

奖金部分:
这个协处理器向后兼容性声明的一个小答案提供了WFI:

  
    

ARMv7处理器(包括Cortex-A8,Cortex-A9,Cortex-R4和Cortex-M3)都执行WFI指令进入“等待中断”模式。 在这些处理器上,早期处理器上使用的协处理器写入将始终作为NOP执行。因此,可以通过执行MCR和编写可以跨ARMv6K,ARMv6T2和ARMv7的所有配置文件工作的代码。 WFI指令,虽然在ARM11MPCore上,这将导致两次输入“等待中断”模式。要编写进入“等待中断”模式的完全可移植代码,必须在运行时读取CPUID寄存器以确定“等待中断”是否可用以及输入它所需的指令。