Freertos代码之任务创建

流程:

    osThreadId_t wirelessTransTaskHandle;

    const osThreadAttr_t wirelessTransTaskAttri =
    {
        .name = "wirelessTransTask",
        .priority = (osPriority_t) osPriorityNormal6,
        .stack_size = 1024*64
    };

    wirelessTransTaskHandle = osThreadNew(wirelessTransTask, NULL, &wirelessTransTaskAttri);

// cmsis_rtos_v2/cmsis_os2.c

osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
  char empty;
  const char *name;
  uint32_t stack;
  TaskHandle_t hTask;
  UBaseType_t prio;
  int32_t mem;

  hTask = NULL;

  if (!IS_IRQ() && (func != NULL)) {
    stack = configMINIMAL_STACK_SIZE;        // 配置的最小栈
    prio  = (UBaseType_t)osPriorityNormal;    // 先分配一个优先级

    empty = '\0';
    name  = ∅        // 初始化指针
    mem   = -1;

    if (attr != NULL) {
      if (attr->name != NULL) {
        name = attr->name;            // 新建任务名
      }
      if (attr->priority != osPriorityNone) {
        prio = (UBaseType_t)attr->priority;        // 新建任务优先级
      }

        // 优先级检查,不能小于最小优先级,不能高于最大优先级, 及 joinable mode 检查
      if ((prio < osPriorityIdle) || (prio > osPriorityISR) || ((attr->attr_bits & osThreadJoinable) == osThreadJoinable)) {
        return (NULL);
      }

      if (attr->stack_size > 0U) {
        /* In FreeRTOS stack is not in bytes, but in sizeof(StackType_t) which is 4 on ARM ports.       */
        /* Stack size should be therefore 4 byte aligned in order to avoid division caused side effects */
        stack = attr->stack_size / sizeof(StackType_t); // 堆栈大小应为4字节对齐
      }

      if ((attr->cb_mem    != NULL) && (attr->cb_size    >= sizeof(StaticTask_t)) &&
          (attr->stack_mem != NULL) && (attr->stack_size >  0U)) {
        mem = 1;    // 没有对这些变量初始化,即使用静态内存分配
      }
      else {
        if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) && (attr->stack_mem == NULL)) {
          mem = 0;    // 采用动态内存分配
        }
      }
    }
    else {
      mem = 0;
    }
    
    // 任务创建
    if (mem == 1) {        // 静态内存分配
      hTask = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t  *)attr->stack_mem,
                                                                                    (StaticTask_t *)attr->cb_mem);
    }
    else {
      if (mem == 0) {    // 动态内存分配
        if (xTaskCreate ((TaskFunction_t)func, name, (uint16_t)stack, argument, prio, &hTask) != pdPASS) {
          hTask = NULL;
        }
      }
    }
  }

  return ((osThreadId_t)hTask);
}

// task.c

  此函数中宏定义 portSTACK_GROWTH 是为了区分堆栈的生成方式,它可以分为递增堆栈(Ascending Stack)和递减堆栈(Decending Stack)。当堆栈由低地址向高地址生成时,称为递增堆栈;当堆栈由高地址向低地址生成时,称为递减堆栈。

这样就有4种类型的堆栈工作方式:

        1.满递增堆栈: 堆栈指针指向最后压入的数据,且由低地址向高地址生成.

        2.满递减堆栈: 堆栈指针指向最后压入的数据,且由高地址向低地址生成.

        3.空递增堆栈: 堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成.

        4.空递减堆栈: 堆栈指针指向下一个将要放放数据的空位轩,且由高地址向低地址生成.

    BaseType_t xTaskCreate(    TaskFunction_t pxTaskCode,
                            const char * const pcName,        /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
                            const configSTACK_DEPTH_TYPE usStackDepth,
                            void * const pvParameters,
                            UBaseType_t uxPriority,
                            TaskHandle_t * const pxCreatedTask )
    {
    TCB_t *pxNewTCB;
    BaseType_t xReturn;

        /* If the stack grows down then allocate the stack then the TCB so the stack
        does not grow into the TCB.  Likewise if the stack grows up then allocate
        the TCB then the stack. */
        #if( portSTACK_GROWTH > 0 )
        {
            /* Allocate space for the TCB.  Where the memory comes from depends on
            the implementation of the port malloc function and whether or not static
            allocation is being used. */
            pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );

            if( pxNewTCB != NULL )
            {
                /* Allocate space for the stack used by the task being created.
                The base of the stack memory stored in the TCB so the task can
                be deleted later if required. */
                pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */

                if( pxNewTCB->pxStack == NULL )
                {
                    /* Could not allocate the stack.  Delete the allocated TCB. */
                    vPortFree( pxNewTCB );
                    pxNewTCB = NULL;
                }
            }
        }
        #else /* portSTACK_GROWTH */
        {
        StackType_t *pxStack;

            /* Allocate space for the stack used by the task being created. */
            pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */

            if( pxStack != NULL )
            {
                /* Allocate space for the TCB. */
                pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e961 MISRA exception as the casts are only redundant for some paths. */

                if( pxNewTCB != NULL )
                {
                    /* Store the stack location in the TCB. */
                    pxNewTCB->pxStack = pxStack;
                }
                else
                {
                    /* The stack cannot be used as the TCB was not created.  Free
                    it again. */
                    vPortFree( pxStack );
                }
            }
            else
            {
                pxNewTCB = NULL;
            }
        }
        #endif /* portSTACK_GROWTH */

        if( pxNewTCB != NULL )
        {
            #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !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 /* configSUPPORT_STATIC_ALLOCATION */

            prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );        // 初始化新任务
            prvAddNewTaskToReadyList( pxNewTCB );  // 将新任务加入优先安排就绪任务列表
            xReturn = pdPASS;
        }
        else
        {
            xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
        }

        return xReturn;
    }

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值