forked from epagris/FreeRTOS-Kernel
		
	This change prevents tickless idle mode potentially sleeping for an extra tick in the corer case that a tick interrupt occurred between the scheduler being suspended and the expected idle time being checked for a second time (within the idle task) - as described by the sequence below. Th change updates eTaskConfirmSleepModeStatus() to specifically check if a tick is pending, and if so, abort entering sleep mode.
+ The idle task decides to enter sleep mode on the following line. ``` if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) ``` + The scheduler is suspended, preventing any context switches. [Potentially a tick interrupt could occur here. That could happen if other tasks executing consumed a lot of time since the above code line executed. If a tick interrupt occurs here the interrupt will be entered but the interrupt will not do anything other than increment xPendedTicks.] + The expected idle time is checked again. No context switches can occur now so the code will execute until the scheduler is unsuspended. Assuming configEXPECTED_IDLE_TIME_BEFORE_SLEEP is set to a sensible value, a tick interrupt won't occur for some time. + portSUPPRESS_TICKS_AND_SLEEP() is called. + The default implementation of the tickless function calls eTaskConfirmSleep() - which prior to this change does not return eAbortSleep even though xPendedTicks is not 0, and after this change does return eAbortSleep.
This commit is contained in:
		
							parent
							
								
									499e55a03c
								
							
						
					
					
						commit
						e1b98f0b4b
					
				
							
								
								
									
										6
									
								
								tasks.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tasks.c
									
									
									
									
									
								
							@ -3526,6 +3526,12 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
 | 
			
		||||
			/* A yield was pended while the scheduler was suspended. */
 | 
			
		||||
			eReturn = eAbortSleep;
 | 
			
		||||
		}
 | 
			
		||||
		else if( xPendedTicks != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* A tick interrupt has already occurred but was held pending
 | 
			
		||||
			because the scheduler is suspended. */
 | 
			
		||||
			eReturn = eAbortSleep;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* If all the tasks are in the suspended list (which might mean they
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user