对vTaskStartScheduler()函数添加中文注释,放在CSDN是为保存。
void vTaskStartScheduler( void )
{
BaseType_t xReturn;
/* 添加优先级最低的空闲任务 */
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
{
StaticTask_t * pxIdleTaskTCBBuffer = NULL;
StackType_t * pxIdleTaskStackBuffer = NULL;
uint32_t ulIdleTaskStackSize;
/* The Idle task is created using user provided RAM - obtain the
* address of the RAM then create the idle task. */
vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize );
xIdleTaskHandle = xTaskCreateStatic( prvIdleTask,
configIDLE_TASK_NAME,
ulIdleTaskStackSize,
( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */
pxIdleTaskStackBuffer,
pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
if( xIdleTaskHandle != NULL )
{
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
}
}
#else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
{
/* 使用动态分配内存创建空闲任务。 */
xReturn = xTaskCreate( prvIdleTask,
configIDLE_TASK_NAME,
configMINIMAL_STACK_SIZE,
( void * ) NULL,
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */
&xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
}
#endif /* configSUPPORT_STATIC_ALLOCATION */
#if ( configUSE_TIMERS == 1 )
{
if( xReturn == pdPASS )
{
xReturn = xTimerCreateTimerTask();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* configUSE_TIMERS */
if( xReturn == pdPASS )
{
/* 只有在用户可定义的宏FREERTOS_TASKS_C_ADDITIONS_INIT()被定义时,
* 才应该调用freertos_tasks_c_additions_init(),因为该函数只调用了该宏。 */
#ifdef FREERTOS_TASKS_C_ADDITIONS_INIT
{
freertos_tasks_c_additions_init();
}
#endif
/* 在调用xPortStartScheduler()之前,中断被关闭,
* 以确保在开启任务任务调度器期间或之前不会产生SysTick 中断。
* 创建的任务的堆栈包含一个状态字,其中中断被打开,
* 因此当第一个任务开始运行时,中断会自动重新启用。 */
portDISABLE_INTERRUPTS(); /* 禁用中断函数 */
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
{
/* Switch C-Runtime's TLS Block to point to the TLS
* block specific to the task that will run first. */
configSET_TLS_BLOCK( pxCurrentTCB->xTLSBlock );
}
#endif
/* 初始化一些全局变量
* xNextTaskUnblockTime: 下一个距离取消任务阻塞的时间,初始化为最大值
* xSchedulerRunning: 任务调度器运行标志,设为已运行
* xTickCount: 系统使用节拍计数器,宏 configINITIAL_TICK_COUNT 默认为 0 */
xNextTaskUnblockTime = portMAX_DELAY;
xSchedulerRunning = pdTRUE;
xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT;
/* 为任务运行时间统计功能初始化功能时基定时器
* 是否启用该功能,可在 FreeRTOSConfig.h 文件中进行配置*/
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();
traceTASK_SWITCHED_IN();
/* 设置用于系统时钟节拍的硬件定时器(SysTick)会在这个函数中进入第一个任务,
* 并开始任务调度任务调度开启后,便不会再返回 */
xPortStartScheduler();
/* 在大多数情况下,xPortStartScheduler()不会返回。
* 如果它返回pdTRUE,则没有足够的堆内存可用来创建Idle或Timer任务。
* 如果返回pdFALSE,则应用程序调用xTaskEndScheduler()。
* 大多数端口没有实现xTaskEndScheduler(),因为没有什么可返回的。 */
}
else
{
/* 只有在内核无法启动,因为没有足够的
* FreeRTOS 堆空间来创建空闲任务或定时器任务时,才会执行到这行代码 */
configASSERT( xReturn != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY );
}
/* Prevent compiler warnings if INCLUDE_xTaskGetIdleTaskHandle is set to 0,
* meaning xIdleTaskHandle is not used anywhere else. */
( void ) xIdleTaskHandle;
/* OpenOCD makes use of uxTopUsedPriority for thread debugging. Prevent uxTopUsedPriority
* from getting optimized out as it is no longer used by the kernel. */
( void ) uxTopUsedPriority;
}