This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Why is the FreeRTOS function xTimerResetFromISR not working in tickless mode?


I modified the blinky_freertos example from SDK 12 slightly to perform the following:

I have one timer and one task. The task blinks a LED and then suspends. In the timer callback function (one second period) I resume the task to have a LED that blinks every second. I now want to synchronise my timer to the "1 pulse per second" output of GPS module. To achieve this, I create a interrupt routine that resets my timer and resumes my task (so if the timer is reset just before it would call its callback, my task is still resumed). I took care not to resume a task from the ISR with a priority higher than the task that was interrupted.

If I'm running this code with tickless mode off, everything behaves as I expect. I attached a scope screenshot that shows the blinking LED (blue) is nicely synchronized to the external interrupt (yellow). Now when I turn tickless mode on, the synchronization will fail. It looks like the end of the delay in the task is synchronized with with the interrupt, and not the start of the task. Is this a bug? If not, can anybody tell me what I'm doing wrong? Our application is battery powered so tickless mode is really a must have.

I attached my main.c, FreeRTOSConfig.h, makefile and two scope screencaps.



main.c updated





  • Hi Aryan,

    This is not likely. The interrupt is generated by a gps that has an accuracy of 30 ns, synchornized to atomic clocks in the gps sattelites. Furthermore, this would not explain why the tickless mode has an impact on the behaviour. I did some more research and I see the following: In tickless mode the LED is set exactly 50 ms before the interrupt arrives. This is exactly the delay I use before turning the LED off again. When I change this period to 80 ms, I observe that the LED is turned on exactly 80 ms before the interrupt occurs. With other words, the interrupt is synchronized with the end of the delay in the led_toggle_task_function. Furthermore, I added some timestamping and logging to the code to better understand what is going on. I use the functions xTaskGetTickCount and xTaskGetTickCountFromISR to get the timestamps from the different occasions.

  • The result is this:

         :INFO:tickCount Timer Callback: 274782.
     0> :INFO:tickCount LED on: 274782.
     0> :INFO:tickCount ISR: 274782.
     0> :INFO:tickCount LED off: 274863.
     0> :INFO:tickCount Timer Callback: 275807.
     0> :INFO:tickCount LED on: 275807.
     0> :INFO:tickCount ISR: 275807.
     0> :INFO:tickCount LED off: 275888.
     0> :INFO:tickCount Timer Callback: 276832.
     0> :INFO:tickCount LED on: 276832.
     0> :INFO:tickCount ISR: 276832.
     0> :INFO:tickCount LED off: 276913.

    Even though I see on my oscilloscope that the LED is turned on 80 ms before the interrupt arrives, they get the same tickCount. I cannot draw any other conclusion then that one of them is wrong.

  • Furthermore the first time the interrupt occurs after startup, the timer is reset correctly, but in the following seconds, it drifts slowly to the left on my scope until it stabilizes with the moment the LED is turned of synchronized to the interrupt.

    On explanation could be that when the interrupt occurs during the delay of the function, It incorrectly thinks the current time is the time the delay started (the time is not updated during the delay and also not during the interrupt!) The reset of the timer is simply a function that sets the callback time of the timer equal to the current time + the timer period. If the current time is not correct, the timer is not correctly reset. Could this be happening? (I'm definitely not an expert in this matter!)

  • This is btw exactly the behaviour reported in this thread And this bug was fixed in SDK 12 according to this thread:

    Are you sure the fix made it into the "release" of SDK 12?

  • It might be possible that there is a bug in writing to RTC value at the wakeup in tickless idle. This is driving me crazy, Why can't I see this here. Let me checkout a clean SDK and try your project one more time. Meanwhile, can you please check if you are seeing the same thing in KEIL?