任务块结构
typedef struct tskTaskControlBlock
{
volatile StackType_t * pxTopOfStack;//栈顶指针
ListItem_t xStateListItem;//状态列表项
ListItem_t xEventListItem;//事件列表项
UBaseType_t uxPriority;//任务优先级
StackType_t * pxStack;//指向起始栈
char pcTaskName[ configMAX_TASK_NAME_LEN ];//任务名称
......
} tskTCB;
//任务就绪列表
List_t pxReadyTasksLists[ configMAX_PRIORITIES ];
//延时列表1
List_t xDelayedTaskList1;
//延时列表2,使用2个列表,1个正常延时,另一个当延时超过当前的tick计数值使用
List_t xDelayedTaskList2;
//指向当前延时任务列表
List_t * volatile pxDelayedTaskList;
//指向当前延时溢出任务列表
List_t * volatile pxOverflowDelayedTaskList;
//挂起任务列表
List_t xPendingReadyList;
1、动态创建任务函数xTaskCreate
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const configSTACK_DEPTH_TYPE uxStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask )
{
TCB_t * pxNewTCB;
BaseType_t xReturn;
//创建新任务
pxNewTCB = prvCreateTask( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, pxCreatedTask );
if( pxNewTCB != NULL )
{
//创建成功,添加新的任务块到就绪列表
prvAddNewTaskToReadyList( pxNewTCB );
//返回成功
xReturn = pdPASS;
}
else
{
//创建失败,返回失败
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
}
return xReturn;
}
static TCB_t * prvCreateTask( TaskFunction_t pxTaskCode,
const char * const pcName,
const configSTACK_DEPTH_TYPE uxStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask )
{
TCB_t * pxNewTCB;
//判断栈增长方向,STM32栈向上增长
{
StackType_t * pxStack;
//分配uxStackDepth 长度的栈空间,给新建的任务使用
pxStack = pvPortMallocStack( ( ( ( size_t ) uxStackDepth ) * sizeof( StackType_t ) ) );
if( pxStack != NULL )
{
//分配内存空间
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
if( pxNewTCB != NULL )
{
//清空TCB_T结构空间
( void ) memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) );
//任务控制块的pxStack指向新分配的栈空间
pxNewTCB->pxStack = pxStack;
}
else
{
//任务控制块创建失败,释放pxStack 栈空间
vPortFreeStack( pxStack );
}
}
else
{
pxNewTCB = NULL;
}
}
if( pxNewTCB != NULL )
{
//初始化新任务
prvInitialiseNewTask( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );
}
return pxNewTCB;
}
static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
const char * const pcName,
const configSTACK_DEPTH_TYPE uxStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask,
TCB_t * pxNewTCB,
const MemoryRegion_t * const xRegions )
{
StackType_t * pxTopOfStack;
UBaseType_t x;
{
//栈顶指针指向新创建的任务的函数起始栈空间
pxTopOfStack = pxNewTCB->pxStack;
pxTopOfStack = ( StackType_t * ) ( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) + portBYTE_ALIGNMENT_MASK ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
//任务函数起始地址+函数分配栈大小-1,指向endOfStack
pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( uxStackDepth - ( configSTACK_DEPTH_TYPE ) 1 );
}
//存储任务名称到任务控制块的pcTaskName
if( pcName != NULL )
{
for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )
{
pxNewTCB->pcTaskName[ x ] = pcName[ x ];
/* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than
* configMAX_TASK_NAME_LEN characters just in case the memory after the
* string is not accessible (extremely unlikely). */
if( pcName[ x ] == ( char ) 0x00 )
{
break;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
//名字最后追加字符串'\0'
pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1U ] = '\0';
}
else
{
mtCOVERAGE_TEST_MARKER();
}
//优先级检测
configASSERT( uxPriority < configMAX_PRIORITIES );
//设置优先级
pxNewTCB->uxPriority = uxPriority;
vListInitialiseItem( &( pxNewTCB->xStateListItem ) );
vListInitialiseItem( &( pxNewTCB->xEventListItem ) );
/* Set the pxNewTCB as a link back from the ListItem_t. This is so we can get
* back to the containing TCB from a generic item in a list. */
listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB );
/* Event lists are always in priority order. */
listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority );
listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB );
if( pxCreatedTask != NULL )
{
/* Pass the handle out in an anonymous way. The handle can be used to
* change the created task's priority, delete the created task, etc.*/
*pxCreatedTask = ( TaskHandle_t ) pxNewTCB;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
添加任务:void prvAddNewTaskToReadyList( TCB_t * pxNewTCB )
static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB )
{
//进入临界区,添加任务时不允许被中断打断
taskENTER_CRITICAL();
{
//当前任务总数加1
uxCurrentNumberOfTasks++;
if( xSchedulerRunning == pdFALSE )
{
if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 )
{
//创建第1个任务prvCreateIdleTasks()
prvInitialiseTaskLists();
}
.....................
}
//添加任务到就绪列表,新任务默认初始化后处于就绪状态
prvAddTaskToReadyList( pxNewTCB );
portSETUP_TCB( pxNewTCB );
if( xSchedulerRunning != pdFALSE )
{
//新任务的优先级高于当前正在运行任务的优先级,直接切换当前任务到运行状态
taskYIELD_ANY_CORE_IF_USING_PREEMPTION( pxNewTCB );
}
}
//退出临界保护区
taskEXIT_CRITICAL();
}
#define prvAddTaskToReadyList( pxTCB )
do {
//在ready列表里面添加新的任务块
listINSERT_END( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) );
} while( 0 )



6997

被折叠的 条评论
为什么被折叠?



