溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

FreeRTOS實(shí)時(shí)操作系統(tǒng)多任務(wù)管理基礎(chǔ)知識(shí)有哪些

發(fā)布時(shí)間:2022-04-06 15:08:27 來源:億速云 閱讀:131 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“FreeRTOS實(shí)時(shí)操作系統(tǒng)多任務(wù)管理基礎(chǔ)知識(shí)有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“FreeRTOS實(shí)時(shí)操作系統(tǒng)多任務(wù)管理基礎(chǔ)知識(shí)有哪些”吧!

    RTOS 系統(tǒng)的核心就是任務(wù)管理,F(xiàn)reeRTOS 也不例外,而且大多數(shù)學(xué)習(xí) RTOS 系統(tǒng)的工程師或者學(xué)生主要就是為了使用 RTOS 的多任務(wù)處理功能,初步上手 RTOS 系統(tǒng)首先必須掌握的也是任務(wù)的創(chuàng)建、刪除、掛起和恢復(fù)等操作,由此可見任務(wù)管理的重要性。

    什么是多任務(wù)系統(tǒng)?

    回想一下我們以前在使用 51、AVR、STM32 單片機(jī)裸機(jī)(未使用系統(tǒng))的時(shí)候一般都是在main 函數(shù)里面用 while(1)做一個(gè)大循環(huán)來完成所有的處理,即應(yīng)用程序是一個(gè)無限的循環(huán),循環(huán)中調(diào)用相應(yīng)的函數(shù)完成所需的處理。有時(shí)候我們也需要中斷中完成一些處理。相對(duì)于多任務(wù)系統(tǒng)而言,這個(gè)就是單任務(wù)系統(tǒng),也稱作前后臺(tái)系統(tǒng),中斷服務(wù)函數(shù)作為前臺(tái)程序,大循環(huán)while(1)作為后臺(tái)程序

    FreeRTOS實(shí)時(shí)操作系統(tǒng)多任務(wù)管理基礎(chǔ)知識(shí)有哪些

    前后臺(tái)系統(tǒng)的實(shí)時(shí)性差,前后臺(tái)系統(tǒng)各個(gè)任務(wù)(應(yīng)用程序)都是排隊(duì)等著輪流執(zhí)行,不管你這個(gè)程序現(xiàn)在有多緊急,沒輪到你就只能等著!相當(dāng)于所有任務(wù)(應(yīng)用程序)的優(yōu)先級(jí)都是一樣的。但是前后臺(tái)系統(tǒng)簡(jiǎn)單啊,資源消耗也少啊!在稍微大一點(diǎn)的嵌入式應(yīng)用中前后臺(tái)系統(tǒng)就明顯力不從心了,此時(shí)就需要多任務(wù)系統(tǒng)出馬了。

    多任務(wù)系統(tǒng)會(huì)把一個(gè)大問題(應(yīng)用)“分而治之”,把大問題劃分成很多個(gè)小問題,逐步的把小問題解決掉,大問題也就隨之解決了,這些小問題可以單獨(dú)的作為一個(gè)小任務(wù)來處理。這些小任務(wù)是并發(fā)處理的,注意,并不是說同一時(shí)刻一起執(zhí)行很多個(gè)任務(wù),而是由于每個(gè)任務(wù)執(zhí)行的時(shí)間很短,導(dǎo)致看起來像是同一時(shí)刻執(zhí)行了很多個(gè)任務(wù)一樣。多個(gè)任務(wù)帶來了一個(gè)新的問題,究竟哪個(gè)任務(wù)先運(yùn)行,哪個(gè)任務(wù)后運(yùn)行呢?完成這個(gè)功能的東西在 RTOS 系統(tǒng)中叫做任務(wù)調(diào)度器。不同的系統(tǒng)其任務(wù)調(diào)度器的實(shí)現(xiàn)方法也不同,比如 FreeRTOS 是一個(gè)搶占式的實(shí)時(shí)多任務(wù)系統(tǒng),那么其任務(wù)調(diào)度器也是搶占式的。

    FreeRTOS實(shí)時(shí)操作系統(tǒng)多任務(wù)管理基礎(chǔ)知識(shí)有哪些

    高優(yōu)先級(jí)的任務(wù)可以打斷低優(yōu)先級(jí)任務(wù)的運(yùn)行而取得 CPU 的使用權(quán),這樣就保證了那些緊急任務(wù)的運(yùn)行。這樣我們就可以為那些對(duì)實(shí)時(shí)性要求高的任務(wù)設(shè)置一個(gè)很高的優(yōu)先級(jí),比如自動(dòng)駕駛中的障礙物檢測(cè)任務(wù)等。高優(yōu)先級(jí)的任務(wù)執(zhí)行完成以后重新把 CPU 的使用權(quán)歸還給低優(yōu)先級(jí)的任務(wù),這個(gè)就是搶占式多任務(wù)系統(tǒng)的基本原理。

    FreeRTOS  任務(wù)與協(xié)程

    FreeRTOS 中應(yīng)用既可以使用任務(wù),也可以使用協(xié)程(Co-Routine),或者兩者混合使用。但是任務(wù)和協(xié)程使用不同的API函數(shù),因此不能通過隊(duì)列(或信號(hào)量)將數(shù)據(jù)從任務(wù)發(fā)送給協(xié)程,反之亦然。協(xié)程是為那些資源很少的 MCU 準(zhǔn)備的,其開銷很小,但是 FreeRTOS 官方已經(jīng)不打算再更新協(xié)程了,所以本教程只講解任務(wù)。

    1.任務(wù)(Task) 的特性

    在使用 RTOS 的時(shí)候一個(gè)實(shí)時(shí)應(yīng)用可以作為一個(gè)獨(dú)立的任務(wù)。每個(gè)任務(wù)都有自己的運(yùn)行環(huán)境,不依賴于系統(tǒng)中其他的任務(wù)或者 RTOS 調(diào)度器。任何一個(gè)時(shí)間點(diǎn)只能有一個(gè)任務(wù)運(yùn)行,具體運(yùn)行哪個(gè)任務(wù)是由 RTOS 調(diào)度器來決定的,RTOS 調(diào)度器因此就會(huì)重復(fù)的開啟、關(guān)閉每個(gè)任務(wù)。任務(wù)不需要了解 RTOS 調(diào)度器的具體行為,RTOS 調(diào)度器的職責(zé)是確保當(dāng)一個(gè)任務(wù)開始執(zhí)行的時(shí)候其上下文環(huán)境(寄存器值,堆棧內(nèi)容等)和任務(wù)上一次退出的時(shí)候相同。為了做到這一點(diǎn),每個(gè)任務(wù)都必須有個(gè)堆棧,當(dāng)任務(wù)切換的時(shí)候?qū)⑸舷挛沫h(huán)境保存在堆棧中,這樣當(dāng)任務(wù)再次執(zhí)行的時(shí)候就可以從堆棧中取出上下文環(huán)境,任務(wù)恢復(fù)運(yùn)行。

    任務(wù)特性: 簡(jiǎn)單。沒有使用限制。支持搶占支持優(yōu)先級(jí)每個(gè)任務(wù)都擁有堆棧導(dǎo)致了 RAM 使用量增大。如果使用搶占的話的必須仔細(xì)的考慮重入的問題。

    2.協(xié)程(Co-routine)的特性

    協(xié)程是為那些資源很少的 MCU 而做的,但是隨著 MCU 的飛速發(fā)展,性能越來越強(qiáng)大,現(xiàn)
    在協(xié)程幾乎很少用到了!但是 FreeRTOS 目前還沒有把協(xié)程移除的計(jì)劃,但是 FreeRTOS 是絕對(duì)
    不會(huì)再更新和維護(hù)協(xié)程了,因此協(xié)程大家了解一下就行了。在概念上協(xié)程和任務(wù)是相似的,但
    是有如下根本上的不同:

    • 堆棧使用:所有的協(xié)程使用同一個(gè)堆棧(如果是任務(wù)的話每個(gè)任務(wù)都有自己的堆棧),這樣就比使用任務(wù)消耗更少的 RAM。

    • 調(diào)度器和優(yōu)先級(jí):協(xié)程使用合作式的調(diào)度器,但是可以在使用搶占式的調(diào)度器中使用協(xié)程。

    • 宏實(shí)現(xiàn):協(xié)程是通過宏定義來實(shí)現(xiàn)的。

    • 使用限制:為了降低對(duì) RAM 的消耗做了很多的限制。

    任務(wù)狀態(tài)

    FreeRTOS 中的任務(wù)永遠(yuǎn)處于下面幾個(gè)狀態(tài)中的某一個(gè):

    運(yùn)行態(tài)

    當(dāng)一個(gè)任務(wù)正在運(yùn)行時(shí),那么就說這個(gè)任務(wù)處于運(yùn)行態(tài),處于運(yùn)行態(tài)的任務(wù)就是當(dāng)前正在使用處理器的任務(wù)。如果使用的是單核處理器的話那么不管在任何時(shí)刻永遠(yuǎn)都只有一個(gè)任務(wù)處于運(yùn)行態(tài)。

    就緒態(tài)

    處于就緒態(tài)的任務(wù)是那些已經(jīng)準(zhǔn)備就緒(這些任務(wù)沒有被阻塞或者掛起),可以運(yùn)行的任務(wù),但是處于就緒態(tài)的任務(wù)還沒有運(yùn)行,因?yàn)橛幸粋€(gè)同優(yōu)先級(jí)或者更高優(yōu)先級(jí)的任務(wù)正在運(yùn)行!

    阻塞態(tài)

    如果一個(gè)任務(wù)當(dāng)前正在等待某個(gè)外部事件的話就說它處于阻塞態(tài),比如說如果某個(gè)任務(wù)調(diào)用了函數(shù) vTaskDelay()的話就會(huì)進(jìn)入阻塞態(tài),直到延時(shí)周期完成。任務(wù)在等待隊(duì)列、信號(hào)量、事件組、通知或互斥信號(hào)量的時(shí)候也會(huì)進(jìn)入阻塞態(tài)。任務(wù)進(jìn)入阻塞態(tài)會(huì)有一個(gè)超時(shí)時(shí)間,當(dāng)超過這個(gè)超時(shí)時(shí)間任務(wù)就會(huì)退出阻塞態(tài),即使所等待的事件還沒有來臨!

    掛起態(tài)

    像阻塞態(tài)一樣,任務(wù)進(jìn)入掛起態(tài)以后也不能被調(diào)度器調(diào)用進(jìn)入運(yùn)行態(tài),但是進(jìn)入掛起態(tài)的任務(wù)沒有超時(shí)時(shí)間。任務(wù)進(jìn)入和退出掛起態(tài)通過調(diào)用函數(shù) vTaskSuspend()和 xTaskResume()。

    FreeRTOS實(shí)時(shí)操作系統(tǒng)多任務(wù)管理基礎(chǔ)知識(shí)有哪些

    任務(wù)優(yōu)先級(jí)

    每 個(gè) 任 務(wù) 都 可 以 分 配 一 個(gè) 從 0~(configMAX_PRIORITIES-1) 的 優(yōu) 先 級(jí) ,configMAX_PRIORITIES 在文件 FreeRTOSConfig.h 中有定義,前面我們講解 FreeRTOS 系統(tǒng)配置的時(shí)候已經(jīng)講過了。如果所使用的硬件平臺(tái)支持類似計(jì)算前導(dǎo)零這樣的指令(可以通過該指令選 擇 下 一 個(gè) 要 運(yùn) 行 的 任 務(wù) , Cortex-M 處 理 器 是 支 持 該 指 令 的 ) , 并 且 configUSE_PORT_OPTIMISED_TASK_SELECTION 也 設(shè) 置 為 了 1 , 那 么 宏configMAX_PRIORITIES 不能超過 32!也就是優(yōu)先級(jí)不能超過 32 級(jí)。其他情況下宏configMAX_PRIORITIES 可以為任意值,但是考慮到 RAM 的消耗,宏 configMAX_PRIORITIES最好設(shè)置為一個(gè)滿足應(yīng)用的最小值。

    優(yōu)先級(jí)數(shù)字越低表示任務(wù)的優(yōu)先級(jí)越低,0 的優(yōu)先級(jí)最低,configMAX_PRIORITIES-1 的優(yōu)先級(jí)最高??臻e任務(wù)的優(yōu)先級(jí)最低,為 0。

    FreeRTOS 調(diào)度器確保處于就緒態(tài)或運(yùn)行態(tài)的高優(yōu)先級(jí)的任務(wù)獲取處理器使用權(quán),換句話說就是處于就緒態(tài)的最高優(yōu)先級(jí)的任務(wù)才會(huì)運(yùn)行。當(dāng)宏 configUSE_TIME_SLICING 定義為 1 的時(shí)候多個(gè)任務(wù)可以共用一個(gè)優(yōu)先級(jí),數(shù)量不限。默認(rèn)情況下宏configUSE_TIME_SLICING 在文件FreeRTOS.h 中已經(jīng)定義為 1。此時(shí)處于就緒態(tài)的優(yōu)先級(jí)相同的任務(wù)就會(huì)使用時(shí)間片輪轉(zhuǎn)調(diào)度器獲取運(yùn)行時(shí)間。

    任務(wù)實(shí)現(xiàn)

    在使用 FreeRTOS 的過程中,我們要使用函數(shù) xTaskCreate()或 xTaskCreateStatic()來創(chuàng)建任務(wù),這兩個(gè)函數(shù)的第一個(gè)參數(shù)pxTaskCode,就是這個(gè)任務(wù)的任務(wù)函數(shù)。什么是任務(wù)函數(shù)?任務(wù)函數(shù)就是完成本任務(wù)工作的函數(shù)。我這個(gè)任務(wù)要干嘛?要做什么?要完成什么樣的功能都是在這個(gè)任務(wù)函數(shù)中實(shí)現(xiàn)的。 比如我要做個(gè)任務(wù),這個(gè)任務(wù)要點(diǎn)個(gè)流水燈,那么這個(gè)流水燈的程序就是任務(wù)函數(shù)中實(shí)現(xiàn)的。FreeRTOS 官方給出的任務(wù)函數(shù)模板如下:

    void vATaskFunction(void *pvParameters) 
    {
        for( ; ; ) 
        {
            //--任務(wù)應(yīng)用程序--
            vTaskDelay(); 
            /*此處不一定要用延時(shí)函數(shù),其他只要能讓 FreeRTOS 發(fā)生任務(wù)切換的 API 函數(shù)都可以,
            比如請(qǐng)求信號(hào)量、隊(duì)列等,甚至直接調(diào)用任務(wù)調(diào)度器。只不過最常用的就是 FreeRTOS 的延時(shí)函數(shù)。*/
        }
        /*不能從任務(wù)函數(shù)中返回或者退出,從任務(wù)函數(shù)中返回或退出的話就會(huì)調(diào)用
        configASSERT(),前提是你定義了 configASSERT()。如果一定要從任務(wù)函數(shù)中退出的話那一定
        要調(diào)用函數(shù) vTaskDelete(NULL)來刪除此任務(wù)。*/
        //vTaskDelete(NULL);  (5)
    }

    任務(wù)控制塊

    FreeRTOS 的每個(gè)任務(wù)都有一些屬性需要存儲(chǔ),F(xiàn)reeRTOS 把這些屬性集合到一起用一個(gè)結(jié)構(gòu)體來表示,這個(gè)結(jié)構(gòu)體叫做任務(wù)控制塊:TCB_t,在使用函數(shù) xTaskCreate()創(chuàng)建任務(wù)的時(shí)候就會(huì)自動(dòng)的給每個(gè)任務(wù)分配一個(gè)任務(wù)控制塊。在老版本的 FreeRTOS 中任務(wù)控制塊叫做 tskTCB,新版本重命名為 TCB_t,但是本質(zhì)上還是 tskTCB,本教程后面提到任務(wù)控制塊的話均用 TCB_t表示,此結(jié)構(gòu)體在文件 tasks.c 中有定義。 FreeRTOS 的任務(wù)控制塊中的成員變量相比 UCOSIII 要少很多,而且大多數(shù)與裁剪有關(guān),當(dāng)不使用某些功能的時(shí)候與其相關(guān)的變量就不參與編譯,任務(wù)控制塊大小就會(huì)進(jìn)一步的減小。

    typedef struct tskTaskControlBlock{    volatile StackType_t  *pxTopOfStack;  //任務(wù)堆棧棧頂    #if ( portUSING_MPU_WRAPPERS == 1 )        xMPU_SETTINGS xMPUSettings;  //MPU 相關(guān)設(shè)置    #endif    ListItem_t  xStateListItem;  //狀態(tài)列表項(xiàng)    ListItem_t  xEventListItem;  //事件列表項(xiàng)    UBaseType_t uxPriority;  //任務(wù)優(yōu)先級(jí)    StackType_t *pxStack;  //任務(wù)堆棧起始地址    char pcTaskName[ configMAX_TASK_NAME_LEN ];//任務(wù)名字    #if ( portSTACK_GROWTH > 0 )        StackType_t *pxEndOfStack;  //任務(wù)堆棧棧底    #endif    #if ( portCRITICAL_NESTING_IN_TCB == 1 )        UBaseType_t uxCriticalNesting; //臨界區(qū)嵌套深度    #endif    #if ( configUSE_TRACE_FACILITY == 1 ) //trace 或到 debug 的時(shí)候用到        UBaseType_t uxTCBNumber;         UBaseType_t uxTaskNumber;     #endif    #if ( configUSE_MUTEXES == 1 )        UBaseType_t uxBasePriority;  //任務(wù)基礎(chǔ)優(yōu)先級(jí),優(yōu)先級(jí)反轉(zhuǎn)的時(shí)候用到        UBaseType_t uxMutexesHeld;  //任務(wù)獲取到的互斥信號(hào)量個(gè)數(shù)    #endif    #if ( configUSE_APPLICATION_TASK_TAG == 1 )        TaskHookFunction_t pxTaskTag;    #endif    #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) //與本地存儲(chǔ)有關(guān)        void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];    #endif    #if( configGENERATE_RUN_TIME_STATS == 1 )        uint32_t ulRunTimeCounter;  //用來記錄任務(wù)運(yùn)行總時(shí)間    #endif    #if ( configUSE_NEWLIB_REENTRANT == 1 )        struct  _reent xNewLib_reent; //定義一個(gè) newlib 結(jié)構(gòu)體變量    #endif    #if( configUSE_TASK_NOTIFICATIONS == 1 ) //任務(wù)通知相關(guān)變量        volatile uint32_t ulNotifiedValue; //任務(wù)通知值        volatile uint8_t ucNotifyState;  //任務(wù)通知狀態(tài)    #endif    #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )        //用來標(biāo)記任務(wù)是動(dòng)態(tài)創(chuàng)建的還是靜態(tài)創(chuàng)建的,如果是靜態(tài)創(chuàng)建的此變量就為 pdTURE,        //如果是動(dòng)態(tài)創(chuàng)建的就為 pdFALSE         uint8_t  ucStaticallyAllocated;    #endif    #if( INCLUDE_xTaskAbortDelay == 1 )        uint8_t ucDelayAborted;    #endif} tskTCB;//新版本的 FreeRTOS 任務(wù)控制塊重命名為 TCB_t,但是本質(zhì)上還是 tskTCB,主要是為了兼容//舊版本的應(yīng)用。typedef tskTCB TCB_t;typedef struct tskTaskControlBlock
    {
        volatile StackType_t  *pxTopOfStack;  //任務(wù)堆棧棧頂
        #if ( portUSING_MPU_WRAPPERS == 1 )
            xMPU_SETTINGS xMPUSettings;  //MPU 相關(guān)設(shè)置
        #endif
        ListItem_t  xStateListItem;  //狀態(tài)列表項(xiàng)
        ListItem_t  xEventListItem;  //事件列表項(xiàng)
        UBaseType_t uxPriority;  //任務(wù)優(yōu)先級(jí)
        StackType_t *pxStack;  //任務(wù)堆棧起始地址
        char pcTaskName[ configMAX_TASK_NAME_LEN ];//任務(wù)名字
        #if ( portSTACK_GROWTH > 0 )
            StackType_t *pxEndOfStack;  //任務(wù)堆棧棧底
        #endif
        #if ( portCRITICAL_NESTING_IN_TCB == 1 )
            UBaseType_t uxCriticalNesting; //臨界區(qū)嵌套深度
        #endif
        #if ( configUSE_TRACE_FACILITY == 1 ) //trace 或到 debug 的時(shí)候用到
            UBaseType_t uxTCBNumber; 
            UBaseType_t uxTaskNumber; 
        #endif
        #if ( configUSE_MUTEXES == 1 )
            UBaseType_t uxBasePriority;  //任務(wù)基礎(chǔ)優(yōu)先級(jí),優(yōu)先級(jí)反轉(zhuǎn)的時(shí)候用到
            UBaseType_t uxMutexesHeld;  //任務(wù)獲取到的互斥信號(hào)量個(gè)數(shù)
        #endif
        #if ( configUSE_APPLICATION_TASK_TAG == 1 )
            TaskHookFunction_t pxTaskTag;
        #endif
        #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) //與本地存儲(chǔ)有關(guān)
            void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
        #endif
        #if( configGENERATE_RUN_TIME_STATS == 1 )
            uint32_t ulRunTimeCounter;  //用來記錄任務(wù)運(yùn)行總時(shí)間
        #endif
        #if ( configUSE_NEWLIB_REENTRANT == 1 )
            struct  _reent xNewLib_reent; //定義一個(gè) newlib 結(jié)構(gòu)體變量
        #endif
        #if( configUSE_TASK_NOTIFICATIONS == 1 ) //任務(wù)通知相關(guān)變量
            volatile uint32_t ulNotifiedValue; //任務(wù)通知值
            volatile uint8_t ucNotifyState;  //任務(wù)通知狀態(tài)
        #endif
        #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
            //用來標(biāo)記任務(wù)是動(dòng)態(tài)創(chuàng)建的還是靜態(tài)創(chuàng)建的,如果是靜態(tài)創(chuàng)建的此變量就為 pdTURE,
            //如果是動(dòng)態(tài)創(chuàng)建的就為 pdFALSE 
            uint8_t  ucStaticallyAllocated;
        #endif
        #if( INCLUDE_xTaskAbortDelay == 1 )
            uint8_t ucDelayAborted;
        #endif
    } tskTCB;
    //新版本的 FreeRTOS 任務(wù)控制塊重命名為 TCB_t,但是本質(zhì)上還是 tskTCB,主要是為了兼容
    //舊版本的應(yīng)用。
    typedef tskTCB TCB_t;

     任務(wù)堆棧

    FreeRTOS 之所以能正確的恢復(fù)一個(gè)任務(wù)的運(yùn)行就是因?yàn)橛腥蝿?wù)堆棧在保駕護(hù)航,任務(wù)調(diào)度器在進(jìn)行任務(wù)切換的時(shí)候會(huì)將當(dāng)前任務(wù)的現(xiàn)場(chǎng)(CPU 寄存器值等)保存在此任務(wù)的任務(wù)堆棧中,等到此任務(wù)下次運(yùn)行的時(shí)候就會(huì)先用堆棧中保存的值來恢復(fù)現(xiàn)場(chǎng),恢復(fù)現(xiàn)場(chǎng)以后任務(wù)就會(huì)接著從上次中斷的地方開始運(yùn)行。

    創(chuàng)建任務(wù)的時(shí)候需要給任務(wù)指定堆棧,如果使用的函數(shù) xTaskCreate()創(chuàng)建任務(wù)(動(dòng)態(tài)方法)的話那么任務(wù)堆棧就會(huì)由函數(shù) xTaskCreate()自動(dòng)創(chuàng)建,后面分析 xTaskCreate()的時(shí)候會(huì)講解。如果使用函數(shù) xTaskCreateStatic()創(chuàng)建任務(wù)(靜態(tài)方法)的話就需要程序員自行定義任務(wù)堆棧,然后堆棧首地址作為函數(shù)的參數(shù) puxStackBuffer 傳遞給函數(shù)。

    任務(wù)堆棧的數(shù)據(jù)類型為 StackType_t,StackType_t 本質(zhì)上是 uint32_t,在 portmacro.h 中有定義。所以 StackType_t 類型的變量為 4 個(gè)字節(jié),那么任務(wù)的實(shí)際堆棧大小就應(yīng)該是我們所定義的 4 倍。

    到此,相信大家對(duì)“FreeRTOS實(shí)時(shí)操作系統(tǒng)多任務(wù)管理基礎(chǔ)知識(shí)有哪些”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI