Issues with freeRTOS tickless on K21

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

Issues with freeRTOS tickless on K21

5,214 Views
martis
Contributor II

I am using freertos in my application, and I am now trying to lower the power consumption by implementing tickless mode.

 

However, I have some issues regarding the implementation of vPortSuppressTicksAndSleep.

 

I used the freertos_tickless_twrk21f120m project from SDK_2.0_TWR-K21F120M as a starting point. As it is, the example seems to be working, but when starting to modify it and test other frequencies, it does not behave as expected.

 

The LPTMR is setup with the default config which means 1khz clock.
However, configLPTMR_RATE_HZ is set to SystemCoreClock, which is 120000000.
When calculating the amount of LPTMR counts for one tick, the following expression is used:

 

ulLPTimerCountsForOneTick = configSYSTICK_CLOCK_HZ / configLPTMR_RATE_HZ;

 

As these two are defined to be the same, ulLPTimerCountsForOneTick is one. In the example  both configTICK_RATE_HZ and configLPTMR_RATE_HZ is 1000, which means that it is correct that one tick is 1 tick on the LPtimer.
But for the general case, the calculation doesn't make any sense, as the it doesn't include anything about the tick rate.

 

The correct calculation should be:
ulLPTimerCountsForOneTick = configLPTMR_RATE_HZ / configTICK_RATE_HZ;

 

Fixing this issue allows me to play with different frequency settings of the LPTimer and RTOStick, and the timing looks correct.
But this is only until the sleep period is interrupted by an external interrupt, which sometimes causes the project to hang. This is due to the
vTaskStepTick( ulCompleteTickPeriods );
which is called with
ulCompleteTickPeriods = LPTMR_GetCurrentTimerCount(TICKLESS_LPTMR_BASE_PTR);
as parameter.

 

This again assumes that the LPTMR is at the same frequency as the rtos tick.

 

Adding:
ulCompleteTickPeriods /= ulLPTimerCountsForOneTick;
after reading out the value scales the value correctly, and avoids getting caught in the configASSERT in vTaskStepTick due to wrong input.

 

I do not know if there are any more errors in this implementation, so it would be great if someone could have a look at this.

Labels (1)
23 Replies

3,831 Views
davidjurajda
NXP Employee
NXP Employee

Hello Everybody,

 

I would like to share fix for discussed issue.

There are two FreeRTOS versions (8.2.3 and 9.0.0) available in distribution system (mcuxpresso.nxp.com).

Version depends on the release in which specific board become supported.

 

Each version have slightly different code organization for low power tickless idle mode.

 

I have prepared patch with following updates:

---- v. 8.2.3. ----

boards\<board>\rtos_examples\freertos_tickless\FreeRTOSConfig.h

    original:    #define configLPTMR_RATE_HZ (configCPU_CLOCK_HZ)

    fixed:       #define configLPTMR_CLOCK_HZ (1000)

 

freertos_8.2.3\Source\portable\<tool>\<architecture>\port.c:

    vPortSuppressTicksAndSleep()

    original:    ulCompleteTickPeriods = LPTMR_GetCurrentTimerCount(TICKLESS_LPTMR_BASE_PTR);

    fixed:       ulCompleteTickPeriods = LPTMR_GetCurrentTimerCount(TICKLESS_LPTMR_BASE_PTR)/ulLPTimerCountsForOneTick;

 

    prvSetupTimerInterrupt()

    original:    ulLPTimerCountsForOneTick = configSYSTICK_CLOCK_HZ / configLPTMR_RATE_HZ;

    fixed:       ulLPTimerCountsForOneTick = ( configLPTMR_CLOCK_HZ / configTICK_RATE_HZ );

 

---- v. 9.0.0. ----

boards\<board>\rtos_examples\freertos_tickless\FreeRTOSConfig.h

    original:    #define configLPTMR_RATE_HZ                     (configCPU_CLOCK_HZ)

    fixed:       #define configLPTMR_CLOCK_HZ                    (1000)

 

freertos_9.0.0\Source\portable\<tool>\<architecture>\fsl_tickless_lptmr.c

    vPortSuppressTicksAndSleep()

    original:    ulCompleteTickPeriods = LPTMR_GetCurrentTimerCount(pxLptmrBase);

    fixed:       ulCompleteTickPeriods = LPTMR_GetCurrentTimerCount(pxLptmrBase)/ulLPTimerCountsForOneTick;

 

    prvSetupTimerInterrupt(

    original:    ulLPTimerCountsForOneTick = configSYSTICK_CLOCK_HZ / configLPTMR_RATE_HZ;

    fixed:       ulLPTimerCountsForOneTick = ( configLPTMR_CLOCK_HZ / configTICK_RATE_HZ );

 

I would like to explain configLPTMR_CLOCK_HZ macro, because it is confusing. Its purpose is to pass low power timer clock frequency to tick functions in FreeRTOS core files.

 

There is difference in comparison with systick timer (common across different architectures), because systick timer is initialized directly in official port.c (in v 8.2.3 or in fsl_tickless_lptmr.c in 9.0.0) file (prvSetupTimerInterrupt function). The low power timers are different between families (kinetis, lpc) and hence it need to be initialized in application (LPTMR_Init in main). Macro configLPTMR_CLOCK_HZ cannot be changed without update of low power timer initialization in main function (LPTMR_Init). It is not perfect, but it is the reason for existence of configLPTMR_CLOCK_HZ. Current implementation have this inconsistency, and we are going to rework it.

 

Another topic to explain is split of port.c into several files in v 9.0.0. It is because we are supporting several different low power timers across one architecture (e.g. ARM_CM4F). LPTMR is used in kinetis line, and RTC in LPC line.

 

I would like to thanks Martis and other people in discussion for reporting the issue. I am sorry for delay in my reaction.

 

Regards,

David (FreeRTOS integrator)

0 Kudos
Reply

3,831 Views
gsmgbl
Contributor IV

Hi David,

I am using the V8.2.3 on my IAR and I am a beginner for FreeRTOS and first implementing the low power capability.

My MCU is Kinetis KL7.

First, I measured my board with no tickles idle enabled (#define configUSE_TICKLESS_IDLE 0), then my current consumption is 12mA approx.

Then I enabled (#define configUSE_TICKLESS_IDLE 1), then my current consumption get down to 4mA. 

After you posted this patch, then I enabled both the (#define configUSE_TICKLESS_IDLE 1 and #define configSYSTICK_USE_LOW_POWER_TIMER 1) and followed the freertos_tickles project, but it is measured as 4mA and no further power saving.

Did I miss something when I am following the freertos_tickless project?

My target is get down to something close to the VLPR mode, which approx. a few hundred uA.

Do you have any recommendations or tips that guide me on the right path? any example project that I can try out?

Please advise. Thank you!

Regards,

Gilbert

0 Kudos
Reply

3,831 Views
BlackNight
NXP Employee
NXP Employee

Hi Gilbert,

I assume you enter low power mode in your idle hook?

Enabling tickless idle mode reduces the amount of ticks (see Low Power with FreeRTOS: Tickless Idle Mode | MCU on Eclipse ). So if you are in low power mode, you have less activities and less interrupts from the low power mode. Of course this all depends on your system activities, but it looks you get some good savings.

Switching from SysTick to LPTMR with enabling low power timer does not save you anything (well, apart of some minor current): you still get interuped the same way as in tickless mode with SysTick. The usage of the low power timer makes sense because in some low power mode this is one of the few timers still running (SysTick not running any more). So you get the most benefit with tickless idle and low power timer if you actually go into deep sleep modes. An article about this is here: IoT: FreeRTOS Down to the Micro Amps | MCU on Eclipse 

Note that for the deep low power modes you need to plan accordingly, as debugging might not be possible. Additionally you might have to use the extra hooks to decide if the application really has to go into low power mode. On that topic see Starting Point for Kinetis Low Power LLS Mode | MCU on Eclipse   and Tickless Low power features in FreeRTOS .

The above links point to projects on GitHub (but for GNU, not for IAR, but I you can port it to IAR easily).

I hope this helps,

Erich

0 Kudos
Reply

3,831 Views
gsmgbl
Contributor IV

Hi Erich,

Thanks for your info and guideline again and sorry that took me sometimes to get back on this task.

I have been going through a lot of different attempts, like using the patch above with my V8.2.3 or V9.0.0, but I finally stick with my V8.2.3 because there were a few different errors with my IAR Workbench. In the other post, I found the V9.0.0 is not compatible with old IAR version.

Anyway, FYI, I am quite new to FreeRTOS and I am still getting familiar with this, many thanks to your posts and example. All I want to do is running a few of my tasks by enabled the configUSE_TICKLESS_IDLE mode, this save me the power down to a few mA. Then I will have a physical switch to turn OFF my device except my MCU, by then I would like to put the MCU to deep sleep mode, then I enabled my configSYSTICK_USE_LOW_POWER_TIMER but none of my task is running once I enabled this feature.

I also tried to enter directly to several deep sleep mode directly by using the NXP SMC library functions, but my device is either keep on reset itself , or couldn't wakeup after enter into the deep sleep mode.

In addition, I have already disabled my watchdog COP function, plus I tried to disable the tickles idle mode as well, the symptoms are still the same.

I am quite confusing with the low power and deep sleep approach, plus hardly find any information explain this clearly, plus a lot of different variation such as the MCU, FreeRTOS version and IDE. Is there any recommendation? Please kindly advise. Thank you very much and appreciate if there is any project example to follow or understand better.

Regards,

Gilbert

0 Kudos
Reply

3,831 Views
BlackNight
NXP Employee
NXP Employee

Hi Gilbert,

I recommend that you create and start with a very small example project where you enter the low power mode and wakup up again. Then move this technique/important code steps into the FreeRTOS IDLE task handling.

Tickless Idle mode works out of the box with the McuOnEclipse FreeRTOS port. But I have not used IAR except for some minor small trials because it is not freely available. And low power modes are by nature deeply depending on the MCU used, so you have to spend at least some amount of time reading the reference manual.

Erich

0 Kudos
Reply

3,831 Views
gsmgbl
Contributor IV

Hi Erich,

Thanks for your quick response.

In fact, I started with the demo project from NXP, which the "power mode switch" project to begins with.

I run this project on my development board, the FRDM-KL27Z, and I found that the STOP mode is not running correct because the current draw even high then the VLPW mode. Anyway, I wakeup the MCU both by physical switch and timer correctly. Unfortunately, this project is not running based on FreeRTOS, in addition, the rtos example provides only the tickles idle mode example. Any additional information would be helpful at this point. Please advise. Thanks.

Regards,

Gilbert

0 Kudos
Reply

3,831 Views
martis
Contributor II

Thanks David, glad to finally get this confirmed :smileyhappy:

0 Kudos
Reply

3,831 Views
martis
Contributor II

I still need the fixed port.c.

Could you please provide this soon?

3,831 Views
BlackNight
NXP Employee
NXP Employee

I have a project for the FRDM-KL27Z with KDS, Kinetis SDK V2.0 and FreeRTOS with tickless idle mode and low power timer on GitHub here: mcuoneclipse/Examples/KDS/FRDM-KL27Z/FRDM-KL27Z_McuOnEclipseLib at master · ErichStyger/mcuoneclipse... 

You find the FreeRTOS (I'm using the latest V9.0.0 with support for static allocation and trace) in the root of that project. The port is for many Cortex, so you can use it e.g. for M0+, M4(F) and as well for M7, although I have used the low power timer only with Kinetis-L. Unlike the port in the SDK, I'm using either Systick OR LPTMR and not mixing them (which does not make sense in my view).

I hope this helps,

Erich

PS: That project is using Processor Expert in the background (I have found a way to use it with the SDK V2.0) with include header files for configuration (see McuOnEclipse Components: 12-Dec-2016 Release | MCU on Eclipse ): If you don't want/need a graphical user interface to configure FreeRTOS (and the other components), simply remove that .pe file in the project root.

3,831 Views
gsmgbl
Contributor IV

Hi Erich,

I am using IAR Workbench for my development unfortunately, I took a look at your project and looks quite different from my environment. So do you have any similar project under IAR? or can you give me some hints or directions to convert the project? cos this is my first project. Thanks a lot and greatly appreciate your help!!

Regards,

Gilbert

0 Kudos
Reply

3,831 Views
BlackNight
NXP Employee
NXP Employee

Yes, this is an Eclipse project, not an IAR project. But the FreeRTOS port supports many different compilers. Have a look at mcuoneclipse/FRTOS1config.h at master · ErichStyger/mcuoneclipse · GitHub and the configCOMPILER macro: you can set this to configCOMPILER_ARM_IAR and then the FreeRTOS is configured to use IAR compiler.

I hope this helps,

Erich

0 Kudos
Reply

3,831 Views
gsmgbl
Contributor IV

Hi Erich,

Thanks for your info and tips.

Greatly appreciate!

Regards,

Gilbert

0 Kudos
Reply

3,831 Views
soledad
NXP Employee
NXP Employee

Hi martis,

Our development team reproduced and fixed the issue. Thank you for your feedback.  Please check the comments below:

"Issue was reproduced and fixed. I have used configLPTMR_CLOCK_HZ instead configLPTMR_RATE_HZ. Macro configLPTMR_RATE_HZ defined as (configCPU_CLOCK_HZ) was wrong. LPTMR is not driven by CPU clock (120MHz) but by LPO (1kHz). New macro configLPTMR_CLOCK_HZ is defined according to real LPTMR clock frequency 1kHz.

There is issue with configLPTMR_CLOCK_HZ definition in FreeRTOSConfig.h. LPTMR is not initialized in FreeRTOS but in application, but LPTMR is used in freertos source code. That is also reason why we need to define LPTMR clock frequency somewhere (currently in FreeRTOSConfig.h). This is pointing out to problem with lptmr tickless implementation. LPTMR tickless should be implemented as part of application, not as part of FreeRTOS."

Have a great day,
Sol

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

0 Kudos
Reply

3,831 Views
gsmgbl
Contributor IV

Hi Sol,

I have similar situation with KL27 and i am using freertos v8.2.3, I found no definition about the LPTMR for both clock or rate macros. Would it be possible to post a example project (fixed freertos_tickless project), then we can see more clearly how it works? as well as the fixed port.c file is a great help.

Thank you and greatly appreciate this!!

Regards,

Gilbert

0 Kudos
Reply

3,831 Views
martis
Contributor II

Hello Sol,

Thanks for finally getting some feedback on this.

It is not clear to me in this written explanation exactly what changes the development team has done in the "port.c" file. Could you please provide the fixed "port.c"?

I am also not sure what is ment with "There is issue with configLPTMR_CLOCK_HZ definition in FreeRTOSConfig.h. LPTMR is not initialized in FreeRTOS but in application, but LPTMR is used in freertos source code".

Yes, configLPTMR_CLOCK_HZ must be added to FreeRTOSConfig.h and the LPTMR must be initialized by the application, but so does configCPU_CLOCK_HZ and the system clock. FreeRTOS does depend upon the application setting some parameters and configuring this correctly according to this, but I don't think this is a problem.

It would be really great to get a quick reply with the fixed "port.c",  because it has been more than 1,5 months to get an answer here, and I would like to be able to continue my development.

Thanks!

0 Kudos
Reply

3,831 Views
soledad
NXP Employee
NXP Employee

Hi,

Developers are preparing the patch. I'll let you know as soon as they have it ready.

Regards

Sol

0 Kudos
Reply

3,831 Views
gsmgbl
Contributor IV

Hi Sol,

I re-generated the example project from the MCUExpress due to the new 2.1 SDK and FreeRTOS V9.0.0. I found that the configLPTMR_CLOCK_HZ are still using the configCPU_CLOCK_HZ, which mentioned it is wrong previously. So is the patch for the FreeRTOS V8.2.3 or V9.0.0 or both? Please advise. Thank you.

Regards,

Gilbert

0 Kudos
Reply

3,831 Views
martis
Contributor II

Any news on this?

0 Kudos
Reply

3,831 Views
martis
Contributor II

Glad to see that you are looking into it.

Looking forward to hearing the conclusion!

0 Kudos
Reply

3,831 Views
soledad
NXP Employee
NXP Employee

Hello,

You are right, we already  were able to reproduced the problem, and we need to escalate  to our development team, once we have an update from them I will contact you asap


Have a great day,
Sol

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

0 Kudos
Reply