• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 設計應用 > 學RTOS從配置文件開始!

    學RTOS從配置文件開始!

    作者: 時間:2024-12-24 來源: 收藏

    最近有小伙伴問:學從哪里開始?這個問題說簡單也簡單,說難也難,因為每個人掌握的基礎不同,自然,從哪里開始學起也各有不同。首先你要去了解相關的一些基礎知識,然后再下載源碼實踐運行,跑起來!接下來真正入門的第一步,大概率還得從“配置”文件開始,這里的配置,可以理解為大家說的“裁剪系統”及相關的一些配置。

    本文引用地址:http://www.czjhyjcfj.com/article/202412/465754.htm

    比如 Free 中“FreeRTOSConfig.h”

    640.gif

    當然,是你已經具備一定基礎知識,上手源碼第一步要掌握的內容。不僅僅是 FreeRTOS,其他μCOS、RT-Thread,甚至Linux都是從配置開啟第一步的。

    可能會有老鐵說,使用STM32CubeMX配置FreeRTOS,就不用修改(配置)FreeRTOSConfig.h文件?這么說吧,第三方工具圖形化配置,也會牽涉到,而且僅僅是基礎的配置,你要做項目還是會修改配置文件。通過第三方配置工具,你不會真正掌握RTOS底層原理,后期做項目你會發現很困難。

    FreeRTOS配置文件常見內容

    本文結合流程的FreeRTOS給大家講講其中配置文件的內容。FreeRTOS配置文件看起來有點多,但它都有分類,多了解一下,你會發現理解起來也不是很難。

    通用配置

    通用配置基本配置,就是需要我們定義的一些配置,也是比較重要的配置。   

    1.configUSE_PREEMPTION調度模式配置

    配置為0:合作式調度,即時間片輪流執行;

    配置為1:搶占式調度,即優先級高的任務搶先執行;

    由于我們要求實時響應,就配置為1,使用搶占式調度方式。否則就發揮不到實時操作系統的作用。

    2.configCPU_CLOCK_HZ

    CPU時鐘,就是我們常說的主頻。注意:單位是Hz。

    如:STM32F407主頻為168M

    #define configCPU_CLOCK_HZ      (168000000)

    3.configTICK_RATE_HZ

    系統滴答,即系統每秒鐘滴答的次數,可以說是系統的心跳,但需要和主頻區分開來。系統滴答的值要根據CPU主頻來看,一般主頻越高,取值相對越大,一般在100至1000之間。

    簡單舉例:系統滴答決定vTaskDelay。

    比如:

    #define configTICK_RATE_HZ    (1000)

    則:vTaskDelay(1000),表示延時1S。

    4.configMAX_PRIORITIES

    系統最大優先級值:我們創建任務是,配置的優先級值不能超過這個最大值。

    xTaskCreate(vAppTask1, "Task1", TASK1_STACK_SIZE, NULL, TASK1_PRIORITY, NULL);

    提示:

    a.系統優先級和中斷優先級原理類似,高優先級的會搶在低優先級的前面,但需要區分系統和中斷優先級的應用場景。

    b.FreeRTOS中優先級數值越大,優先級越高。而UCOS則相反。

    5.configMINIMAL_STACK_SIZE

    最小堆棧值:在系統中,一般用于空閑、定時等一些系統任務中,當然,我們有些地方也可以使用這個定義的堆棧值。

    注意數值的單位,一般在ARM中為4個字節。

    6.configTOTAL_HEAP_SIZE

    系統總共堆(棧)大小:我們需要根據需要使用的情況定義這個值。不能定義太小,太小內存容易溢出;也不能定義太大,有些芯片RAM本身就不大(有些就只有幾K),如果太大我們就沒法定義太多全局變量,或分配其他堆棧空間。

    7.configMAX_TASK_NAME_LEN

    任務名稱最大長度:也就是創建任務定義任務名稱的字符串長度。

    xTaskCreate(vAppTask1, "Task1", TASK1_STACK_SIZE, NULL, TASK1_PRIORITY, NULL);

    提示:結束符 '?'也包含在內。

    8.configUSE_16_BIT_TICKS

    是否使用16位滴答計數值

    配置為0:則使用32位的滴答計數值,一般在32位處理器中都是配置為0;

    配置為1:則使用16位的滴答計數值,一般8位或者16位處理器中配置為1。

    9.configIDLE_SHOULD_YIELD

    是否讓空閑任務“放棄”搶占:也就是說在執行與空閑任務相同優先級的任務過程中,空閑任務是否具有搶占的機會。

    配置為0:不放棄搶占;

    配置為1:放棄搶占;

    10.configUSE_MUTEXES

    是否使用互斥鎖

    配置為0:不使用

    配置為1:使用

    提示:互斥鎖也叫互斥信號量,也就是說對資源“加鎖”。它的作用是實現多任務間共享資源的獨占式處理。簡單的說,就是某個資源在某一時刻只允許一個任務處理,處理完之后才允許其他任務處理該資源。

    比如:A任務優先級高,B任務優先級低;AB任務都會使用一個串口發送指令數據,(即每次必須發送完成,不能發送到一半就被打斷)。

    當B任務正在發送數據時,A任務處于就緒狀態(要打斷B任務)。那么B任務就需要使用互斥鎖占有該串口(加鎖,占有該資源),等發送完指令,就釋放該串口(開鎖,釋放該資源)。一旦釋放了該資源,A任務就可以使用該串口(資源)了。

    11.configUSE_RECURSIVE_MUTEXES

    是否使用遞歸互斥鎖

    配置為0:不使用

    配置為1:使用

    13.configQUEUE_REGISTRY_SIZE(*)

    可添加(或登記)隊列名的數量:這個配置信息不好翻譯,它主要結合vQueueAddToRegistry與vQueueUnregisterQueue這兩個函數使用。

    直接上函數接口:

    void vQueueAddToRegistry(QueueHandle_t xQueue, const char *pcQueueName);
    void vQueueUnregisterQueue(QueueHandle_t xQueue);

    從函數接口可以知道,一個函數是登記(已經創建的)隊列的名稱;一個函數是注銷隊列的名稱;其實,主要目的就是給(已經創建的)隊列取名,方便調試查找。

    提示:很多初學者理解為“可創建隊列的最大數”,這個配置參數與其完全不一樣的概念。

    14.configUSE_QUEUE_SETS(*)

    是否使用消息隊列“SET”功能

    配置為0:不使用

    配置為1:使用

    15.configUSE_TIME_SLICING

    是否使用時間片進行調度:這個參數結合上面第1各配置參數configUSE_PREEMPTION一起使用。這個配置參數是在后面新版本增加的,好像在V7版本之前是沒有這個配置參數。所以,在FreeRTOSConfig.h配置文件中默認是沒有的,而是定義在FreeRTOS.h中。

    #ifndef configUSE_TIME_SLICING  
    #define configUSE_TIME_SLICING 1
    #endif

    HOOK配置

    1.configUSE_IDLE_HOOK

    是否定義IDLE空閑任務HOOK函數

    配置為0:不定義

    配置為1:定義

    configUSE_IDLE_HOOK是系統設計之初就有的,必須在“FreeRTOSConfig.h”中宏定義。不像有些宏定義可以不在“FreeRTOSConfig.h”中定義,因為它們在“FreeRTOS.h”有判斷是否定義了,如果沒有定義,會有一個默認的定義。

    比如:“configUSE_MUTEXES”可以不在“FreeRTOSConfig.h”中定義,而在“FreeRTOS.h”中可以看到如下一段代碼:

    #ifndef configUSE_MUTEXES
    #define configUSE_MUTEXES 0
    #endif

    也就是說,如果沒有定義,它會默認給你定義。

    回來說configUSE_IDLE_HOOK,在task.c文件中,有如下一段代碼:

    #if (configUSE_IDLE_HOOK == 1)
    {  
    extern void vApplicationIdleHook(void);  
    vApplicationIdleHook();
    }
    #endif

    意思是說:如果你配置configUSE_IDLE_HOOK為1,那么你就必須要實現“vApplicationIdleHook()”這個函數,否則編譯會出錯。初學者默認不定義該函數。

    2.configUSE_TICK_HOOK

    是否定義TICK滴答HOOK函數

    配置為0:不定義

    配置為1:定義

    在task.c文件中的xTaskIncrementTick函數下可以看見如下代碼:

    #if (configUSE_TICK_HOOK == 1)
    {  
        if(uxPendedTicks == (UBaseType_t) 0U)  
        {    vApplicationTickHook();  
        }  
    else  
    {    
        mtCOVERAGE_TEST_MARKER();  
        }
    }
    #endif

    提示:xTaskIncrementTick函數是在PendSV_Handler中斷函數中被調用的。因此,vApplicationTickHook()函數執行的時間必須很短才行。

    3.configCHECK_FOR_STACK_OVERFLOW

    是否定義棧溢出HOOK函數

    配置為0:不定義

    配置為1:定義

    這個配置比較關鍵和重要,特別對于復雜的系統設計,代碼量比較大那種工程,使用該功能,可以幫你分析是否有內存越界的情況。

    4.configUSE_MALLOC_FAILED_HOOK

    是否定義內存分配失敗HOOK函數

    配置為0:不定義

    配置為1:定義

    我們創建任務、信號量、隊列等都需要耗費系統堆棧,如果我們對系統總共分配堆棧不夠多,在創建多個任務或隊列時容易分配失敗,這個時候就起到一個提示作用。

    5.configUSE_DAEMON_TASK_STARTUP_HOOK

    是否定義守護進程HOOK函數

    配置為0:不定義

    配置為1:定義

    通過分析軟件源代碼可以發現,這個HOOK函數是在TIMER任務下面實現的,所以需要配置configUSE_TIMERS為1。

    TIMERS配置

    TIMER即定時器,在RTOS中的TIMER屬于軟件定時。FreeRTOS的定時器精度不高,會隨著定時的增加而改變,特別是TIMER任務優先級較低,高優先級占用資源的情況下。

    若要使用高精度的定時,還是最后使用硬件的定時器(現在處理器一般都有多個硬件TIMER)。

    1.configUSE_TIMERS是否使用軟件定時器

    配置為0:不使用

    配置為1:使用

    其他許多相關的功能都需要結合該配置才能使用,使用時需要注意是否關聯。

    2.configTIMER_TASK_PRIORITY

    軟件定時器任務優先級:軟件定時器其實也是需要創建一個任務,創建方式和我們常規的一樣,只是它是有系統內核完成,不用我們自己寫創建任務代碼。

    這里的這個優先級就是定時器任務的優先級。

    3.configTIMER_QUEUE_LENGTH

    軟件定時器命令隊列長度:關于TIMER的命令隊列牽涉的知識相對復雜點,后期進一步講述,可看下圖:

    640.png

    4.configTIMER_TASK_STACK_DEPTH

    分配給軟件定時器的堆棧空間

    CO_ROUTINES配置

    CO_ROUTINES這個不好翻譯,網上都叫協同程序,或者合作程序,理解為協同一起使用的程序,后期結合應用講述。

    1.configUSE_CO_ROUTINES

    是否使用CO_ROUTINES

    配置為0:不使用

    配置為1:使用

    2.configMAX_CO_ROUTINE_PRIORITIES

    CO_ROUTINE優先級

    MEMORY配置

    內存分配相關的配置,這里的配置與heap_x.c有關,后面會再次進行講述。

    1.configSUPPORT_STATIC_ALLOCATION

    是否支持靜態分配

    配置為0:不支持

    配置為1:支持

    2.configSUPPORT_DYNAMIC_ALLOCATION

    是否支持動態分配

    配置為0:不支持

    配置為1:支持

    3.configTOTAL_HEAP_SIZE

    分配給系統的堆棧:創建任務,堆棧,靜態、動態都分配的內存都來自這里。

    4.configAPPLICATION_ALLOCATED_HEAP

    APP使用哪里分配的堆

    配置為0:使用系統分配的堆

    配置為1:使用外部分配的堆

    默認使用系統分配的堆,見下面定義:
    #if(configAPPLICATION_ALLOCATED_HEAP == 1 )
      extern uint8_t ucHeap[configTOTAL_HEAP_SIZE];
    #else
      static uint8_t ucHeap[configTOTAL_HEAP_SIZE];
    #endif

    RUN_TIME_STATS配置

    運行時信息統計配置

    1.configGENERATE_RUN_TIME_STATS

    是否生成統計信息

    配置為0:否

    配置為1:是

    2.configUSE_TRACE_FACILITY

    是否協助執行可視化和跟蹤

    配置為0:否

    配置為1:是

    這里會添加額外的結構體來實現。

    3.configUSE_STATS_FORMATTING_FUNCTIONS

    是否統計相關的功能

    配置為0:否

    配置為1:是

    設置宏configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS為1會編譯vTaskList()和vTaskGetRunTimeStats()函數。如果將這兩個宏任意一個設置為0,上述兩個函數不會被編譯。

    其他配置

    這里簡單綜合講述一下各項配置

    1.configASSERT

    斷言配置

    2.Interrupt相關

    configKERNEL_INTERRUPT_PRIORITY:內核中斷優先級

    configMAX_SYSCALL_INTERRUPT_PRIORITY:系統調用最大的優先級

    configMAX_API_CALL_INTERRUPT_PRIORITY:API調用的最大優先級

    這一節與(Cortex)內核硬件中斷有關。

    3.INCLUDE配置

    #define INCLUDE_vTaskPrioritySet
    #define INCLUDE_uxTaskPriorityGet
    #define INCLUDE_vTaskDelete

    這里給大家分享了常見的一些配置內容,要深入理解并掌握,還是需要自己多動手修改代碼驗證才行。



    關鍵詞: RTOS 配置文件

    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 登封市| 甘洛县| 城固县| 铜山县| 新和县| 万州区| 东源县| 萨迦县| 闻喜县| 林口县| 和政县| 增城市| 霍林郭勒市| 平舆县| 岗巴县| 秭归县| 尖扎县| 武夷山市| 五莲县| 吉隆县| 泽库县| 同德县| 秦安县| 成都市| 历史| 洛浦县| 崇信县| 会理县| 筠连县| 青田县| 双峰县| 绩溪县| 新建县| 长顺县| 胶州市| 蒙阴县| 六枝特区| 蒲城县| 兴仁县| 霍城县| 资阳市|