RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

任務(wù)堆棧的檢測方法

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

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

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

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

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

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

打開 FreeRTOSConfig.h 文件,找到宏

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

#define INCLUDE_uxTaskGetStackHighWaterMark     1

這個宏定義為 1 之后再文件 task.c 中就可以看到函數(shù) uxTaskGetStackHighWaterMark 生效了,說明這個函數(shù)已經(jīng)是可以使用的狀態(tài)了。

2、uxTaskGetStackHighWaterMark 函數(shù)的說明

freeRTOS 中任務(wù)堆棧的檢測函數(shù)的函數(shù)原型如下:

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;
    }

函數(shù)描述:

函數(shù)參數(shù):

xTask:需要檢查的堆棧情況的任務(wù)句柄。這個句柄在創(chuàng)建任務(wù)時就可以知道的。

注意:將 xTask 設(shè)置為 NULL 的話檢測的就是調(diào)用這個函數(shù)的任務(wù)堆棧情況。

函數(shù)返回值:

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

特別注意:

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

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

3.1、任務(wù)自己檢測自己的堆棧情況

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

void vTask1( void * pvParameters )
{
    UBaseType_t uxHighWaterMark;

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

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

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

3.2、使用任務(wù)單獨(dú)檢測任務(wù)的堆棧情況

可以使用一個任務(wù)單獨(dú)進(jìn)行項(xiàng)目中的任務(wù)堆棧的情況進(jìn)行檢測,如下:

void TaskStackDetect_Task1( void * pvParameters )
{
    UBaseType_t uxHighWaterMark;

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

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

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

         ......

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

         vTaskDelay( 1000 );
     }
 }

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

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

void TaskStackDetect_Callback(TimerHandle_t pxTimer)
{
    UBaseType_t uxHighWaterMark;

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

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

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

         ......

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

    關(guān)注

    0

    文章

    182

    瀏覽量

    19753
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    484

    瀏覽量

    62139
  • 空間
    +關(guān)注

    關(guān)注

    2

    文章

    48

    瀏覽量

    13629
收藏 人收藏

    評論

    相關(guān)推薦

    uCOS任務(wù)堆棧的深入分析

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

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

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

    任務(wù)控制塊和任務(wù)堆棧的關(guān)系是什么?

    學(xué)完,發(fā)現(xiàn)自己最基本的概念都不清楚啊。任務(wù)控制塊和任務(wù)堆棧在ram上是兩個獨(dú)立的區(qū)域?qū)??所有的系統(tǒng)API函數(shù)的操作都是針對TCB的,或者通過TCB對堆棧進(jìn)行控制?系統(tǒng)中那部分內(nèi)容,是
    發(fā)表于 04-20 23:56

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

    用OSTaskStkChk函數(shù)檢測堆棧的使用情況,發(fā)現(xiàn)有兩個任務(wù)使用情況為100%,堆棧設(shè)置為1024,增大堆棧到2048,依然使用率100
    發(fā)表于 04-20 22:56

    FreeRTOS中的任務(wù)堆棧溢出檢測機(jī)制

    合理的任務(wù)堆棧大小,并實(shí)際運(yùn)行程序進(jìn)行測試,來確保系統(tǒng)運(yùn)行過程中不會發(fā)生堆棧溢出。FreeRTOS中的任務(wù)堆棧溢出
    發(fā)表于 10-15 13:51

    堆棧的定義與任務(wù)

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

    任務(wù)堆棧是什么意思

    店里的兩個不同位置做,那么這個兩個位置就比喻為每個任務(wù)的“工作場所”——即任務(wù)堆棧。在uC/OS-III中,每個任務(wù)都像我們以前寫的函數(shù)類似,其結(jié)構(gòu)為://
    發(fā)表于 12-16 06:12

    如何設(shè)置應(yīng)用任務(wù)堆棧大???

    想到的就是堆棧大小不足。但任務(wù)所需的堆棧大小與具體應(yīng)用相關(guān),如何確定任務(wù)堆棧的大?。俊瘛瘛瘛瘛瘛瘛?通過分析
    發(fā)表于 06-08 15:11

    任務(wù)系統(tǒng)中的堆棧使用

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

    freertos怎么查看任務(wù)堆棧的大?。?/a>

    要通過什么方法來獲取當(dāng)前任務(wù)堆棧大小
    發(fā)表于 10-12 08:01

    ucosiii堆棧檢測函數(shù)運(yùn)用的小疑問求解

    附上堆棧檢測函數(shù)的代碼 #defineUsage_STK_SIZE128u //統(tǒng)計(jì)任務(wù) #defineIWDG_STK_SIZE64u//看門狗任務(wù) m data-ke->
    發(fā)表于 10-19 06:47

    關(guān)于FreeRTOS創(chuàng)建任務(wù)時的堆棧問題

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

    深入分析uCOS的任務(wù)堆棧

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

    RTOS任務(wù)堆棧大小與代碼量有啥關(guān)系嗎?

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

    任務(wù)系統(tǒng)中的堆棧使用

    不同的微控制器棧的實(shí)現(xiàn)也不同,許多32位處理器支持多個棧。例如,ARM Cortex-M內(nèi)核有兩個棧指針,分別指向主棧和進(jìn)程棧。在基于μC/OS-III的應(yīng)用中,多任務(wù)開始前使用主堆棧,其空間為鏈接命令文件中定義的堆棧區(qū)域。
    的頭像 發(fā)表于 12-02 11:15 ?806次閱讀
    RM新时代网站-首页