<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

任務堆棧的檢測方法

汽車電子技術 ? 來源:嵌入式之入坑筆記 ? 作者:嵌入式之入坑筆記 ? 2023-02-10 14:11 ? 次閱讀

使用freeRTOS時,創建的每一個任務都需要分配任務的堆??臻g,這些堆??臻g一般都是使用者根據任務的情況大致分配的。使用者往往不能直接知道分配的任務堆??臻g是否足夠任務運行使用,有時候可能會不夠,在運行過程中就出現了堆棧溢出,導致程序出現各種各樣的奇怪問題,出現問題之后可能一時半會還難以找出來。

這種情況如果能有一種檢測手段能夠知道任務在運行過程中堆棧的使用情況或者剩余情況,那就可以很好的把握任務堆棧的情況,也可以在一開始就避免堆棧溢出這樣的問題發生,將來項目產品上線了也避免了這樣的風險存在!

值得開心的是,freeRTOS真的有提供這樣的檢測堆棧剩余量的功能。下面介紹怎么使用freeRTOS的任務堆棧的剩余量的方法。

1、允許堆棧檢測 API 的使用

freeRTOS中堆棧使用剩余量的檢測使用的是 uxTaskGetStackHighWaterMark ,使用這個函數需要先將一個宏定義為 1 才能使用堆棧檢測功能。

打開 FreeRTOSConfig.h 文件,找到宏

INCLUDE_uxTaskGetStackHighWaterMark 并將其值定為 1,如下:

#define INCLUDE_uxTaskGetStackHighWaterMark     1

這個宏定義為 1 之后再文件 task.c 中就可以看到函數 uxTaskGetStackHighWaterMark 生效了,說明這個函數已經是可以使用的狀態了。

2、uxTaskGetStackHighWaterMark 函數的說明

freeRTOS 中任務堆棧的檢測函數的函數原型如下:

UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )
    {
        TCB_t * pxTCB;
        uint8_t * pucEndOfStack;
        UBaseType_t uxReturn;


        pxTCB = prvGetTCBFromHandle( xTask );


        #if portSTACK_GROWTH < 0
            {
                pucEndOfStack = ( uint8_t * ) pxTCB->pxStack;
            }
        #else
            {
                pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack;
            }
        #endif


        uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack );


        return uxReturn;
    }

函數描述:

函數參數:

xTask:需要檢查的堆棧情況的任務句柄。這個句柄在創建任務時就可以知道的。

注意:將 xTask 設置為 NULL 的話檢測的就是調用這個函數的任務堆棧情況。

函數返回值:

自創建 xTask 這個任務以來,已存在的最小可用堆??臻g量(以字為單位)。即返回的值是以字為單位的堆棧剩余量(例如,在 32 位機器上,返回值 1 表示任務堆棧中未使用的堆棧還剩余 4 個字節)。如果返回值為零,則該任務可能堆棧已經溢出。如果返回值接近零,則任務接近堆棧溢出。

特別注意:

freeRTOS中還有一個 uxTaskGetStackHighWaterMark2() ,這個是 uxTaskGetStackHighWaterMark() 的另外一個版本,它返回一個用戶可定義的類型,主要用在一些 8 位架構上數據類型寬度有限制的MCU中。

3、堆棧剩余量檢測的使用方法

3.1、任務自己檢測自己的堆棧情況

如果 UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) 的參數 xTask 設置為NULL,則哪個任務調用這個函數檢測的就是哪個任務的堆棧情況,如下:

void vTask1( void * pvParameters )
{
    UBaseType_t uxHighWaterMark;

   // 檢測任務使用前的堆棧情況
    uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );

    for( ;; )
     {
         ...    // 其他代碼
         ...
         ...
         vTaskDelay( 1000 );

         // 檢測任務運行之后的堆棧剩余情況
         uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
     }
 }

3.2、使用任務單獨檢測任務的堆棧情況

可以使用一個任務單獨進行項目中的任務堆棧的情況進行檢測,如下:

void TaskStackDetect_Task1( void * pvParameters )
{
    UBaseType_t uxHighWaterMark;

    for( ;; )
     {
         uxHighWaterMark = uxTaskGetStackHighWaterMark( 任務句柄1 );
         print(uxHighWaterMark);

         uxHighWaterMark = uxTaskGetStackHighWaterMark( 任務句柄2 );
         print(uxHighWaterMark);

         uxHighWaterMark = uxTaskGetStackHighWaterMark( 任務句柄3 );
         print(uxHighWaterMark);

         ......

         uxHighWaterMark = uxTaskGetStackHighWaterMark( 任務句柄n );
         print(uxHighWaterMark);

         vTaskDelay( 1000 );
     }
 }

3.3、使用軟件定時器檢測任務堆棧的情況

檢測堆棧的剩余情況也可以使用freeRTOS中提供的軟件定時器服務,創建一個軟件定時器,然后在軟件定時器的回調函數里面定時進行檢測即可,原理和使用一個任務檢測是一樣的。如下:

void TaskStackDetect_Callback(TimerHandle_t pxTimer)
{
    UBaseType_t uxHighWaterMark;

    uxHighWaterMark = uxTaskGetStackHighWaterMark( 任務句柄1 );
    print(uxHighWaterMark);

    uxHighWaterMark = uxTaskGetStackHighWaterMark( 任務句柄2 );
    print(uxHighWaterMark);

    uxHighWaterMark = uxTaskGetStackHighWaterMark( 任務句柄3 );
    print(uxHighWaterMark);

         ......

    uxHighWaterMark = uxTaskGetStackHighWaterMark( 任務句柄n );
    print(uxHighWaterMark);
}
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 堆棧
    +關注

    關注

    0

    文章

    171

    瀏覽量

    19595
  • FreeRTOS
    +關注

    關注

    12

    文章

    474

    瀏覽量

    61443
  • 空間
    +關注

    關注

    2

    文章

    48

    瀏覽量

    13540
收藏 人收藏

    評論

    相關推薦

    uCOS任務堆棧的深入分析

    在uCOS中,每一個任務都有一個獨立的任務堆棧。為了深入理解任務堆棧的作用,不妨分析任務從“出生
    發表于 11-01 11:52 ?3131次閱讀

    詳解μC/OS-II如何檢測任務堆棧實際使用情況——即如何設置ucosii任務堆棧大小

    :OSTaskStkChk()不錯,檢測任務堆棧實際使用情況正是用的這個函數,下面來本函數的接口原型:INT8U OSTaskStkChk(INT8U prio, //待測任務的優先級
    發表于 09-23 17:00

    任務控制塊和任務堆棧的關系是什么?

    學完,發現自己最基本的概念都不清楚啊。任務控制塊和任務堆棧在ram上是兩個獨立的區域對嗎?所有的系統API函數的操作都是針對TCB的,或者通過TCB對堆棧進行控制?系統中那部分內容,是
    發表于 04-20 23:56

    ucosiii堆棧使用情況檢測使用率100%?

    用OSTaskStkChk函數檢測堆棧的使用情況,發現有兩個任務使用情況為100%,堆棧設置為1024,增大堆棧到2048,依然使用率100
    發表于 04-20 22:56

    FreeRTOS中的任務堆棧溢出檢測機制

    合理的任務堆棧大小,并實際運行程序進行測試,來確保系統運行過程中不會發生堆棧溢出。FreeRTOS中的任務堆棧溢出
    發表于 10-15 13:51

    堆棧的定義與任務

    任務堆棧堆棧定義:在存儲器中按數據“后進先出(LIFO)”的原則組織的連續存儲空間。堆棧大小計算: TASK_STK_SIZE * sizeof(OS_STK)
    發表于 12-16 07:45

    如何設置應用任務堆棧大???

    想到的就是堆棧大小不足。但任務所需的堆棧大小與具體應用相關,如何確定任務堆棧的大???●●●●●●● 通過分析
    發表于 06-08 15:11

    任務系統中的堆棧使用

    在使用μC/OS的多任務應用程序中,main()啟動后首先使用系統C棧,在OS啟動后使用任務棧?;讦藽/OS-II或μC/OS-III編寫應用代碼時,用戶必須為每個任務聲明一個堆棧,
    發表于 01-05 13:52

    freertos怎么查看任務堆棧的大???

    要通過什么方法來獲取當前任務堆棧大小
    發表于 10-12 08:01

    ucosiii堆棧檢測函數運用的小疑問求解

    附上堆棧檢測函數的代碼 #defineUsage_STK_SIZE128u //統計任務 #defineIWDG_STK_SIZE64u//看門狗任務 m data-ke->
    發表于 10-19 06:47

    關于FreeRTOS創建任務時的堆棧問題

    usStackDepth指定堆棧大小。 請問,這個堆棧是用來干什么的? 是任務中分配的局部變量放在這個堆棧里嗎? 或者是任務切換過程中保存局
    發表于 10-31 08:08

    μC OS-II 任務棧處理的一種改進方法

    在μC/OS-II 內核中,各個不同的任務使用獨立的堆棧空間,堆棧的大小按每個任務所需要的最大堆棧深度來定義,這種
    發表于 05-15 13:46 ?14次下載

    深入分析uCOS的任務堆棧

    堆棧作用的就是用來保存局部變量,從本質上講也就是將CPU寄存器的值保存到RAM中。在uCOS中,每一個任務都有一個獨立的任務堆棧。為了深入理解任務
    發表于 12-01 01:25 ?586次閱讀

    RTOS任務堆棧大小與代碼量有啥關系嗎?

    需要提前分配堆棧大小,也就是在創建任務的時候分配好堆棧的大小。 比如uCOS創建一個檢測(Check)任務: //
    的頭像 發表于 05-26 09:34 ?1914次閱讀

    任務系統中的堆棧使用

    不同的微控制器棧的實現也不同,許多32位處理器支持多個棧。例如,ARM Cortex-M內核有兩個棧指針,分別指向主棧和進程棧。在基于μC/OS-III的應用中,多任務開始前使用主堆棧,其空間為鏈接命令文件中定義的堆棧區域。
    的頭像 發表于 12-02 11:15 ?606次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>