xTaskCreate .

创建新的任务并添加到任务队列中,准备运行

 

Parameters:
pvTaskCode 指向任务的入口函数. 任务必须执行并且永不返回 (即:无限循环).
pcName 描述任务的名字。主要便于调试。最大长度由configMAX_TASK_NAME_LEN.定义
usStackDepth 指定任务堆栈的大小 ,堆栈能保护变量的数目- 不是字节数. 例如,如果堆栈为16位宽度,usStackDepth定义为 100, 200 字节,这些将分配给堆栈。堆栈嵌套深度(堆栈宽度)不能超多最大值——包含了size_t类型的变量
pvParameters 指针用于作为一个参数传向创建的任务
uxPriority 任务运行时的优先级( 0 : 优先级最低)
pvCreatedTask 用于传递一个处理——引用创建的任务
返回:
pdPASS 是如果任务成功创建并且添加到就绪列中,另外错误代码在projdefs. H文件定义

使用例子:

 

 

 

 

 
 
// 使用句柄来删除任务 vTaskDelete( xHandle ); }

 
 
// 创建任务,存储处理。注意传递的参数为ucParameterToPass //它在任务中不能始终存在, 所以定义为静态变量. 如果它是动态堆栈的变量,可能存在 // 没有那么长,或者至少随着时间毁灭, // 新的时间, 尝试存储它 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );

 
 
// 函数来创建一个任务 void vOtherFunction( void ) { static unsigned char ucParameterToPass; xTaskHandle xHandle;

 
 
// 创建任务 void vTaskCode( void * pvParameters ) { for( ;; ) { // 任务代码 } }

 
 
portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask );
 
[:以下为FreeRTOS_v4 .5 .0在at91sam7s64处理器上的task任务创建函数 (gliethtp ) ] signed portBASE_TYPE xTaskCreate ( pdTASK_CODE pvTaskCode , const signed portCHAR * const pcName , unsigned portSHORT usStackDepth , void *pvParameters , unsigned portBASE_TYPE uxPriority , xTaskHandle *pxCreatedTask ) { signed portBASE_TYPE xReturn ; tskTCB * pxNewTCB ; # if ( configUSE_TRACE_FACILITY = = 1 ) //uxTaskNumber为任务id号,一般用来调试,每个任务会唯一对应一个处于[0,0xffffffff]范围之间的数值 //因为优先级并不能唯一表示一个task,所以为了能够唯一标识一个task, //可以使用TCB或者TCB->uxTCBNumber      static unsigned portBASE_TYPE uxTaskNumber = 0 ; # endif //动态申请tskTCB存储区和usStackDepth堆栈存储区 //FreeRTOS提供3中动态内存分配机制,具体可参见《浅析FreeRTOS_v4.5.0内存分配与回收及其改进方案》 //文章地址:http://blog.chinaunix.net/u1/38994/showart_392500.html     pxNewTCB = prvAllocateTCBAndStack ( usStackDepth ) ;      if ( pxNewTCB ! = NULL )      {                 portSTACK_TYPE *pxTopOfStack ; //对task的 //pxTCB->pcTaskName //pxTCB->uxBasePriority //pxTCB->xGenericListItem //pxTCB->xEventListItem进行初始化, //将xEventListItem->xItemValue值置为configMAX_PRIORITIES - ( portTickType ) uxPriority //所以xEventListItem->xItemValue的最小值为1.(注:非0[gliethttp])         prvInitialiseTCBVariables ( pxNewTCB , pcName , uxPriority ) ;          # if portSTACK_GROWTH < 0          {              //堆栈是向下生长的,at91sam7s64就是以这种方式来生长堆栈             pxTopOfStack = pxNewTCB - >pxStack + ( usStackDepth - 1 ) ;          }          # else          {             pxTopOfStack = pxNewTCB - >pxStack ;              }          # endif          //初始化该task对应的堆栈空间          //具体可参见《浅析FreeRTOS_v4.5.0的任务切换原理和栈结构》          //文章地址:http://blog.chinaunix.net/u1/38994/showart_391270.html          //需要注意的是pvTaskCode应该+4,即lr-4,这样来模拟IRQ,          //pxNewTCB->pxTopOfStack存放了当前task使用到的sp栈顶值         pxNewTCB - >pxTopOfStack = pxPortInitialiseStack ( pxTopOfStack , pvTaskCode , pvParameters ) ;         portENTER_CRITICAL ( ) ; //原子操作          {             uxCurrentNumberOfTasks + + ;              if ( uxCurrentNumberOfTasks = = ( unsigned portBASE_TYPE ) 1 )              {                  //这是FreeRTOS系统创建的第1个任务,那么初始化FreeRTOS的一些基础量:                  //1.pxReadyTasksLists队列链表                  //2.xDelayedTaskList1队列链表                  //3.xDelayedTaskList2队列链表                  //4.xPendingReadyList队列链表                  //5.xTasksWaitingTermination队列链表                  //6.xSuspendedTaskList队列链表                  //7.pxDelayedTaskList = &xDelayedTaskList1;暂时的前台时间队列链表                  //8.pxOverflowDelayedTaskList = &xDelayedTaskList2;暂时的后台时间队列链表                 pxCurrentTCB = pxNewTCB ;                 prvInitialiseTaskLists ( ) ;              }              else              {                      if ( xSchedulerRunning = = pdFALSE )                  { //当前FreeRTOS还没有启动调度器,                  //那么当前pxCurrentTCB需要是指向最高优先级任务                      if ( pxCurrentTCB - >uxPriority < = uxPriority )                      {                          //比它高,所以pxNewTCB应该做当前任务                         pxCurrentTCB = pxNewTCB ;                      }                  }              }                              if ( pxNewTCB - >uxPriority > uxTopUsedPriority )              {                 uxTopUsedPriority = pxNewTCB - >uxPriority ; //在vTaskList()中使用到了              }              # if ( configUSE_TRACE_FACILITY = = 1 )              {                 pxNewTCB - >uxTCBNumber = uxTaskNumber ; //存储新创建的task的id号                 uxTaskNumber + + ; //id号+1,以便供下一个创建的task使用              }              # endif //#define prvAddTaskToReadyQueue( pxTCB )                                       \ //{                                                                             \ //    if( pxTCB->uxPriority > uxTopReadyPriority )                              \ //    {                                                                         \ //        uxTopReadyPriority = pxTCB->uxPriority;                               \ //    }                                                                         \ //    vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) );\ //} //把新创建的task添加到就绪运行队列链表中, //本task会被插入到pxReadyTasksLists中自己优先级所对应的数组下 //这时本task对应优先级的数组可能已经有同优先级的任务在上边了, //没关系,只需要将本task添加到轮转调度的最后位置即可,对于FreeRTOS轮转调度的理解, //可以参见《浅析FreeRTOS_v4.5.0的任务切换原理和栈结构》 //文章地址:http://blog.chinaunix.net/u1/38994/showart_391270.html             prvAddTaskToReadyQueue ( pxNewTCB ) ;             xReturn = pdPASS ; //标示成功创建          }         portEXIT_CRITICAL ( ) ; //原子操作结束      }      else      {         xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ;      }      if ( xReturn = = pdPASS )      {          if ( ( void * ) pxCreatedTask ! = NULL )          {              *pxCreatedTask = ( xTaskHandle ) pxNewTCB ; //把创建的TCB,传递到外界参数pxCreatedTask中          }          if ( xSchedulerRunning ! = pdFALSE )          { //os已经正常启动              if ( pxCurrentTCB - >uxPriority < uxPriority )              {                  //新创建的task-B的优先级比调用创建函数xTaskCreate()的task-A的优先级高                  //那么task-B立即抢占task-A,取得cpu的使用权                  //可以参见《浅析FreeRTOS_v4.5.0的任务切换原理和栈结构》                  //文章地址:http://blog.chinaunix.net/u1/38994/showart_391270.html                 taskYIELD ( ) ;              }          }      }      return xReturn ; //返回xTaskCreate()函数的执行结果 }
 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值