FreeRTOS in tickless mode and LLS3

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FreeRTOS in tickless mode and LLS3

1,989 Views
EugeneHiihtaja
Senior Contributor I

Hi !

I have taken FreeRTOS example from SDK and configure it in tickless mode where Systick timer only is used as clock source. 

Everything works fine in tick and tickless configurations.

After that I have put MCU to LLS3 low power mode and wakeup it to RUN mode back be using external LLWU enabled GPIO pin. Typical LLWU clean up is executed ( in interrupt handler ) and PLL lock ( MGC in PEE mode) are executed

as first code after wake up.

/* Wait for PLL lock. MCG in PEE mode in RUN. */
while (!(kMCG_Pll0LockFlag & CLOCK_GetStatusFlags()))
{
}
CLOCK_SetPeeMode();

...

Everything works fine in RTOS use Systick and tickless mode is disabled.

But in tickless mode, systick timer is not recovered and task scheduler dosn't work any more.

ApplicationTickHook() is not called anymore and execution is not continued.

Can it be so that fsl_tickless_systick.c is implemented in way what block LLS3 recovering some how ?

It is just not taken in account  ?

Can you suggest what fix need to be done if RTOS can continue execution after LLS3 in Tickless mode ?

Regards,

Eugene

0 Kudos
9 Replies

1,130 Views
zahidul3
Contributor III

Hi Eugene,

I am facing same issue getting out of LLS3 in tickless mode on the K82. How did you resolve this issue?

0 Kudos

1,651 Views
EugeneHiihtaja
Senior Contributor I

Hi !

I think this is just not correct implementation of wait mode in vPortSuppressTicksAndSleep() function.

It is done like this:

"

__asm volatile( "dsb" ::: "memory" );
__asm volatile( "wfi" );
__asm volatile( "isb" );

"

but should be like this for have clean up from all previous  low power modes:

"

/* Wait mode. */
SMC_PreEnterWaitModes();
SMC_SetPowerModeWait(SMC);
SMC_PostExitWaitModes();

"

Deep sleep bit should be cleaned  becouse it is set in LLS3 mode.

/* configure Normal Wait mode */
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;

Is this right workaround ?

Regards,

Eugene

0 Kudos

1,651 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Eugene,

   Yes, you can refer to the SDK power mode code:

        SMC_PreEnterWaitModes();
            SMC_SetPowerModeWait(SMC);
            SMC_PostExitWaitModes();

void SMC_PreEnterWaitModes(void)
{
    g_savedPrimask = DisableGlobalIRQ();
    __ISB();
}

void SMC_PostExitWaitModes(void)
{
    EnableGlobalIRQ(g_savedPrimask);
    __ISB();
}

status_t SMC_SetPowerModeWait(SMC_Type *base)
{
    /* configure Normal Wait mode */
    SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
    __DSB();
    __WFI();
    __ISB();

    return kStatus_Success;
}

disable the interrup before enter the wait mode, just make sure, when entering the wait mode, no interrupt happens, otherwise the wait mode entry may be failed.

About LLS mode, the code should be:

            SMC_PreEnterStopModes();
            SMC_SetPowerModeLls(SMC);
            SMC_PostExitStopModes();

#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
status_t SMC_SetPowerModeLls(SMC_Type *base
#if ((defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \
     (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO))
                             ,
                             const smc_power_mode_lls_config_t *config
#endif
                             )
{
    uint8_t reg;

    /* configure to LLS mode */
    reg = base->PMCTRL;
    reg &= ~SMC_PMCTRL_STOPM_MASK;
    reg |= (kSMC_StopLls << SMC_PMCTRL_STOPM_SHIFT);
    base->PMCTRL = reg;

/* configure LLS sub-mode*/
#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE)
    reg = base->STOPCTRL;
    reg &= ~SMC_STOPCTRL_LLSM_MASK;
    reg |= ((uint32_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT);
    base->STOPCTRL = reg;
#endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */

#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)
    if (config->enableLpoClock)
    {
        base->STOPCTRL &= ~SMC_STOPCTRL_LPOPO_MASK;
    }
    else
    {
        base->STOPCTRL |= SMC_STOPCTRL_LPOPO_MASK;
    }
#endif /* FSL_FEATURE_SMC_HAS_LPOPO */

    /* Set the SLEEPDEEP bit to enable deep sleep mode */
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

    /* read back to make sure the configuration valid before enter stop mode */
    (void)base->PMCTRL;
    __DSB();
    __WFI();
    __ISB();

    /* check whether the power mode enter LLS mode succeed */
    if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)
    {
        return kStatus_SMC_StopAbort;
    }
    else
    {
        return kStatus_Success;
    }
}

Wish it helps you!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,651 Views
EugeneHiihtaja
Senior Contributor I

Hi Kerry !

I think systick is configured properly and decrementing values.

Current value is take before last function what put MCU to LLS mode is executed.

Control and Load registers always the same.

uint32_t systick_current_value_before = portNVIC_SYSTICK_CURRENT_VALUE_REG; // Before
PM_PowerModeSwitch(&targetConfig, NULL);

..

 uint32_t systick_current_value_after = portNVIC_SYSTICK_CURRENT_VALUE_REG; // After

portNVIC_SYSTICK_CURRENT_VALUE_REG - 0xAE6 -> 0x6DB  // Before and after
portNVIC_SYSTICK_CTRL_REG - 0x10007
portNVIC_SYSTICK_LOAD_REG - 0xBB7F

Out task Task1-
In task _idle_P ------
++vPortSuppressTicksAndSleep 957

 -- No exit !!! 

You can see that code exit from Task and go to Idle and execute proprietary vPortSuppressTicksAndSleep( 957 )

and not exit any more.

State machine is not so clear for me yet, but looks like no any interrupts what can resume RTOS from idle.

Looks like LLS3 entry has some effect what is not known yet.

 

Eugene

0 Kudos

1,651 Views
EugeneHiihtaja
Senior Contributor I

Hi Kerry !

Yes, I have used FRDM-K82 board at beginning but now my project is huge.

I think testing example can be combined from SDK examples frdmk82f_freertos_tickless and frdmk82f_power_mode (switch).

Put MCU to LLS3 mode and wakeup via SW3 button.

All LLWU clean up is the same and etc.

From my side I have add only this code :

/* Wait for PLL lock. MCG in PEE mode in RUN. */
while (!(kMCG_Pll0LockFlag & CLOCK_GetStatusFlags()))
{
}
CLOCK_SetPeeMode();

But what can be under suspicious in  fsl_tickless_systick.c ? if you have idea I can try .

Regards,

Eugene

0 Kudos

1,651 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Eugene,

    After you wake up and do the PEE configuration.

  Then, also read the systick according register, and use the uart to printf it, check the systick register, any difference with the data before enter the LLS mode?

 


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,651 Views
EugeneHiihtaja
Senior Contributor I

Hi Kerry !

1.

After wakeup , the first code what is executed is put  MCG to PEE mode back.

/* Wait for PLL lock. MCG in PEE mode in RUN. */
while (!(kMCG_Pll0LockFlag & CLOCK_GetStatusFlags()))
{
}
CLOCK_SetPeeMode();

2. In normal mode when Systick generated every tick -> no need any systick reinitialization , it is resumed and continue with the same clock

    as before going to LLS3 mode ( After PLL lock and set to PEE mode ).

  Problem coming in TickLess mode only where NXP proprietary code is taken in use fsl_tickless_systick.c  .

Any simple reenabling of SystickTimer and Interrupts dosn't help. Some values in your framework is used for calculate sleep compenstation

and all Systick registers and Aux variables should be reinitialized in smart way.

Is any idea how to resume freeRTOS from LLS3 when it configured in Tickless mode ?

Regards,

Eugene

0 Kudos

1,651 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Eugene,

  Do you also use the FRDM-K82 board?

 Please also tell me which project in the SDK you are using.

  Or you can send me your test project, which include the LLS mode enter and recovery.

  When I have time, I will help you to check it in details.


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,651 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Eugene,

   If before you enter the LLS mode in the PEE mode, after wake up, the clock mode will turned to the PBE mode, so if you want to work at the PEE mode, you need to do the PBE-PEE clock mode convert, do you do this?

   After you configure the PEE mode, you also can reconfigure the systick, then check whether your FreeRTOS works or not?

 


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos