freeRtos调度函数代码解读

读了一下下freeRTOS的代码,结合代码过一下freeRTOS调度器是怎么工作的。

vTaskStartScheduler

创建完用户的各种任务之后,调用函数vTaskStartScheduler便进入了任务调度,任务地阿杜这个函数做了三件事。

  1. 创建 idle 任务 , 以下便是这部分代码

可以看出idle task的任务优先级被设置为portPRIVILEGE_BIT, 而portPRIVILEGE_BIT被定义为0x00,也就是最低优先级(freeRTOS中数字越大优先级越高)。换句话说,idle task的回调函数只有在系统“无事可做”的时候会被调用。

// The Idle task is created using user provided RAM
vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize );
// Create the idle task
xIdleTaskHandle = xTaskCreateStatic(	prvIdleTask,
							configIDLE_TASK_NAME,
							ulIdleTaskStackSize,
							( void * ) NULL, 
							portPRIVILEGE_BIT, 
							pxIdleTaskStackBuffer,
							pxIdleTaskTCBBuffer );
  1. 创建 timer task
		if( xReturn == pdPASS )
		{
			xReturn = xTimerCreateTimerTask();
		}
  1. 启动timer task 和 最高优先级task ,即调用xPortStartScheduler
if( xPortStartScheduler() != pdFALSE )

然后进入xPortStartScheduler,这个函数并不在freeRTOS的三大源码文件中,而是属于port的一部分,以下代码来自MSVC-MingW的实现(此代码可运行于windows上)。

  • 启动 tick 中断

    pvHandle = CreateThread( NULL, 0, prvSimulatedPeripheralTimer, NULL, CREATE_SUSPENDED, NULL );
    	if( pvHandle != NULL )
    	{
    		SetThreadPriority( pvHandle, portSIMULATED_TIMER_THREAD_PRIORITY );
    		SetThreadPriorityBoost( pvHandle, TRUE );
    		SetThreadAffinityMask( pvHandle, 0x01 );
    		ResumeThread( pvHandle );
    	}
    
  • 启动最高优先级任务

ResumeThread( pxThreadState->pvThread );

  • 调用函数ProcessSimulatedInterrupts

至此在此层函数范围内程序不在往下执行,即程序进入函数·ProcessSimulatedInterrupts便不再出来了,ProcessSimulatedInterrupts的主题是一个死循环,完成任务的调度,如以下代码。

static void prvProcessSimulatedInterrupts( void )
{
...
	for(;;)
	{
...
		for( i = 0; i < portMAX_INTERRUPTS; i++ )
		{
        ...
					if( ulIsrHandler[ i ]() != pdFALSE )
...
		}

		if( ulSwitchRequired != pdFALSE )
		{
			void *pvOldCurrentTCB;

			pvOldCurrentTCB = pxCurrentTCB;

			vTaskSwitchContext();

			/* If the task selected to enter the running state is not the task
			that is already in the running state. */
			if( pvOldCurrentTCB != pxCurrentTCB )
			{
				pxThreadState = ( ThreadState_t *) *( ( size_t * ) pvOldCurrentTCB );
				SuspendThread( pxThreadState->pvThread );

				xContext.ContextFlags = CONTEXT_INTEGER;
				( void ) GetThreadContext( pxThreadState->pvThread, &xContext );

				pxThreadState = ( ThreadState_t * ) ( *( size_t *) pxCurrentTCB );

				ResumeThread( pxThreadState->pvThread );
			}
		}

		pxThreadState = ( ThreadState_t * ) ( *( size_t *) pxCurrentTCB );
		SetEvent( pxThreadState->pvYieldEvent );
		ReleaseMutex( pvInterruptEventMutex );
	}
}

你可能感兴趣的:(RTOS)