Implementing tickless idle on Cortex M4.

jpt106 wrote on Monday, September 22, 2014:

Sorry I was not clear. Yes the fix posted made the problem happen less often but I was to reproduce the issue still. I am using tickless configuration in my system. There is a task that runs periodically every 8 ticks (62.5 milliseconds). There is CLI interface through a UART. From the CLI I run different commands that cause other tasks to run processing the request for the CLI command. For testing, I have a script that continuously runs different CLI commands. This causes the other tasks to randomly run and generate other interrupts beside the AST interrupt.

Without your fix posted, running the test script my system fails the assert “configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime )” within a minute. With the posted fix, it takes about 10 minutes running the test script.

Originally I found when the system was failing it was calculating a negative alarm value and programming that negative value into the alarm for the AST. The code I posted tried to prevent the negative alarm value issue. After further investigation, I found the root cause of the issue. The AST clear counter on alarm does not clear the counter on the same AST clock cycle as when the counter equals the alarm. The counter gets reset to one on the next clock cycle when the counter exceeds the alarm value. This caused a race condition where during the time of single AST clock cycle (61 microseconds) the counter equals the alarm value. I saw during debugging in the code “if( ulTickFlag != pdFALSE)”
where ast_read_counter_value( AST ) returned the same value as the alarm value. This caused a negative value to be calculated for ulAlarmValue.

The newly posted code fixes the root cause directly by detected when the race condition happens and taking action.

1 Like