[逆解] FreeRTOS 1 - 问题分析

FreeRTOS资源

Homepage:https://www.freertos.org/

Github:https://github.com/FreeRTOS/FreeRTOS

Git:git clone [email protected]:FreeRTOS/FreeRTOS.git --recurse-submodules

FreeRTOS示例

在FreeRTOS中,多个用户任务可以包装成Task,并行运行。一个典型的FreeRTOS程序如下例:

int main(void)
{
  /* Board initialization */
  BSP_Init();
  
  /* Create FreeRTOS Task1 */
  xTaskCreate((TaskFunction_t)Task1,                    /* Task entry function */
              (const char*   )"Task1",                  /* Task name */
              (uint16_t      )512,                          /* Task stack size */
              (void*         )NULL,                         /* Task entry parameter */
              (UBaseType_t   )1,                                /* Task priority */
              (TaskHandle_t* )&onTaskCreated);  /* Task created event handler */
  /* Create FreeRTOS Task2 */
  xTaskCreate((TaskFunction_t)Task2,                    /* Task entry function */
              (const char*   )"Task2",                  /* Task name */
              (uint16_t      )512,                          /* Task stack size */
              (void*         )NULL,                         /* Task entry parameter */
              (UBaseType_t   )2,                                /* Task priority */
              (TaskHandle_t* )&onTaskCreated);  /* Task created event handler */
  
  /* FreeRTOS main loop */
  vTaskStartScheduler();
  
  /* Untouched code normally */
  while(1);   
}

Task的实质是一段循环运行的函数代码。比如下例的两个Task实现了不同闪动频率的两个LED灯。

void Task1(void *pvParameters)
{
    for(;;)
    {
        LED0(ON);
        vTaskDelay(300);
        LED0(OFF);
        vTaskDelay(300);
    }
}

void Task2(void *pvParameters)
{
    for(;;)
    {
        LED0(ON);
        vTaskDelay(500);
        LED0(OFF);
        vTaskDelay(500);
    }
}

FreeRTOS的核心目标

FreeRTOS的目标就是将多个这样的函数代码,采用一定的方式拆解成更小的片段,分时穿插运行,造成并行运行的假象。如下图所示:

           +----------+----------+----------+----------+
Task 1:    | Slice 1A | Slice 1B | Slice 1C | Slice 1D | 
           +----------+----------+----------+----------+
        
           +----------+----------+----------+
Task 2:    | Slice 2A | Slice 2B | Slice 2C |
           +----------+----------+----------+
              
           +----++----++----++----++----++----++----++----++----++----+
Runtime*:  | 1A || 2A || 1B || 1C || 2B || 1D || 1A || 2C || 2A || 1B | ...
           +----++----++----++----++----++----++----++----++----++----+
         
*: runtime中的顺序只是某一种可能性

为实现这样的目标,FreeRTOS需要解决下面的这些问题:

  1. 如何将一个完整的任务函数分拆成若干个代码段?
  2. 如何保持任务切换前后能正确运行?
  3. 如何调度代码段?

以上分析同样适用于其他的RTOS。这些问题实际上在桌面操作系统中已经有答案。RTOS实际上是对完整操作系统进行了不同程度的精简,以满足嵌入式系统有限的系统资源。不同的RTOS实质上大同小异,只在实现细节上有一些细微差别,特别是API的封装方式和代码工具包的支持上各有千秋。

内存管理

操作系统的另一个核心任务是进行内存管理。特别是桌面操作系统要保证多任务的安全性,会用虚拟内存区隔不同的任务空间。但嵌入式系统很少提供内存管理模块,嵌入式操作系统通常也并不会管理虚拟内存。

FreeRTOS也是如此,所有的Task都运行在同一个地址空间下,更像是线程,不是进程。

在内存管理方面,FreeRTOS只提供了一些Heap模块,方便用户动态申请内存。

你可能感兴趣的:([逆解] FreeRTOS 1 - 问题分析)