From e21f8c764624e11e03d52e12cb62c4e8b9afcdc0 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 13 Dec 2024 08:46:19 +0000 Subject: [PATCH] Add `TaskStat::setOutput` (#2923) This PR supports switching the output of TaskStat at runtime. This allows monitoring of freeRTOS task usage for esp32 devices. Useful for switching output between standard serial and USB serial. --- .../Esp32/Services/Profiling/TaskStat.cpp | 23 +++++++++++-------- .../Esp8266/Services/Profiling/TaskStat.cpp | 4 ++-- .../Arch/Host/Services/Profiling/TaskStat.cpp | 4 ++-- .../Rp2040/Services/Profiling/TaskStat.cpp | 4 ++-- Sming/Services/Profiling/TaskStat.h | 10 +++++++- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/Sming/Arch/Esp32/Services/Profiling/TaskStat.cpp b/Sming/Arch/Esp32/Services/Profiling/TaskStat.cpp index ddc127cd17..7042e433e7 100644 --- a/Sming/Arch/Esp32/Services/Profiling/TaskStat.cpp +++ b/Sming/Arch/Esp32/Services/Profiling/TaskStat.cpp @@ -27,7 +27,7 @@ struct TaskStat::Info { #endif }; -TaskStat::TaskStat(Print& out) : out(out) +TaskStat::TaskStat(Print& out) : out(&out) { #if CONFIG_FREERTOS_USE_TRACE_FACILITY && CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS taskInfo = std::make_unique(2); @@ -38,13 +38,16 @@ TaskStat::~TaskStat() = default; bool TaskStat::update() { + if(!out) { + return false; + } #if CONFIG_FREERTOS_USE_TRACE_FACILITY && CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS // Get current task states auto& info = taskInfo[endIndex]; info.count = uxTaskGetSystemState(info.status, maxTasks, &info.runTime); if(info.count == 0) { - out.println(_F("[TaskStat] uxTaskGetSystemState returned 0")); + out->println(_F("[TaskStat] uxTaskGetSystemState returned 0")); return false; } @@ -79,7 +82,7 @@ bool TaskStat::update() // Calculate totalElapsedTime in units of run time stats clock period. uint32_t totalElapsedTime = endInfo.runTime - startInfo.runTime; if(totalElapsedTime == 0) { - out.println(_F("[TaskStat] Run time was 0: Have you set CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS?")); + out->println(_F("[TaskStat] Run time was 0: Have you set CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS?")); return false; } @@ -87,8 +90,8 @@ bool TaskStat::update() PSTR_ARRAY(hdrfmt, "# | Core | Prio | Handle | Run Time | % Time | Name"); PSTR_ARRAY(datfmt, "%-3u | %c | %4u | %08x | %8u | %3u%% | %s\r\n"); - out.println(); - out.println(hdrfmt); + out->println(); + out->println(hdrfmt); // Match each task in startInfo.status to those in the endInfo.status for(unsigned i = 0; i < startInfo.count; i++) { int k = -1; @@ -108,27 +111,27 @@ bool TaskStat::update() #if CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID coreId = status.xCoreID; #endif - out.printf(datfmt, status.xTaskNumber, (coreId == CONFIG_FREERTOS_NO_AFFINITY) ? '-' : ('0' + coreId), - status.uxCurrentPriority, status.xHandle, taskElapsedTime, percentageTime, status.pcTaskName); + out->printf(datfmt, status.xTaskNumber, (coreId == CONFIG_FREERTOS_NO_AFFINITY) ? '-' : ('0' + coreId), + status.uxCurrentPriority, status.xHandle, taskElapsedTime, percentageTime, status.pcTaskName); } } // Print unmatched tasks for(unsigned i = 0; i < startInfo.count; i++) { if(!startMatched[i]) { - out.printf("Deleted: %s\r\n", startInfo.status[i].pcTaskName); + out->printf("Deleted: %s\r\n", startInfo.status[i].pcTaskName); } } for(unsigned i = 0; i < endInfo.count; i++) { if(!endMatched[i]) { - out.printf("Created: %s\r\n", endInfo.status[i].pcTaskName); + out->printf("Created: %s\r\n", endInfo.status[i].pcTaskName); } } return true; #else - out.println("[TaskStat] Tracing disabled"); + out->println("[TaskStat] Tracing disabled"); return false; #endif } diff --git a/Sming/Arch/Esp8266/Services/Profiling/TaskStat.cpp b/Sming/Arch/Esp8266/Services/Profiling/TaskStat.cpp index 80280f3547..1b226b3060 100644 --- a/Sming/Arch/Esp8266/Services/Profiling/TaskStat.cpp +++ b/Sming/Arch/Esp8266/Services/Profiling/TaskStat.cpp @@ -15,7 +15,7 @@ namespace Profiling struct TaskStat::Info { }; -TaskStat::TaskStat(Print& out) : out(out) +TaskStat::TaskStat(Print& out) : out(&out) { } @@ -23,7 +23,7 @@ TaskStat::~TaskStat() = default; bool TaskStat::update() { - out.println("[TaskStat] Not Implemented"); + out->println("[TaskStat] Not Implemented"); return false; } diff --git a/Sming/Arch/Host/Services/Profiling/TaskStat.cpp b/Sming/Arch/Host/Services/Profiling/TaskStat.cpp index 80280f3547..1b226b3060 100644 --- a/Sming/Arch/Host/Services/Profiling/TaskStat.cpp +++ b/Sming/Arch/Host/Services/Profiling/TaskStat.cpp @@ -15,7 +15,7 @@ namespace Profiling struct TaskStat::Info { }; -TaskStat::TaskStat(Print& out) : out(out) +TaskStat::TaskStat(Print& out) : out(&out) { } @@ -23,7 +23,7 @@ TaskStat::~TaskStat() = default; bool TaskStat::update() { - out.println("[TaskStat] Not Implemented"); + out->println("[TaskStat] Not Implemented"); return false; } diff --git a/Sming/Arch/Rp2040/Services/Profiling/TaskStat.cpp b/Sming/Arch/Rp2040/Services/Profiling/TaskStat.cpp index 80280f3547..1b226b3060 100644 --- a/Sming/Arch/Rp2040/Services/Profiling/TaskStat.cpp +++ b/Sming/Arch/Rp2040/Services/Profiling/TaskStat.cpp @@ -15,7 +15,7 @@ namespace Profiling struct TaskStat::Info { }; -TaskStat::TaskStat(Print& out) : out(out) +TaskStat::TaskStat(Print& out) : out(&out) { } @@ -23,7 +23,7 @@ TaskStat::~TaskStat() = default; bool TaskStat::update() { - out.println("[TaskStat] Not Implemented"); + out->println("[TaskStat] Not Implemented"); return false; } diff --git a/Sming/Services/Profiling/TaskStat.h b/Sming/Services/Profiling/TaskStat.h index 141435bf27..f0fe609671 100644 --- a/Sming/Services/Profiling/TaskStat.h +++ b/Sming/Services/Profiling/TaskStat.h @@ -47,8 +47,16 @@ class TaskStat */ bool update(); + /** + * @brief Change the output stream + */ + void setOutput(Print& out) + { + this->out = &out; + } + private: - Print& out; + Print* out; static constexpr size_t maxTasks{32}; struct Info; std::unique_ptr taskInfo;