浅析FreeRTOS源码:xTaskCreate函数

1、这个函数的作用

创建一个新的任务,使得FreeRTOS的调度器可以在这个任务就绪的时候给他CPU的使用权,让它运行。

2、分析代码

分析的内容直接写在代码注释中了

#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )// 打开了动态分配这个宏
    BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,					// 任务函数
                            const char * const pcName, 					// 任务的名字
                            const configSTACK_DEPTH_TYPE usStackDepth,	// 栈大小
                            void * const pvParameters,					// 参数列表
                            UBaseType_t uxPriority,						// 优先级
                            TaskHandle_t * const pxCreatedTask )		// 句柄
    {
        TCB_t * pxNewTCB;       // 新建任务控制块
        BaseType_t xReturn;     // 返回值

        /* 栈向下增长:先分配栈,再分配TCB,这样栈就不会长到TCB里。
         * 栈向上增长:先分配TCB,再分配栈。 */
        #if ( portSTACK_GROWTH > 0 )	// 栈向上增长的情况
        {
            // 与栈向下增长的情况差不多,因此此处省略
        }
        #else /* portSTACK_GROWTH */
        {
            StackType_t * pxStack;      // 定义栈变量

            /* 给栈变量分配内存空间 */
            pxStack = pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */

            if( pxStack != NULL )   // 分配成功
            {
                /* 给TCB分配内存空间 */
                pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */

                if( pxNewTCB != NULL )  // 分配成功
                {
                    memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) );// 清洗TCB内存空间

                    /* 分配好的栈地址保存到TCB */
                    pxNewTCB->pxStack = pxStack;
                }
                else                    // 分配失败
                {
                    /* 释放栈的内存空间 */
                    vPortFreeStack( pxStack );
                }
            }
            else                    // 分配失败
            {
                pxNewTCB = NULL;    // TCB无效
            }
        }
        #endif /* portSTACK_GROWTH */

        if( pxNewTCB != NULL )      // TCB 有效的情况
        {
            #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e9029 !e731 Macro has been consolidated for readability reasons. */
            {
                /* Tasks can be created statically or dynamically, so note this
                 * task was created dynamically in case it is later deleted. */
                pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB;
            }
            #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */

            // 初始化新任务
            prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );
            // 把新任务添加到就绪列表
            prvAddNewTaskToReadyList( pxNewTCB );
            xReturn = pdPASS;
        }
        else                        // TCB 无效的情况
        {
            xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;// 配置返回值(分配内存失败错误)
        }

        return xReturn;
    }

#endif /* configSUPPORT_DYNAMIC_ALLOCATION */

3、总结

这个函数的主要工作:
1、根据栈增方开辟内存空间
2、为TCB分配内存空间
3、初始化新任务(prvInitialiseNewTask函数,该函数的浅析见https://blog.csdn.net/wong_xian/article/details/140775770)
4、将新任务添加到就绪列表(prvAddNewTaskToReadyList函数)

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值