Tickless idle and interrupts which don’t need scheduler service

Dears, for my ultra low power application I need to find way how to quickly proceed interrupt which doesn’t need scheduler service and return immediately back into sleep mode. Routines fnEnterSleepPRE() and fnEnterSleepPOST() consume long time (I2C bus communication is necessary to achive ultra low consumption of board at the sleep mode) which takes battery energy. It’s the reason why it’s not suitable to do it by standard way through scheduler. Any idea ? I don’t feel to be enough familiar with FreeRTOS to solve this phylosophic question myself. In old one OS (cooperative) we are using code, see the following snippet. Main idea is to inform OS from interrupt handler’s through procesFlag. If procesFlag is set to “RUN” OS service will follow, if not it return’s into sleep mode immediately.
        procesFlag = SLEEP;
        fn_EnterSleepPRE ();

        do{
            /* Disable interrupts first to avoid interrupt executing between EM2 */
            INT_Disable();
            /* Enter energy mode */
            EMU_EnterEM2(true);
            /* ISR for any pending and enabled IRQs will be executed after this */
            INT_Enable();
        } while(procesFlag != RUN); /* if any interrupt routine need OS service, set procesFlag == RUN; if not, uP fall at once into sleep mode */

        fn_EnterSleepPOST ();
I’m using EFM32GG, Cortex-M3. My solution is now based on FreeRTOSv9.0.0FreeRTOSDemoCORTEXEFM32GiantGeckoSimplicityStudioLowPowerDemolowpowertickmanagement_BURTC.c Thank’s in advance. Zdenek

Tickless idle and interrupts which don’t need scheduler service

Are you using configUSETICKLESSIDLE? If so can you use the pre and post sleep macros to add a loop around the code that goes into sleep if a context switch is not pending whn your efm wakes?

Tickless idle and interrupts which don’t need scheduler service

Hi Dave, thank’s for your answer. Yes, I’m using configUSETICKLESSIDLE = 1, and special port of vPortSuppressTicksAndSleep() for EFM – see FreeRTOSv9.0.0FreeRTOSDemoCORTEXEFM32GiantGeckoSimplicityStudioLowPowerDemolowpowertickmanagement_BURTC.c. I’m not able follow your advice, pls. can you explain it more precisely or write some snippet of code? Thank’s. Zdenek

Tickless idle and interrupts which don’t need scheduler service

The code in that file contains the following: ~~~ configPRESLEEPPROCESSING( xModifiableIdleTime ); /* xExpectedIdleTime being set to 0 by configPRESLEEPPROCESSING() means the application defined code has already executed the WAIT instruction. */ if( xModifiableIdleTime > 0 ) { __asm volatile( “dsb” ); SLEEP_Sleep(); __asm volatile( “isb” ); } /* Allow the application to define some post sleep processing. */ configPOST_SLEEP_PROCESSING( xModifiableIdleTime ); ~~~ configPRESLEEPPROCESSING() and configPOSTSLEEPPROCESSING() can be defined in FreeRTOSConfig.h to contain any code you want. I think the suggestion was to define them to create a loop around the sleep function that is executed continuously until the interrupt that woke your CPU from sleep attempts to perform a context switch. For example, something like this: ~~~

define configPRESLEEPPROCESSING()

while( context switch not pending ) {

define configPOSTSLEEPPROCESSING()

} ~~~ then you will re-enter sleep again immediately if the CPU woke because of an interrupt that didn’t attempt a context switch.

Tickless idle and interrupts which don’t need scheduler service

Hi, thank’s for your reply. I understood your idea. It’s a great tool – prepare hook’s via macros to modify code without attacking source.. But, it’s a problem in my case. When I prepare solution according your instructions, interrupts stay disabled inside of loop prepared via macros and nothing happen. Explanation : sleepSLEEP() function which I’m using from Silabs library (sleep.c) call INTDisable() before going into EM2 sleep mode. INTDisable() is also used before sleepSLEEP(). There is used “lock level counter”. Value of this counter is 2, before falling into EM2. It means, that when uP wake up, call INTEnable() from sleepSLEEP() (value of counter = 1 and interrupt stays disabled) and return back into FreeRTOS code. Interrupts will be enabled on third line after “configPOSTSLEEPPROCESSING( xModifiableIdleTime );” where you recommend me to put “while” bracket. How to solve this ? Thank’s in advance Zdenek < ~~~ SLEEPEnergyModet SLEEPSleep(void) { SLEEPEnergyMode_t allowedEM; INT_Disable(); allowedEM = SLEEP_LowestEnergyModeGet(); if ((allowedEM >= sleepEM1) && (allowedEM <= sleepEM3)) { SLEEP_EnterEMx(allowedEM); } else { allowedEM = sleepEM0; } INT_Enable(); return(allowedEM); } ~~~ >

Tickless idle and interrupts which don’t need scheduler service

I’m not sure I’m fully following, but how about editing the fucntion, or providing your own modified version of the function, rather than just using the library function exactly as it is.

Tickless idle and interrupts which don’t need scheduler service

The problem we face is associated with the order in which the instructions bellow are performed. INT_Disable(); configPRESLEEPPROCESSING(); SLEEP(); configPOSTSLEEPPROCESSING(); INT_Enable(); So when the loop around the sleep function is made between configPRESLEEPPROCESSING and configPOSTSLEEPPROCESSING, then no interrupt execution can be performed because of disabled INT. It will only wake and sleep again.