freertos定位问题常用调试信息(内存、任务、信号量)
使用freertos 程序运行出现问题,有时需要输出一些信息辅助定位问题,整理了一下相关的调试接口。
堆栈情况查看
xPortGetFreeHeapSize
查看当前还有多少空闲内存,判断是否内存不够导致程序无法运行,这函数可以用来优化内存的使用情况。比如当所有内核对象都分配好后,执行此函数返回2000,那么configTOTAL_HEAP_SIZE就可减小2000。
size_t xPortGetFreeHeapSize( void )
{
return xFreeBytesRemaining;//返回单位为字节
}
xPortGetMinimumEverFreeHeapSize
返回:程序运行过程中,空闲内存容量的最小值。
注意:只有heap_4、heap_5支持此函数。
size_t xPortGetMinimumEverFreeHeapSize( void )
{
return xMinimumEverFreeBytesRemaining;//返回单位为字节
}
uxTaskGetStackHighWaterMark( TaskHandle_t xTask )
检查任务从创建好到现在的历史剩余最小值,这个值越小说明任务堆栈溢出的可能性就越大!FreeRTOS 把这个历史剩余最小值叫做“高水位线”。
#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )//参数为要查询的任务,NULL时则查本任务
{
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;//返回值单位为字,32位机器即为4字节
}
#endif
任务相关
vTaskGetCpuLoadStats
vTaskGetCpuLoadStats()调用uxTaskGetSystemState(),然后格式化为的表,以百分比形式显示每个任务在运行状态中花费的时间(0.1s/1s/10s)。
sprintf(pBuf, "\r\nTask-----------0.1s------1s-----10s\r\n");
len = strlen(pBuf);
FreeRTOS_write(hSerialPort0, pBuf, len);
vTaskGetCpuLoadStats(pBuf);
len = strlen(pBuf);
FreeRTOS_write(hSerialPort0, pBuf, len);
vTaskGetRunTimeStats
vTaskGetRunTimeStats()调用uxTaskGetSystemState(),然后格式化为可读的表,以绝对数值和百分比的形式显示每个任务在运行状态中花费的时间量。
sprintf(pBuf, "\r\nTask------------------------Abs time---------%% Time\r\n");
len = strlen(pBuf);
FreeRTOS_write(hSerialPort0, pBuf, len);
vTaskGetRunTimeStats(pBuf);
len = strlen(pBuf);
FreeRTOS_write(hSerialPort0, pBuf, len);
vTaskList
vTaskList()调用uxTaskGetSystemState(),然后格式化为可读的表,显示任务名称、状态和堆栈使用情况。
sprintf(pBuf, "\r\nTask---------State---Priority---Stack---Num\r\n");
len = strlen(pBuf);
FreeRTOS_write(hSerialPort0, pBuf, len);
vTaskList(pBuf);
len = strlen(pBuf);
FreeRTOS_write(hSerialPort0, pBuf, len);
//vTaskList中格式化的字符串
sprintf( pcWriteBuffer, "\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber );
队列
uxQueueMessagesWaiting返回队列已用量
uxQueueSpacesAvailable返回队列剩余量
信号量
uxSemaphoreGetCount返回信号量计数值,实际调用uxQueueMessagesWaiting
//如果信号量是一个计数信号量,那么uxSemaphoreGetCount()返回当前的计数值。如果信号量是二进制信号量,则uxSemaphoreGetCount()返回1(信号量可用),返回0(信号量不可用)。
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
xSemaphoreGetMutexHolder返回信号量持有者,返回值为Task control block结构体TaskHandle_t
//如果xMutex确实是一个互斥锁类型信号量,返回当前的互斥锁持有者。
//如果xMutex不是互斥锁类型信号量,或者互斥锁是可用的(不被任务持有),返回NULL
#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
更多推荐
所有评论(0)