您的位置:首页 > 其它

FreeRTOS 源码注释(xTaskGenericCreate)

2012-06-22 21:04 274 查看
FreeRTOS 是个轻量级的实时操作系统,功能还不错。最近花了些时间研究了一下,代码写的很严谨,值得学习。鉴于国内介绍资料非常少,因此,准备做一个系列笔记,将其主要功能代码做个注释,主要是方便自己查找。也希望能给对这个操作系统感兴趣的国内同行一点参考。

xTaskGenericCreate 用来建立一个任务,实际上 xTaskCreate 也是对 xTaskGenericCreate 的包装。

下面的代码有些删减,将一些非主线的内容去掉了,这样更方便学习。

signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion
* const xRegions )

{

signed portBASE_TYPE xReturn;

tskTCB * pxNewTCB;

configASSERT( pxTaskCode );

configASSERT( ( uxPriority < configMAX_PRIORITIES ) );

/* 为TCB 和 堆栈分配空间 */

pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );

if( pxNewTCB != NULL ) /* 如果 TCB 空间分配成功 */

{

portSTACK_TYPE *pxTopOfStack;

/* 计算堆栈栈顶的位置 */

#if( portSTACK_GROWTH < 0 )/* portSTACK_GROWTH == -1 对应倒生堆栈,比如 x86 */

{

pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( unsigned short ) 1 ); /* pxStack 指向堆栈的起始地址 */

pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( unsigned long ) pxTopOfStack ) & ( ( unsigned long ) ~portBYTE_ALIGNMENT_MASK ) );/* 堆栈有地址对齐的要求 */

}

#else

{

pxTopOfStack = pxNewTCB->pxStack;/* 新建的堆栈是空的,所以堆栈的栈顶就在起始地址处(正生堆栈)*/

/* Check the alignment of the stack buffer is correct. */

/* 如果要做堆栈检查,就要知道堆栈的另一端界限在哪里 */

pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );

}

#endif

/* 设置 TCB 的各个部分 */

prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth );

/* 初始化堆栈,使得任务好像被中断函数中断了一样,中断返回地址就是任务的首地址,与 uC/OS-II 的方式相同 */

if( ( void * ) pxCreatedTask != NULL )

{

/* 返回任务的句柄 */

*pxCreatedTask = ( xTaskHandle ) pxNewTCB;

}

taskENTER_CRITICAL();

{

uxCurrentNumberOfTasks++;

if( pxCurrentTCB == NULL )

{

/* 如果没有其他任务,这个任务必然就成为当前任务,好像只有第一个任务会遇到这个情况阿?! */

pxCurrentTCB = pxNewTCB;

if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 )

{

/* 如果这是第一个任务,就做初始化工作,uC/OS-II 有单独的初始化函数,FreeRTOS 没有,初始化工作放在这里 */

prvInitialiseTaskLists();

}

}

else

{

if( xSchedulerRunning == pdFALSE )

{

if( pxCurrentTCB->uxPriority <= uxPriority )

{

pxCurrentTCB = pxNewTCB; /*新任务优先级高*/

}

}

}

if( pxNewTCB->uxPriority > uxTopUsedPriority )

{

uxTopUsedPriority = pxNewTCB->uxPriority;

}

uxTaskNumber++;

prvAddTaskToReadyQueue( pxNewTCB );/* 将任务加入到 Ready 队列 */

xReturn = pdPASS;

traceTASK_CREATE( pxNewTCB );

}

taskEXIT_CRITICAL();

}

else

{

xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;

traceTASK_CREATE_FAILED();

}

if( xReturn == pdPASS )

{

if( xSchedulerRunning != pdFALSE )

{

if( pxCurrentTCB->uxPriority < uxPriority )

{

portYIELD_WITHIN_API(); /* 新任务比当前正在运行的任务优先级高,因此要做任务调度 */

}

}

}

return xReturn;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: