美文网首页[学习] 逆解系列
[逆解] FreeRTOS 1 - 问题分析

[逆解] FreeRTOS 1 - 问题分析

作者: TalktoEason | 来源:发表于2021-10-10 23:48 被阅读0次

    FreeRTOS资源

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

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

    Git:git clone git@github.com: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 - 问题分析

        本文链接:https://www.haomeiwen.com/subject/cegkoltx.html