philpem wrote on Tuesday, November 22, 2016:
I should also clarify: the specific case of this going wrong is that we were advised against using FreeRTOS Software Timers as it would require an additional Third Party Review to be done on that part of FreeRTOS, and we already had “timeAfter” reviewed.
This was suggested and implemented:
- A global variable is set to xTaskGetTickCount() + 5 minutes when event “A” occurs
- It’s reset to five minutes when further "event A"s occur
- It stops waiting completely (set to zero) when a different type of event (“B”) occurs
- Other things can poll to see if the five minutes has elapsed – that is to say, event “A” has elapsed, and five minutes have elapsed without either an event “A” resetting the counter to 5 minutes again, or an event “B” to say “done waiting, too late”.
In the review, this came up:
timeAfter() will return an incorrect return value when xTaskGetTickCount reaches half of its range, but event “A” hasn’t occurred yet (the global timer is still zero).
If you look at it in terms of 16-bit ticks:
xTaskGetTickCount = 0x7FFF
GlobalTimer = 0
timeAfter = (GlobalTimer - 0x7FFF) = 0x8001 = TRUE
timeAfter = (GlobalTimer - 0x8000) = 0x8000 = TRUE
timeAfter = (GlobalTimer - 0x8001) = 0x7FFF = FALSE
timeAfter = (GlobalTimer - 0x8002) = 0x7FFE = FALSE
The same holds if this is extended to 32-bit ticks.