Browse Source

esp32/modesp32: Implement idf_task_stats().

Signed-off-by: Daniël van de Giessen <daniel@dvdgiessen.nl>
pull/12732/head
Daniël van de Giessen 3 years ago
parent
commit
5842015eb2
No known key found for this signature in database GPG Key ID: 9F0EF4D3441C8163
  1. 22
      docs/library/esp32.rst
  2. 36
      ports/esp32/modesp32.c

22
docs/library/esp32.rst

@ -80,6 +80,28 @@ Functions
The result of :func:`gc.mem_free()` is the total of the current "free"
and "max new split" values printed by :func:`micropython.mem_info()`.
.. function:: idf_task_stats()
Returns information about running ESP-IDF/FreeRTOS tasks, which include
MicroPython threads. This data is useful to gain insight into how much time
tasks spend running or if they are blocked for significant parts of time,
and to determine if allocated stacks are fully utilized or might be reduced.
``CONFIG_FREERTOS_USE_TRACE_FACILITY=y`` must be set in the board
configuration to make this method available. Additionally setting
``CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y`` and
``CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y`` is recommended to be able to
retrieve the core id and runtime respectively.
The return value is a 2-tuple where the first value is the total runtime,
and the second a list of tasks. Each task is a 7-tuple containing: the task
name, ID, current state, priority, runtime, stack high water mark, and the
ID of the core it is running on.
.. note:: For an easier to use output based on this function you can use the
`utop library <https://github.com/micropython/micropython-lib/tree/master/micropython/utop>`,
which implements a live overview similar to the Unix ``top`` command.
Flash partitions
----------------

36
ports/esp32/modesp32.c

@ -212,6 +212,39 @@ static mp_obj_t esp32_idf_heap_info(const mp_obj_t cap_in) {
}
static MP_DEFINE_CONST_FUN_OBJ_1(esp32_idf_heap_info_obj, esp32_idf_heap_info);
#if CONFIG_FREERTOS_USE_TRACE_FACILITY
static mp_obj_t esp32_idf_task_stats(void) {
const size_t task_count_max = uxTaskGetNumberOfTasks();
TaskStatus_t *task_array = m_new(TaskStatus_t, task_count_max);
uint32_t total_time;
const size_t task_count = uxTaskGetSystemState(task_array, task_count_max, &total_time);
mp_obj_t task_list = mp_obj_new_list(0, 0);
for (size_t i = 0; i < task_count; i++) {
mp_obj_t task_data[] = {
mp_obj_new_str(task_array[i].pcTaskName, strlen(task_array[i].pcTaskName)),
mp_obj_new_int_from_uint(task_array[i].xTaskNumber),
MP_OBJ_NEW_SMALL_INT(task_array[i].eCurrentState),
MP_OBJ_NEW_SMALL_INT(task_array[i].uxCurrentPriority),
mp_obj_new_int_from_uint(task_array[i].ulRunTimeCounter),
mp_obj_new_int_from_uint(task_array[i].usStackHighWaterMark),
#if CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
MP_OBJ_NEW_SMALL_INT(task_array[i].xCoreID),
#else
mp_const_none,
#endif
};
mp_obj_t task = mp_obj_new_tuple(7, task_data);
mp_obj_list_append(task_list, task);
}
m_del(TaskStatus_t, task_array, task_count_max);
mp_obj_t task_stats[] = { MP_OBJ_NEW_SMALL_INT(total_time), task_list };
return mp_obj_new_tuple(2, task_stats);
}
static MP_DEFINE_CONST_FUN_OBJ_0(esp32_idf_task_stats_obj, esp32_idf_task_stats);
#endif
static const mp_rom_map_elem_t esp32_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp32) },
@ -226,6 +259,9 @@ static const mp_rom_map_elem_t esp32_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_mcu_temperature), MP_ROM_PTR(&esp32_mcu_temperature_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_idf_heap_info), MP_ROM_PTR(&esp32_idf_heap_info_obj) },
#if CONFIG_FREERTOS_USE_TRACE_FACILITY
{ MP_ROM_QSTR(MP_QSTR_idf_task_stats), MP_ROM_PTR(&esp32_idf_task_stats_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_NVS), MP_ROM_PTR(&esp32_nvs_type) },
{ MP_ROM_QSTR(MP_QSTR_Partition), MP_ROM_PTR(&esp32_partition_type) },

Loading…
Cancel
Save