This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ARM 无法进入WFI 模式



我们的是使用OMAP138, ARM使用linux系统, DSP 是BIOS系统

现在想要让ARM 的linux 系统进入WFI 模式( ARM Wait-For-Interrupt Sleep Mode)

按照omap-138的datasheet 介绍

You can enable the WFI mode via the CP15 register #7 using the following instruction:
• MCR p15, #0, <Rd>, c7, c0, #4
Once the ARM module transitions into the WFI mode, it will remain in this state until an interrupt
(IRQ/FIQ) occurs.
The following sequence exemplifies how to enter the WFI mode:
• Enable any interrupt (for example, an external interrupt) that you plan to use as the wake-up
to exit from the WFI mode.
• Enable the WFI mode using the following CP15 instruction:
MCR p15, #0, r3, c7, c0, #4
The following sequence describes the procedure to wake-up from the WFI mode:
• To wake-up from the WFI mode, trigger any enabled interrupt (for example, an external inter
• The ARM’s PC jumps to the IRQ/FIQ vector and you must handle the interrupt in an interrup
routine (ISR).

我在linux 内核态执行了语句

asm ( " MCR p15, #0, r3, c7, c0, #4\n\t" );

但是系统并没有发生什么变化,供电的电流也没什么变化,好像并没有进入WFI模式

请问如何让arm的linux 进入WFI模式?

  • 请问是否在supervisor模式下执行WFI语句吗?

    To enable the WFI mode, the ARM needs to be in supervisor mode. 

  • 请问linux 下如何进去  supervisor mode ?是在软中断中吗

  • 是的。
    To enter supervisor mode from user mode, generate a software interrupt (SWI).

  • 你好,我在内核定时器中执行了asm ( "MCR p15, #0, r3, c7, c0, #4\n\t" );语句,但是系统也是没什么变化的,

    理论上内核定时器的执行是在软中断的,那么这条语句应该是supervisor mode 模式下执行的

    static void wfi_timer_func(unsigned long arg)
    {
      printk("wfi_timer_func\n");
      printk("asm start 111 \n");

        asm ( "    teq    r3, #0\n\t");
      asm ( "MCR p15, #0, r3, c7, c0, #4\n\t" );
      printk("asm end111\n");

    //  asm ( "mcr p15, #0, r1, c7, c0, #4\n\t" );
    //  printk("asm end222\n");


      return 0; 
    }

    struct timer_list wfitimer; 

    static int funcIn(void) 

     printk("funcIn\n");
    // struct timer_list wfitimer; 
      init_timer(&wfitimer);
      wfitimer.data = 0x1234;
      wfitimer.function = wfi_timer_func;
      wfitimer.expires = jiffies + msecs_to_jiffies(1000); 
      add_timer(&wfitimer);
      
        return 0; 
    }

    static void funcOut(void) 

      printk("funcIn\n");
        return; 

    理论上内核定时器的执行是在软中断的,那么这条语句应该是supervisor mode 模式下执行的

    但是系统依旧没什么变化,我的执行过程是否有什么问题

     

     

    在TI 的官网上,找到进入WFI 的示例代码,如下

    int main(void)
    {

        printf("OMAPL138 is in WFI mode. Insert/Remove the SD card to generate interrupt for wakeup.\n");

        /* The Local PSC number for GPIO is 3. GPIO belongs to PSC1 module.*/
        PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON,
                 PSC_MDCTL_NEXT_ENABLE);

        /* Pin Multiplexing of pins GP6[12], GP6[13], GP2[12], GP0[9], for LEDs in OMAPL138 LCDK board */
        PinMuxSetup_leds();

        /* LEDs SETUP */

            /* Sets the pin 109 (GP6[12]) as output.*/
            GPIODirModeSet(SOC_GPIO_0_REGS, 109, GPIO_DIR_OUTPUT);

            /* Sets the pin 110 (GP6[13]) as output.*/
            GPIODirModeSet(SOC_GPIO_0_REGS, 110, GPIO_DIR_OUTPUT);

            /* Sets the pin 45 (GP2[12]) as output.*/
            GPIODirModeSet(SOC_GPIO_0_REGS, 45, GPIO_DIR_OUTPUT);

            /* Sets the pin 10 (GP0[9]) as output.*/
            GPIODirModeSet(SOC_GPIO_0_REGS, 10, GPIO_DIR_OUTPUT);


        /* Initializes the UART instance.*/
        UARTStdioInit();

        /* Pin Multiplexing of pin 0 of GPIO Bank 4.*/
        GPIOBank4Pin0PinMuxSetup();

        /* Sets the pin 65(GP4[0]) as input.*/
        GPIODirModeSet(SOC_GPIO_0_REGS, 65, GPIO_DIR_INPUT);

        /*
        ** Configure rising edge and falling edge triggers on pin 65 to generate
        ** an interrupt
        */
        GPIOIntTypeSet(SOC_GPIO_0_REGS, 65, GPIO_INT_TYPE_BOTHEDGE);

        /* Enable interrupts for Bank 4.*/
        GPIOBankIntEnable(SOC_GPIO_0_REGS, 4);

        /* Configuring the AINTC to handle interrupts.*/
        SetupInt();

        /* Configure GPIO interrupts */
        ConfigureIntGPIO();

        //UARTPuts("StarterWare GPIO Demo Application.\r\n", -2);
        //UARTPuts("Insert an MMC/SD card.\r\n", -2);

        printf("StarterWare GPIO Demo Application\n");
        printf("Insert an MMC/SD card.\n");

        //Titus : ARM WFI code
        SysCfgRegistersUnlock();

        asm ( "    teq    r1, #0\n\t");

        asm ( "    mcr p15, #0, r1, c7, c0, #4\n\t" );

        //Here, code get stuck due to WFI and it resume when SD card interrupt raised.

        SysCfgRegistersLock();

        //LED D5 would glow when ARM comes out of WFI mode (i.e, when interrupt generated).
        GPIOPinWrite(SOC_GPIO_0_REGS, 109, GPIO_PIN_HIGH);

        printf("Comes out of WFI mode; Resume to normal operation.\n");

        while(1)
        {
            if(flag == 1)
            {
                CheckCardStatus();
            }
        }

    }

    这边是否有完整的代码?

    以及SysCfgRegistersUnlock();和    SysCfgRegistersLock();

    这些函数具体都完成了什么功能呢

    请帮忙看看,谢谢啦

     

  • 置顶贴里有基于starterware的示例。
    http://www.deyisupport.com/question_answer/dsp_arm/omap_l1x/f/54/t/103692.aspx