【freeRTOS】Day1



RTOS的使用不外乎幾個重點,任務的建立/調度,訊息的傳遞,資源的安排

先以一個freeRTOS任務建置的例子來簡單介紹,

使用xTaskCreate()建立task任務,vTaskStartScheduler()啟動任務,

task_1()即被執行的task

vTaskDelay()可暫時交出CPU的使用權,task將處于Blocked阻塞狀況,直到tick的時間結束再回到task_1()

TaskHandle_t  task_1_handle;

static void task_1 (void * pvParameter)
{
    while (true)
    {
        /* Do task things */
        
        /* Delay a task for a given number of ticks */
        vTaskDelay(100);
    }
}

int main(void)
{
    xTaskCreate(task_1, \
                "LED0", \
                configMINIMAL_STACK_SIZE + 200, \
                NULL, \
                configMAX_PRIORITIES-1, \
                &task_1_handle);

    /* Start FreeRTOS scheduler. */
    vTaskStartScheduler();

    while (true)
    {
        /* FreeRTOS should not be here... FreeRTOS goes back to the start of stack
         * in vTaskStartScheduler function. */
    }
}

🔔 vTaskStartScheduler()執行後就啟動RTOS程序,系統不會走到下面的 while(true)迴圈



以下是最先要注意 FreeRTOSConfig.h 的參數設定,會影響task任務的運行結果

configMAX_PRIORITIES

  • 任務優先權最大值,建立任務時為其分配優先權從 0到configMAX_PRIORITIES-1
  • configUSE_PORT_OPTIMISED_TASK_SELECTION為1時不可大於32
  • tskIDLE_PRIORITY為數值0的空閒任務
  • configUSE_PREEMPTION

  • configUSE_PREEMPTION默認為 1
  • configUSE_PREEMPTION為0時任務不進行搶佔,除非運行的任務進入Blocked阻塞/Suspend/Resume,或執行taskYIELD()
  •      再或者有ISR()中斷進行切換

  • 例子:
    • task A擁有高優先權,執行vTaskDelay()進入Blocked mode,程序進入task B
      configUSE_PREEMPTION = 1 ,當vTaskDelay()的計數時間到時,task A將從task B搶奪系統回到Running mode
      configUSE_PREEMPTION = 0 ,task A只有在task B讓出系統才能再度運行


    configUSE_TIME_SLICING

  • configUSE_TIME_SLICING默認為 0
  • configUSE_TIME_SLICING為1時,系統將在每個tick在相同優先權的任務間輪流巡視
  • 例子:
    • task A與B的優先權相同
      configUSE_TIME_SLICING = 1
      configUSE_PREEMPTION = 1 ( 必須為1 )
      configTICK_RATE_HZ = 1000 ( 1000Hz == 1ms )
      可以看到task A和B每執行1ms就進入Blocked

  • 例子:
    • 優先權 task A > B = C,那程序將只運行在task A

    configTOTAL_HEAP_SIZE

  • heap size定義出的記憶體大小供stack建立時的可分配容量,其中也包含TCB (Task Control Block)所需
  • #define configTOTAL_HEAP_SIZE ( 4096 ) 即規畫4096 byte,
  •      configSTACK_DEPTH_TYPE 定義stack寛度為16或32bit

         16bit時,stack size 100則表示為200 bytes

         32bit時,stack size 100則表示為400 bytes

         所以task無論一個或數個,stack size加總必小于heap size

         ❗如果stack size加總超過heap size,系統在運行時會隨即跳到app_error_fault_handler()

    configSUPPORT_DYNAMIC_ALLOCATION

  • TaskCreate()任務動態配置函式的使用,configSUPPORT_DYNAMIC_ALLOCATION需為 1