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?

Hi,

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.

Thanks!

Jules

main.c updated

FreeRTOSConfig.h

tickless_off.png

tickless_on.png

blinky_freertos.rar

  • without tickless mode this looks like this:

         0> :INFO:ISR: tickCount = 14726, RTC = 14726.
     0> :INFO:LED off: tickCount = 14807, RTC = 14807.
     0> :INFO:Timer callback: tickCount = 15750, RTC = 15750.
     0> :INFO:LED on: tickCount = 15750, RTC = 15750.
     0> :INFO:ISR: tickCount = 15750, RTC = 15750.
     0> :INFO:LED off: tickCount = 15831, RTC = 15831.
     0> :INFO:Timer callback: tickCount = 16774, RTC = 16774.
     0> :INFO:LED on: tickCount = 16774, RTC = 16774.
     0> :INFO:ISR: tickCount = 16774, RTC = 16774.
     0> :INFO:LED off: tickCount = 16855, RTC = 16855.
     0> :INFO:Timer callback: tickCount = 17798, RTC = 17798.
     0> :INFO:LED on: tickCount = 17798, RTC = 17798.
     0> :INFO:ISR: tickCount = 17798, RTC = 17798.
     0> :INFO:LED off: tickCount = 17879, RTC = 17879.
     0> :INFO:Timer callback: tickCount = 18822, RTC = 18822.
     0> :INFO:LED on: tickCount = 18822, RTC = 18822.
     0> :INFO:ISR: tickCount = 18822, RTC = 18822.
     0> :INFO:LED off: tickCount = 18903, RTC = 18903.
     0> :INFO:Timer callback: tickCount = 19846, RTC = 19846.
     0> :INFO:LED on: tickCount = 19846, RTC = 19846.
     0> :INFO:ISR: tickCount = 19846, RTC = 19846.
     0> :INFO:LED off: tickCount = 19927, RTC = 19927.
    
  • So in tickless mode, both the led_toggle_task and the timer callback have a tickCount that is around 80 ticks ahead of the RTC. I think this is incorrect behaviour.

    Furthermore I'm suprised by the power consumption with tickless mode disabled. I would expect it only to be slightly larger than using tickless mode due to the periodic ISR caused by the ticks. My multimeter however shows 7.54 mA continuous current draw with tickless mode disabled. Is this normal?

  • Hi,

    I found the bug, but sorry i am in hurry and i will update you later. The bug is in RTC tick handler. it have a corner case where it increments the rtos counter, so the rtos counter is moving ahead of RTC. More info tomorrow and i will give you a workaround.

  • Hi Jules,

    I fixed the bug that was causing the tick difference. but that apparently did not fix the issue of timerreset not functioning in tickless mode. Sorry for pre mature celebrations.

    Anyhow you will like to add this fix to your code with this diff

    diff --git a/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c b/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c
    index d89381d..868052d 100644
    --- a/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c
    +++ b/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c
    @@ -266,6 +266,12 @@ void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
             }
             configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
             nrf_rtc_int_disable(portNRF_RTC_REG, NRF_RTC_INT_COMPARE0_MASK);
    +
    +        /* If we do not clear this pending bit then interrupt trigger caused by compare0 (compare0 is only used in tickless mode)
    +         * pendbit will be confused as TICK in xPortSysTickHandler
    +         */
    +        NVIC_ClearPendingIRQ(portNRF_RTC_IRQn);
    +
             NVIC_EnableIRQ(portNRF_RTC_IRQn);
    
             /* Correct the system ticks */
    

    This will fix the tick difference issue you are seeing

Related