cancel
Showing results for 
Search instead for 
Did you mean: 

CubeMX Feature Request - FreeRTOS alternate clock.

mattreed9
Associate III
Posted on May 12, 2016 at 23:32

In order to take full advantage of Tick-less Idle for Power-Saving I need to use an RTOS clock-source other than the SysTick.

I need to alter the system clock (FreeRTOS does not accommodate this), and to do STOP1 or STOP2 FreeRTOS can't be using the SysTick.

FreeRTOS has the flexibility to do this, but not only can I not implement this in CubeMX (which is OK, and understandable), CubeMX generates code I have to modify to make things work correctly.

Since I am using LPTIM1 as the clock source for FreeRTOS, I have allowed SysTick to drive HAL. But when I can't ''turn off'' SysTick for FreeRTOS and when I generate code CubeMX sticks osSystickHandler into the interrupt for SysTick.  osSystickHandler calls FreeRTOS's tick handler xPortSysTickHandler. None if these calls are structured in a way that I can remove them without altering code that is outside of the ''user code'' doman.

All I need is a flag I can set that says ''Implement Your Own FreeRTOS Ticks'' and then don't put the os SystickHandler call in.

Or - am I missing something? Maybe there already is a way to do this?

-Matt

#cube #cubemx #freertos
7 REPLIES 7
carmine
Associate II
Posted on May 13, 2016 at 12:29

Hi,

I've a question to you not related to the topic. Have you managed to use LPTIM1 timer in tickless mode reliably? I've conduct a lot of experiments, and I reached to the conclusion that the LPTIM1 is not that good if you need to reliably determine how many ticks passed during ''deeper'' sleep modes. I think that this related to the fact that reading the LPTIM1 counter register is not reliable, as ST also states in its datasheets? What is your experience about this?

Carmine

mattreed9
Associate III
Posted on May 13, 2016 at 15:04

Carmine, Thanks so much for your comment. I am having problems implementing LPTIM1 for tickless idle. And, the problems are with reading the current value. I have only spent a couple of days working on the problem and so far am only reliably using LPTIM1 as an alternate clock source.

You have probably saved me many hours of frustration!

I will be focusing on the read flaw you mentioned. 

What other time source can be used? Perhaps an external clock?

I have also considered using LPTIM1 as the clock source, but using RTC to time missed ticks while sleeping. The resolution will not be so good, but it is preferable to not being able to sleep at all. Also, if sleeping for long periods of time (as we will be) the ticks being off for less than 1 second is acceptable.

In our current designs (using an older version of FreeRTOS) we actually disable FreeRTOS while sleeping and ignore the tick count problems. This means we have to be very careful about using vTaskDelay and we don't use FreeRTOS timers at all.

-Matt

-Added later-

Carmine, according to the datasheet all that is needed is to do two reads of the LPTIM1 timer until the two reading match. Have you tried this?

Also, we could program the LPTIM1 to rollover at exactly 1 second and disable the rollover interrupt, then program the RTC to sleep for whole multiple's of seconds based on the expected sleep time and have the RTC wake us up. When the RTC wakes us the missed ticks would be the number of seconds elapsed from the RTC plus the fractions of a second as read from LPTIM1. SInce the RTC would be waking us on a whole multiple of seconds, the fractions of a second would remain, which would be available for a regular SLEEP (instead of a STOP).

- Just a thought -

mattreed9
Associate III
Posted on May 13, 2016 at 21:18

Carmine, you do realize that LPTIM1 is a count-up timer and SysTick is a count-down timer.  So the number of ticks elapsed for LPTIM1 is the counter value. (although LPTIM1 can be configured as a count-down timer it is not by default with the HAL calls).

-Matt

carmine
Associate II
Posted on May 13, 2016 at 22:24

Hi Matt,

really thanks for your feedback.

I've to admit that, when I did tests, I haven't realized that LPTIM1 is only upcounter. However, I had a lot of troubles reading the counter register performing the two consecutive reading, as suggested in the datasheet. Often the two reads didn't match. So I've decided to use another timer as usual for light sleep modes: in my case, it was ok to completely suspend tick generation in stop mode.

However, I want to try it again. I'll let you know what I get out.

carmine
Associate II
Posted on May 14, 2016 at 19:03

Sorry Matt, but yesterday I was too tired when I answered. 

Yes, LPTIM1 is only upcounter. This doesn't change nothing, because my implementation of vPortSetupTimerInterrupt() is quite the same to the one provided in the official FreeRTOS distribution, and it also relies on the fact that the STM32 timer used is configured as upconter. 

I've spent even this whole day trying to figure out the problem, and I reached again to the conclusion that reading the LPTIM counter, especially when the MCU enters deeper sleep modes, is completely unreliable. 

I'm curious to know if even other people reached to the same conclusion.

mattreed9
Associate III
Posted on May 16, 2016 at 22:14

Carmine, Thanks for your reply. I feel very fortunate to be able to speak with someone who is a little ahead of me on developing this feature.

Until today I had not tried enabling STOP mode, I was using only SLEEP mode.

So after reading your post I enabled the STOP mode code. I see what you mean about reading the counter value, the unit seemed to lock-up and when I broke the execution with the debugger I found it in the loop trying to read the counter. On a hunch I put a counter into the interrupt routine for LPTIM1 and found that after only a few seconds the counter had reached a value of over 2 million. This is why we can't read the counter, the interrupts are blocking access. But why it is interrupting so much?  I put a break-point in the interrupt and read out the register values for LPTIM1, ISR indicates a compare, but that is not enabled.

It makes no sense that is it continually being interrupted, that is the mystery.

Did you notice this? Did you find the reason for the constant interrupt?

In my experience a constant interrupt like this is caused by the interrupt flag not being cleared, so when the ISR is exited the same interrupt fires again.

I may add code to write to the ICR, just to see if that helps.

Thanks for your assistance, I appreciate it!

-Matt
mattreed9
Associate III
Posted on May 16, 2016 at 23:23

By modifying the ISR for LPTIM1 as follows:

---------------------------------------------------

void LPTIM1_IRQHandler(void)

{

  /* USER CODE BEGIN LPTIM1_IRQn 0 */

  last_isr = 65;

  /* USER CODE END LPTIM1_IRQn 0 */

  HAL_LPTIM_IRQHandler(&hlptim1);

  /* USER CODE BEGIN LPTIM1_IRQn 1 */

  hlptim1.Instance->ICR = 0x7f;

  /* USER CODE END LPTIM1_IRQn 1 */

}

------------------------------------------------------

It no longer goes into an infinite interrupt loop. But, we still get 1 interrupt as soon as we go to STOP mode (which defeats the whole purpose!). I'm looking through errata and data sheets to see why we get an interrupt, nothing so far.

Tomorrow I will be at an STM32F7 class, I will try to get some time with an FAE to ask about this.

-Matt