1. 程式人生 > 其它 >FreeRtos原始碼分析之vTaskList和vTaskGetRunTimeStats等除錯函式(五)

FreeRtos原始碼分析之vTaskList和vTaskGetRunTimeStats等除錯函式(五)

技術標籤:筆記

一、概述

在使用FreeRtos進行開發的過程中,我們通常需要了解系統的執行狀態、記憶體、CPU使用情況等資訊,來確保系統能夠長期穩定的執行。FreeRtos提供了許多這樣的介面,我們也可以通過閱讀FreeRtos相關的原始碼自己編寫需要的Debug介面。
通常我們需要用到的一些系統資訊為:

  • 當前任務的剩餘記憶體;
  • 當前任務歷史最小記憶體;
  • 系統總的剩餘記憶體;
  • 系統執行的總時間;
  • 單個任務的執行時間;
  • 每個任務佔用的CPU時間;

二、獲取系統資訊的相關函式

2.1、vTaskList

函式原型:void vTaskList( char * pcWriteBuffer );
函式功能:獲取系統中所有任務的任務名、任務狀態、優先順序、最小剩餘堆疊、建立序號相關資訊;

使用示例:

void PrintSysInfo(void)
{
    char *buf = NULL;
    char *fmt = "======================================\r\n\
name\tstatus\tpri\tmin-stack\tnum\r\n\
======================================\r\n";
    buf = pvPortMalloc(512);
    if(NULL == buf)return;
    
    sprintf(buf,"%s"
,fmt); vTaskList(buf+strlen(fmt)); d_printf("%s\r\n",buf); vPortFree(buf); }

列印結果:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-0watrBnC-1612168202907)(en-resource://database/622:1)]
status表示任務的執行狀態,有五種:

  • x 執行狀態
  • R Redy就緒狀態
  • B Block阻塞狀態
  • S Suspend掛起狀態
  • D Deletedr任務已經被刪除

min-stack表示系統歷史剩餘最小堆疊,單位是字,比如33表示33*4=132byte。這個值越接近於0,任務記憶體溢位的可能性就越大;FreeRtos在建立任務的時候會將分配給任務的記憶體全部初始化為0xa5,如果某段記憶體被使用過,那麼其中的值就會被改變,FreeRtos獲取記憶體剩餘空間的原始碼如下:

    static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte )
    {
        uint32_t ulCount = 0U;
        /*任務的記憶體在任務建立時會被填充為tskSTACK_FILL_BYTE,在任務執行時會被填充為其它內容*/
        while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE )
        {
            pucStackByte -= portSTACK_GROWTH;
            ulCount++;
        }
        /*返回值的單位為字而不是位元組*/
        ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */
        
        return ( configSTACK_DEPTH_TYPE ) ulCount;
    }

num表示任務建立的序號,一般按照任務的建立順序編號。

2.2、vTaskGetRunTimeStats

函式原型: void vTaskGetRunTimeStats( char * pcWriteBuffer );
函式功能:獲取每個任務的執行時間,並統計每個任務佔用CPU的時間;
示例:

void PrintSysTimeInfo(void)
{
#if configGENERATE_RUN_TIME_STATS
    char *buf = NULL;
    char *fmt = "======================================\r\n\
任務名\t執行時間\tcpu佔用率\r\n\
======================================\r\n";
    buf = pvPortMalloc(512);
    if(NULL == buf)return;
    
    sprintf(buf,"%s",fmt);
    vTaskGetRunTimeStats(buf+strlen(fmt));
    d_printf("%s\r\n",buf);
    vPortFree(buf);
#endif
}

列印結果:
在這裡插入圖片描述
從結果中可以看出,系統中一共有四個任務,其中空閒任務IDLE執行的時間最長,為10902ms,佔用了98%的CPU執行時間。

FreeRtos預設是不支援這個功能的,如果想要使用這個功能,就需要自己使用硬體定時器來實現。使用前應該實現以下三個巨集:

#define configGENERATE_RUN_TIME_STATS	1//開啟執行時間統計功能
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS configureTimerForRunTimeStats//初始化硬體定時器
#define portGET_RUN_TIME_COUNTER_VALUE getRunTimeCounterValue//獲取定時器的計數值

2.3、uxTaskGetStackHighWaterMark

函式原型:UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
函式功能:獲取指定任務歷史最小剩餘堆疊,返回的值越小,任務越容易記憶體溢位

2.4、eTaskGetState

函式原型:eTaskState eTaskGetState( TaskHandle_t xTask );
函式功能:獲取任務狀態

2.5、uxTaskPriorityGet

函式原型:UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask )
函式功能:獲取任務優先順序

2.6、xTaskGetTickCount

函式原型:TickType_t xTaskGetTickCount( void )
函式功能:獲取任務的系統節拍數,使用者可以根據這個值計算系統執行的總時間,但是需要注意TickType_t的資料型別,當系統時鐘節拍是1ms時,系統執行一個多月後時間會溢位。

2.7、uxTaskGetTaskNumber

函式原型:UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask )
函式功能:獲取任務建立的序號,任務在建立時通常會按照建立順序給任務一個編碼,比如第一個建立的任務序號為1,第二個為2,以此類推。這個值也可以通過vTaskSetTaskNumber函式來修改。
FreeRtos帶註釋原始碼Gitee地址:https://gitee.com/zBlackShadow/FreeRtos10.4.3.git