STM32 FreeRTOS

FreeRTOS 架構

官方網站http://www.freertos.org/
FreeRTOS 是一個相對其他作業系統而言較小的作業系統。最小化的 FreeRTOS 核心僅包括 3 個 .c 文件(tasks.c、queue.c、list.c)和少數標頭檔,總共不到 9000 行程式碼,還包括了註解和空行。一個典型的編譯後 binary(二進位碼)小於 10 KB。
FreeRTOS 的程式碼可以分為三個主要區塊:任務、通訊和硬體界面。

  • 任務 (Task): FreeRTOS 的核心程式碼約有一半是用來處理多數作業系統首要關注的問題:任務,任務是擁有優先權的用戶所定義的 C 函數。task.c 和 task.h 負責所有關於建立、排程和維護任務的繁重工作。
  • 通訊 (Communication): 任務很重要,不過任務間可以互相通訊則更為重要!它帶出了 FreeRTOS 的第二項議題:通訊。FreeRTOS 核心程式碼大約有 40% 是用來處理通訊的。queue.c 和 queue.h 負責處理 FreeRTOS 的通訊,任務和中斷(interrupt)使用佇列(佇列,queue)互相發送數據,並且使用 semaphore 和 mutex 來派發 critical section 的使用信號。
  • 硬體界面:有近 9000 行的程式碼組成基本的 FreeRTOS,這部份是與硬體無關的(hardware-independent),同一份程式碼在不同硬體平台上的 FreeRTOS 都可以運行。大約有 6% 的 FreeRTOS 核心代碼,在與硬體無關的 FreeRTOS 核心和與硬體相關的程式碼間扮演著墊片(shim)的角色。我們將在下個部分討論與硬體相關的程式碼。[#]_

用 cloc統計 FreeRTOS 8.0.0 的 include/ *.c portable/GCC/ARM_CM4F/ 等目錄,可得不含註解、空白行的行數為 6566,而統計與平台有關的部份 (portable/GCC/ARM_CM4F/ 目錄),則是 435 行。計算可得: 435 / 6566 = 0.06625 = 6%,與描述相符,但原本的 9000 行是指含註解的說法 (實際為 8759 行)

原始碼載點

官方下載:https://sourceforge.net/projects/freertos

  • tasks.c:主要掌管 task 的檔案
  • queue.c:管理 task 間 communication (message queue 的概念)
  • list.c:提供系統與應用實作會用到的 list 資料結構
  • portmacro.h:定義了與硬體相關的變數,如資料型態定義,以及與硬體相關的函式呼叫名稱定義(以 portXXXXX 命名)等,統一各平臺的函式呼叫
  • port.c:定義了包含與硬體相關的程式碼實作
  • FreeRTOSConfig.h:包含 clock speed, heap size, mutexes 等等都在此定義(需自行建立)

FreeRTOS 移植

這邊可以參考影片FreeRTOS–第2.2讲 FreeRTOS在STM32F4上的移植STM32F429
主要是把FreeRTOS的結構移植到所要開發的板子上內部支援的很多但沒看到是CubeIDE版本的

  1. 匯入.h檔
    1. <FreeRTOS>/Source/include
    2. <FreeRTOS>/Demo/CORTEX_M4F_STM32F407ZG-SK(這步主要是因為範例移植F4須比照自己需求移植)
    3. <FreeRTOS>/Source/portable/RVDS/ARM_CM4F(這步看主要核心是用哪種F4為 M4核心)
      中的 *.h 匯入
  2. 將 *.c 檔案加入至專案中
    1. <FreeRTOS>/Source/(全部匯入)
    2. <FreeRTOS>/Source/portable/MemMang/heap_1.c
    3.  <FreeRTOS>/Source/portable/RVDS/ARM_CM4F/port.c (這步看主要核心是用哪種F4為 M4核心)
  3. 打開 <FreeRTOS>/Demo/CORTEX_M4F_STM32F407ZG-SK/FreeRTOSConfig.h
    並將 #include “stm32f4xx.h” 標頭檔加入到文件中,且將 
    #define  configCHECK_FOR_STACK_OVERFLOW  2 改成
    #define  configCHECK_FOR_STACK_OVERFLOW  0 ,存檔並關閉。
  4. 打開 <FreeRTOS>/Source/portable/RVDS/ARM_CM4F/port.c 
    並將 #include “stm32f4xx.h” 標頭檔加入到文件中。

注意要點

  1. 修改 FreeRTOSConfig.h 移除 #ifdef ICCARM 和相對應的 #endif
  2. 修改 src/stm32f4xxit.c ,將 SVCHandler(), PendSV_Handler(),SysTick_Handler() 三個函式前面加上 __attribute((weak))
  3. 修改 src/main.c 在前面增加 #include “FreeRTOS.h” 和 #include “task.h”
  4. 修改 src/main.c 增加 vApplicationMallocFailedHook() , vApplicationIdleHook() 和 vApplicationStackOverflowHook() 三個函式,可從 FreeRTOS/Demo/CORTEX_M4F_STM32F407ZG-SK/main.c 中複製
  5. 修改 src/main.c 增加 vApplicationTickHook() 函式,內容為空即可。
  6. 將 lib/FreeRTOS/src 中的 .c 檔加入專案中編譯。注意:heap_x.c 只需選擇一個即可,可以先使用 heap_1.c
  7. 修改 main() ,加入一行 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

步驟 16 中 heap_x.c 是 FreeRTOS 提供的多種記憶體管理方式。如果系統中配置的記憶體不會釋放,可以使用 head_1.c 。否則就要選擇其他的管理方式。FreeRTOS Memory Management – 步驟 17 是為了配合 FreeRTOS ,將 NVIC 的優先權設定成 NVIC_PriorityGroup_4

LED 閃爍測試程式

用這個簡單程式去驗證是否移植成功

void LED_Init(void)
{
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_StructInit(&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

__INLINE void LED_On(void)
{
    GPIO_SetBits(GPIOA, GPIO_Pin_5);
}

__INLINE void LED_Off(void)
{
    GPIO_ResetBits(GPIOA, GPIO_Pin_5);
}

static void Blink_Task(void* pvParameters)
{
    TickType_t xLastFlashTime;

    LED_Init();

    xLastFlashTime = xTaskGetTickCount();

    while (1) {
        LED_On();
        vTaskDelayUntil(&xLastFlashTime, 500);
        LED_Off();
        vTaskDelayUntil(&xLastFlashTime, 4500);
    }
}

int main(void)
{
    // Initialize system
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

    xTaskCreate(Blink_Task, "LED", configMINIMAL_STACK_SIZE, NULL,
                BLINK_TASK_PRIORITY, NULL);

    vTaskStartScheduler();

    while (1) {
    }
}

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart