FreeRTOS_分析
FreeRTOS 是一个开源的实时操作系统。可以在很的低内存使用的情况下运行在单片机上,使得单片机可以并发(虽然某一时刻还是只有一个任务运行) 的运行程序。关于一些 FreeRTOS 优缺点的介绍文章很多,这里就不再赘述直接深入代码探究原理。
关于 FreeRTOS 的疑问
在刚接触 FreeRTOS 的时候我是有以下几个问题的。
1. FreeRTOS 是如何建立任务的呢?
2. FreeRTOS 是调度和切换任务的呢?
3. FreeRTOS 是如何保证实时性呢?
这篇就是对第一个问题,FreeRTOS 是如何建立任务从代码上进行分析。
在 FreeRTOS 官方的指南上对创建任务就是调用了 xTaskCreate 函数。下面的图截取与官方的教程,里面对 xTaskCreate 函数的用法进行了展示,并对参数也进行了大体上的介绍。
xTaskCreate 函数分析
这个函数被包含在 FreeRTOS 代码的 task.c 中。这个函数比较长,下面贴出的函数对里面的内容进行了省略。
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;
/* 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 ) );
...
pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) );
...
prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );
prvAddNewTaskToReadyList( pxNewTCB );
xReturn = pdPASS;
从代码中很容易看出,xTaskCreate 函数主要的工作就是 3 步。
第1步 给新的任务申请空间
pvPortMalloc
函数,其作用是给新的任务申请一块任务控制块(TCB, Task Control Block)空间。后面继续使用 pvPortMallocStack
函数为新的任务申请一块栈空间。 其具体的实现在 heapX.c 中 X 可以是1~5。相关的细节可以看一下相关的介绍,这里的2个用于申请空间的函数可以简单的看作是 malloc 函数就可以了。
第2步 为新任务初始化空间
prvInitialiseNewTask
函数也很长,故省略里面很多的内容。专注于实现逻辑,先放弃具体细节。
static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const uint32_t ulStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask,
TCB_t * pxNewTCB,
const MemoryRegion_t * const xRegions