How to get the total and current stack use for tasks

Leherenn
Posts: 6
Joined: Tue Mar 24, 2020 3:11 pm

How to get the total and current stack use for tasks

Postby Leherenn » Tue May 05, 2020 3:19 pm

I am implementing a diagnostic function, which aims at printing informations about the system, like all the current tasks, their run time and so on.
Something like: `{"current remaining heap":30492,"heap watermark":29180,"tasks":[{"name":"HTTPD Server","status":"Running","runtime":6042,"percentage":0,"stack":???,"priority":5,"watermark":3168,"stack currently used":???},...]}`

There's the handy function `uxTaskGetSystemState` for most of those informations.
I am however looking to add the task total stack size, and the current use (not the watermark).

`uxTaskGetSnapshotAll` provides pointers to the top (current) and end of the stack for each task. Combined with the base of the stack available with `uxTaskGetSystemState`, it should be possible to compute those values using a bit of pointer arithmetic.
The problem is that I cannot find how to link those two structures, `TaskSnapshot_t` being pretty bare bone.

Is there a way to link those structures, or any other way to get this information?

ESP_igrr
Posts: 2067
Joined: Tue Dec 01, 2015 8:37 am

Re: How to get the total and current stack use for tasks

Postby ESP_igrr » Tue May 05, 2020 9:22 pm

Hi Leherenn,

The first member of TaskSnapshot_t structure, pxTCB, has the same meaning as the first member of TaskStatus_t, xHandle — both are task handles, or pointers to the task control block. You can use this field to match between TaskSnapshot_t and TaskStatus_t lists.

Leherenn
Posts: 6
Joined: Tue Mar 24, 2020 3:11 pm

Re: How to get the total and current stack use for tasks

Postby Leherenn » Wed May 06, 2020 3:24 pm

Thank you.
For reference, if it can help someone in the future, I did something like this to link both structures:

Code: Select all

static const TaskSnapshot_t *find_snapshot_linked_to_status(const TaskStatus_t *taskStatus,
                                                            const TaskSnapshot_t *taskSnapshotArray,
                                                            size_t taskSnapshotArraySize) {
  for (size_t i = 0; i < taskSnapshotArraySize; ++i) {
    if (*(int*)taskSnapshotArray[i].pxTCB == *(int*)taskStatus->xHandle) {
      return &taskSnapshotArray[i];
    }
  }

  return NULL;
}
However, `pxStackBase` in `TaskStatus_t` does not seem to be assigned, I get random values, and `prvListTaskWithinSingleList` in task.c does not assign it. It does not look like it is behind a config flag either.
If I add `pxTaskStatusArray[ uxTask ].pxStackBase = pxNextTCB->pxStack;` in `prvListTaskWithinSingleList` then it is working as expected.
Is that a bug, or on purpose?

Lastly, if I do `abs(base - end)`, I am off by 4 bytes.
Is it because at the very bottom there is the current stack pointer, and `end` points right above it?

Who is online

Users browsing this forum: eriksl, Google [Bot], MicroController and 133 guests