FreeRTOS 启动任务调度器vTaskStartScheduler()函数注释

本文详细解释了vTaskStartScheduler函数在FreeRTOS中的作用,包括创建空闲任务(静态或动态分配),初始化定时器,处理中断,设置任务运行时间和系统时钟。着重展示了任务调度器启动前的准备工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值