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

Tickless overrun issue using FreeRTOS, nRF52

Question about usage. I am using the nRF52, and ported product code that was running on the Alpha SDK11 to the release SDK11. I believe that what I will describe is a new issue, after the port, but I have not yet fully investigated the reverted build.

In the idle task (tasks.c), there is a section where the code decides that nothing is going on and it can perform a longer tickless sleep.

	#if ( configUSE_TICKLESS_IDLE != 0 )
	{
	TickType_t xExpectedIdleTime;

		/* It is not desirable to suspend then resume the scheduler on
		each iteration of the idle task.  Therefore, a preliminary
		test of the expected idle time is performed without the
		scheduler suspended.  The result here is not necessarily
		valid. */
		xExpectedIdleTime = prvGetExpectedIdleTime();

		if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
		{
			vTaskSuspendAll();
			{
				/* Now the scheduler is suspended, the expected idle
				time can be sampled again, and this time its value can
				be used. */
         	    /* 	configASSERT( xNextTaskUnblockTime >= xTickCount ); */
                if (xNextTaskUnblockTime < xTickCount )
                {
                    ++xSkipCount;
                }

				xExpectedIdleTime = prvGetExpectedIdleTime();

				if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
				{
					traceLOW_POWER_IDLE_BEGIN();
					portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
					traceLOW_POWER_IDLE_END();
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}
			}
			( void ) xTaskResumeAll();
		}

The only modification above is replacing the assert with a block that counts how often the condition happens, hitting the assert is less fun. The system is running on a 1ms tick rate.

The issue I am having is when I break at the ++xSkipCount, I am seeing that xExpectedIdleTime is > 0 (usually 12 to 50ms), but xTickCount is greater then xNextTaskUnblockTime by about 12 to 48. This is the spread I have observed, not definitive.

Following it thru, after the following call to prvGetExpectedIdleTime(), the next xExpectedIdleTime is a huge positive value as it is of UINT32 type (it should be -nn), which is always greater then the check, so the system schedules a sleep. The RTC trims the sleep time to maximum RTC duration and the system sleeps. The behavior after this is somewhat erratic, which prompted the investigation.

Has anyone observed this sort of behavior in a tickless RTOS project? It seems odd that the tick count can run so far ahead in the short execution space.

Related