Please help me understand IDF FreeRTOS task usages.
I have wrote a function which monitors all of the running tasks and saves their stats to an Arduino Json Document.
(I'm using Arduino as a component of IDF with PlatformIO)
Here is the method which tracks and retrives task information
Code: Select all
void Sys::getTaskInfo(JsonObject& taskInfo) {
JsonArray taskList = taskInfo["taskList"].to<JsonArray>();
UBaseType_t uxArraySize;
TaskStatus_t* taskStatusArray;
uint32_t ulTotalRunTime, ulTaskRuntimePercentage;
uxArraySize = uxTaskGetNumberOfTasks();
taskStatusArray = (TaskStatus_t*)pvPortMalloc(uxArraySize * sizeof(TaskStatus_t));
if (taskStatusArray == NULL) {
return;
}
// Since CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER is set to true
// The clock uses the esp timer which is 1Mhz
// No convresion needed in this case, the time base is already in milliseconds
uxArraySize = uxTaskGetSystemState(taskStatusArray, uxArraySize, &ulTotalRunTime);
if (ulTotalRunTime > 0) {
taskInfo["totalRunTime"] = ulTotalRunTime;
for (UBaseType_t i = 0; i < uxArraySize; i++) {
JsonObject task = taskList.add<JsonObject>();
TaskStatus_t* taskStatus = &taskStatusArray[i];
// Convert task runtime to the same unit
uint32_t taskRunTime = taskStatus->ulRunTimeCounter;
uint64_t tempPercentage = (static_cast<uint64_t>(taskRunTime) * 100UL) / ulTotalRunTime;
ulTaskRuntimePercentage = static_cast<uint32_t>(tempPercentage);
// Store the task information
task["name"] = taskStatus->pcTaskName;
task["state"] = taskStatus->eCurrentState;
task["priority"] = taskStatus->uxCurrentPriority;
task["basePriority"] = taskStatus->uxBasePriority;
task["stackHighWaterMark"] = taskStatus->usStackHighWaterMark;
task["coreId"] = taskStatus->xCoreID;
task["number"] = taskStatus->xTaskNumber;
task["runTimeCounter"] = taskRunTime;
task["runTimePercent"] = ulTaskRuntimePercentage;
// Stack size can not be retrived from taskStatus. There is a separate logic for that.
task["stackSize"] = taskHandler.getStackSize(taskStatus->xHandle);
}
}
vPortFree(taskStatusArray);
}
This function is called every minute
Code: Select all
void Sys::getSysInfo(JsonDocument& info) {
JsonObject taskInfos = info["tasks"].to<JsonObject>();
getTaskInfo(taskInfos);
}
Here is some example results
Code: Select all
[
{
"name": "systemTask",
"state": 1,
"priority": 1,
"basePriority": 1,
"stackHighWaterMark": 13296,
"coreId": 0,
"number": 10,
"runTimeCounter": 41724638,
"runTimePercent": 2,
"stackSize": 16384
},
{
"name": "IDLE",
"state": 1,
"priority": 0,
"basePriority": 0,
"stackHighWaterMark": 912,
"coreId": 1,
"number": 6,
"runTimeCounter": 1624700697,
"runTimePercent": 87,
"stackSize": 0
},
{
"name": "IDLE",
"state": 1,
"priority": 0,
"basePriority": 0,
"stackHighWaterMark": 940,
"coreId": 0,
"number": 5,
"runTimeCounter": 1579542035,
"runTimePercent": 84,
"stackSize": 0
},
{
"name": "loopTask",
"state": 2,
"priority": 1,
"basePriority": 1,
"stackHighWaterMark": 12504,
"coreId": 1,
"number": 8,
"runTimeCounter": 109263130,
"runTimePercent": 5,
"stackSize": 0
}
]
For some reason I have TWO IDLE tasks and they both at 84%.
Couple of questions.
- Why is there two IDLE tasks? ( one for each core? )
- Why is the IDLE task get more time than my other tasks?
- Please explain the following tasks, what they do and why are they there.
- tiT
- Tmr Svc
- ipc0
- ipc1
- emac_rx
- sys_evt