Modified Task display to order based on task number or arbitraruy function
This commit is contained in:
@@ -27,14 +27,14 @@ monitor_port = /dev/ttyACM0
|
|||||||
monitor_speed = 921600
|
monitor_speed = 921600
|
||||||
build_type = release
|
build_type = release
|
||||||
build_flags =
|
build_flags =
|
||||||
-DCORE_DEBUG_LEVEL=4
|
-DCORE_DEBUG_LEVEL=1
|
||||||
-DARDUINO_USB_CDC_ON_BOOT=0
|
-DARDUINO_USB_CDC_ON_BOOT=0
|
||||||
-DARDUINO_USB_MODE=0
|
-DARDUINO_USB_MODE=0
|
||||||
-DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000
|
-DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000
|
||||||
-DCONFIG_ASYNC_TCP_PRIORITY=20
|
-DCONFIG_ASYNC_TCP_PRIORITY=21
|
||||||
-DCONFIG_ASYNC_TCP_QUEUE_SIZE=128
|
-DCONFIG_ASYNC_TCP_QUEUE_SIZE=64
|
||||||
-DCONFIG_ASYNC_TCP_RUNNING_CORE=1
|
-DCONFIG_ASYNC_TCP_RUNNING_CORE=1
|
||||||
-DCONFIG_ASYNC_TCP_STACK_SIZE=8192
|
-DCONFIG_ASYNC_TCP_STACK_SIZE=4096
|
||||||
-fstack-protector-all
|
-fstack-protector-all
|
||||||
|
|
||||||
[env:esp32-s3-devkitc1-n16r8-debug]
|
[env:esp32-s3-devkitc1-n16r8-debug]
|
||||||
@@ -61,8 +61,8 @@ build_flags =
|
|||||||
-DARDUINO_USB_CDC_ON_BOOT=0
|
-DARDUINO_USB_CDC_ON_BOOT=0
|
||||||
-DARDUINO_USB_MODE=0
|
-DARDUINO_USB_MODE=0
|
||||||
-DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000
|
-DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000
|
||||||
-DCONFIG_ASYNC_TCP_PRIORITY=20
|
-DCONFIG_ASYNC_TCP_PRIORITY=21
|
||||||
-DCONFIG_ASYNC_TCP_QUEUE_SIZE=128
|
-DCONFIG_ASYNC_TCP_QUEUE_SIZE=64
|
||||||
-DCONFIG_ASYNC_TCP_RUNNING_CORE=1
|
-DCONFIG_ASYNC_TCP_RUNNING_CORE=1
|
||||||
-DCONFIG_ASYNC_TCP_STACK_SIZE=8192
|
-DCONFIG_ASYNC_TCP_STACK_SIZE=4096
|
||||||
-fstack-protector-all
|
-fstack-protector-all
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
#define CORE_0 0
|
#define CORE_0 0
|
||||||
#define CORE_1 1
|
#define CORE_1 1
|
||||||
#define RT_TASK_STACK 4096 // in words
|
#define RT_TASK_STACK 2048 // in words
|
||||||
#define RT_TASK_PRIORITY (configMAX_PRIORITIES - 4) // highest priority after wifi tasks
|
#define RT_TASK_PRIORITY (configMAX_PRIORITIES - 6) // highest priority after wifi tasks
|
||||||
|
|
||||||
struct isrParams
|
struct isrParams
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,10 +15,6 @@
|
|||||||
#include <webserver.h>
|
#include <webserver.h>
|
||||||
#include <ui.h>
|
#include <ui.h>
|
||||||
|
|
||||||
// FreeRTOS directives
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
|
|
||||||
// Defines to enable channel B
|
// Defines to enable channel B
|
||||||
#define CH_B_ENABLE
|
#define CH_B_ENABLE
|
||||||
#define TEST
|
#define TEST
|
||||||
@@ -76,6 +72,7 @@ void setup()
|
|||||||
initSparkPinInputs();
|
initSparkPinInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////// MAIN LOOP //////////////////////
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
// global variables
|
// global variables
|
||||||
@@ -223,12 +220,12 @@ void loop()
|
|||||||
|
|
||||||
LOG_DEBUG("Real Time Tasks A & B initialized");
|
LOG_DEBUG("Real Time Tasks A & B initialized");
|
||||||
|
|
||||||
////////////////////// MAIN LOOP //////////////////////
|
|
||||||
bool partial_save = false; // flag to indicate if a partial save has been done after a timeout
|
bool partial_save = false; // flag to indicate if a partial save has been done after a timeout
|
||||||
auto last_data = millis();
|
auto last_data = millis();
|
||||||
|
auto last_info = millis();
|
||||||
|
|
||||||
uint32_t counter_a = 0;
|
uint32_t counter_a = 0;
|
||||||
uint32_t counter_b = 0;
|
uint32_t counter_b = 0;
|
||||||
|
|
||||||
uint32_t wait_count = 0;
|
uint32_t wait_count = 0;
|
||||||
|
|
||||||
ignitionBoxStatus ign_info_A;
|
ignitionBoxStatus ign_info_A;
|
||||||
@@ -240,12 +237,13 @@ void loop()
|
|||||||
LITTLEFSGuard fsGuard;
|
LITTLEFSGuard fsGuard;
|
||||||
WebPage webPage(80, LittleFS); // Initialize webserver and Websocket
|
WebPage webPage(80, LittleFS); // Initialize webserver and Websocket
|
||||||
|
|
||||||
while (running)
|
//////////////// INNER LOOP /////////////////////
|
||||||
|
while (running)
|
||||||
{
|
{
|
||||||
auto dataA = pdFALSE;
|
auto dataA = pdFALSE;
|
||||||
auto dataB = pdFALSE;
|
auto dataB = pdFALSE;
|
||||||
|
|
||||||
dataA = xQueueReceive(rt_taskA_queue, &ign_info_A, pdMS_TO_TICKS(10));
|
dataA = xQueueReceive(rt_taskA_queue, &ign_info_A, 0);
|
||||||
if (counter_a >= active_history_A->size()) // not concurrent with write task
|
if (counter_a >= active_history_A->size()) // not concurrent with write task
|
||||||
{
|
{
|
||||||
counter_a = 0;
|
counter_a = 0;
|
||||||
@@ -255,7 +253,7 @@ void loop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CH_B_ENABLE
|
#ifdef CH_B_ENABLE
|
||||||
dataB = xQueueReceive(rt_taskB_queue, &ign_info_B, pdMS_TO_TICKS(10));
|
dataB = xQueueReceive(rt_taskB_queue, &ign_info_B, 0);
|
||||||
if (counter_b >= active_history_B->size()) // not concurrent with write task
|
if (counter_b >= active_history_B->size()) // not concurrent with write task
|
||||||
{
|
{
|
||||||
counter_b = 0;
|
counter_b = 0;
|
||||||
@@ -274,7 +272,7 @@ void loop()
|
|||||||
{
|
{
|
||||||
(*active_history_A)[counter_a++ % active_history_A->size()] = ign_info_A;
|
(*active_history_A)[counter_a++ % active_history_A->size()] = ign_info_A;
|
||||||
ign_info_avg_A.update(ign_info_A); // update moving average with latest ignition status
|
ign_info_avg_A.update(ign_info_A); // update moving average with latest ignition status
|
||||||
Serial.printf("Data Received A: %d/%d\n\r", counter_a, (*active_history_A).size());
|
// Serial.printf("Data Received A: %d/%d\n\r", counter_a, (*active_history_A).size());
|
||||||
if (counter_a % filter_k == 0) // send data every 10 samples
|
if (counter_a % filter_k == 0) // send data every 10 samples
|
||||||
{
|
{
|
||||||
ArduinoJson::JsonDocument wsData;
|
ArduinoJson::JsonDocument wsData;
|
||||||
@@ -288,7 +286,7 @@ void loop()
|
|||||||
{
|
{
|
||||||
(*active_history_B)[counter_b++ % active_history_B->size()] = ign_info_B;
|
(*active_history_B)[counter_b++ % active_history_B->size()] = ign_info_B;
|
||||||
ign_info_avg_B.update(ign_info_B); // update moving average with latest ignition status
|
ign_info_avg_B.update(ign_info_B); // update moving average with latest ignition status
|
||||||
Serial.printf("Data Received B: %d/%d\n\r", counter_b, (*active_history_B).size());
|
// Serial.printf("Data Received B: %d/%d\n\r", counter_b, (*active_history_B).size());
|
||||||
if (counter_b % filter_k == 0) // send data every 10 samples
|
if (counter_b % filter_k == 0) // send data every 10 samples
|
||||||
{
|
{
|
||||||
ArduinoJson::JsonDocument wsData;
|
ArduinoJson::JsonDocument wsData;
|
||||||
@@ -298,7 +296,7 @@ void loop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (dataA == pdFALSE && dataB == pdFALSE && millis() - last_data > 2000)
|
if (dataA == pdFALSE && dataB == pdFALSE && (millis() - last_data) > 2000)
|
||||||
{
|
{
|
||||||
if (!partial_save && counter_a > 0) // if timeout occurs but we have unsaved data, save it before next timeout
|
if (!partial_save && counter_a > 0) // if timeout occurs but we have unsaved data, save it before next timeout
|
||||||
{
|
{
|
||||||
@@ -316,16 +314,23 @@ void loop()
|
|||||||
partial_save = true;
|
partial_save = true;
|
||||||
first_save = true;
|
first_save = true;
|
||||||
}
|
}
|
||||||
Serial.printf("[%d] Waiting for data...\r", wait_count++);
|
//Serial.printf("[%d] Waiting for data...\r", wait_count++);
|
||||||
delay(500);
|
delay(100);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if ((millis() - last_info) > 1000)
|
||||||
|
{
|
||||||
|
clearScreen();
|
||||||
|
Serial.println();
|
||||||
|
printRunningTasksMod(Serial);
|
||||||
|
last_info = millis();
|
||||||
|
|
||||||
|
}
|
||||||
|
} //////////////// INNER LOOP /////////////////////
|
||||||
|
|
||||||
if (trigA_TaskHandle)
|
if (trigA_TaskHandle)
|
||||||
vTaskDelete(trigA_TaskHandle);
|
vTaskDelete(trigA_TaskHandle);
|
||||||
#ifdef CH_B_ENABLE
|
|
||||||
if (trigB_TaskHandle)
|
if (trigB_TaskHandle)
|
||||||
vTaskDelete(trigB_TaskHandle);
|
vTaskDelete(trigB_TaskHandle);
|
||||||
#endif
|
|
||||||
////////////////////// MAIN LOOP //////////////////////
|
} ////////////////////// MAIN LOOP //////////////////////
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,15 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "freertos_stats.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/portable.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#define FREERTOS_TASK_NUMBER_MAX_NUM 256 // RunTime stats for how many Tasks to be stored
|
||||||
|
|
||||||
std::string printBits(uint32_t value) {
|
std::string printBits(uint32_t value) {
|
||||||
std::string result;
|
std::string result;
|
||||||
@@ -12,3 +23,60 @@ std::string printBits(uint32_t value) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printRunningTasksMod(Print &printer, std::function<bool(const TaskStatus_t &a, const TaskStatus_t &b)> orderBy)
|
||||||
|
{
|
||||||
|
static const char *taskStates[] = {"Running", "Ready", "Blocked", "Suspended", "Deleted", "Invalid"};
|
||||||
|
|
||||||
|
static uint32_t ulRunTimeCounters[FREERTOS_TASK_NUMBER_MAX_NUM];
|
||||||
|
static uint32_t ulLastRunTime = 0;
|
||||||
|
uint32_t ulCurrentRunTime = 0, ulTaskRunTime = 0;
|
||||||
|
uint32_t ulTotalRunTime = 0;
|
||||||
|
|
||||||
|
std::vector<TaskStatus_t> pxTaskStatusArray;
|
||||||
|
UBaseType_t uxArraySize = 0;
|
||||||
|
|
||||||
|
// Take a snapshot of the number of tasks in case it changes while this function is executing.
|
||||||
|
uxArraySize = uxTaskGetNumberOfTasks();
|
||||||
|
pxTaskStatusArray.resize(uxArraySize);
|
||||||
|
|
||||||
|
// Generate raw status information about each task.
|
||||||
|
uxArraySize = uxTaskGetSystemState(pxTaskStatusArray.data(), uxArraySize, &ulTotalRunTime);
|
||||||
|
|
||||||
|
if (orderBy == nullptr)
|
||||||
|
std::sort(pxTaskStatusArray.begin(), pxTaskStatusArray.end(), [](const TaskStatus_t &a, const TaskStatus_t &b)
|
||||||
|
{ return a.xTaskNumber < b.xTaskNumber; });
|
||||||
|
else
|
||||||
|
std::sort(pxTaskStatusArray.begin(), pxTaskStatusArray.end(), orderBy);
|
||||||
|
|
||||||
|
// Compute system total runtime
|
||||||
|
ulCurrentRunTime = ulTotalRunTime - ulLastRunTime;
|
||||||
|
ulLastRunTime = ulTotalRunTime;
|
||||||
|
|
||||||
|
// Print Runtime Information
|
||||||
|
printer.printf("Tasks: %u, Runtime: %lus, Period: %luus\r\n", uxArraySize, ulTotalRunTime / 1000000, ulCurrentRunTime);
|
||||||
|
|
||||||
|
// Print Task Headers
|
||||||
|
printer.printf("Num\t Name\tLoad\tPrio\t Free\tCore\tState\r\n");
|
||||||
|
for (const auto &task : pxTaskStatusArray)
|
||||||
|
{
|
||||||
|
|
||||||
|
ulTaskRunTime = (task.ulRunTimeCounter - ulRunTimeCounters[task.xTaskNumber]);
|
||||||
|
ulRunTimeCounters[task.xTaskNumber] = task.ulRunTimeCounter;
|
||||||
|
ulTaskRunTime = (ulTaskRunTime * 100) / ulCurrentRunTime; // in percentage
|
||||||
|
|
||||||
|
printer.printf(
|
||||||
|
"%3u\t%16s"
|
||||||
|
"\t%3lu%%"
|
||||||
|
"\t%4u\t%5lu"
|
||||||
|
"\t%4c"
|
||||||
|
"\t%s\r\n",
|
||||||
|
task.xTaskNumber, task.pcTaskName,
|
||||||
|
ulTaskRunTime,
|
||||||
|
task.uxCurrentPriority, task.usStackHighWaterMark,
|
||||||
|
(task.xCoreID == tskNO_AFFINITY) ? '*' : ('0' + task.xCoreID),
|
||||||
|
taskStates[task.eCurrentState]);
|
||||||
|
}
|
||||||
|
printer.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
std::string printBits(uint32_t value);
|
std::string printBits(uint32_t value);
|
||||||
|
|
||||||
|
void printRunningTasksMod(Print &printer, std::function<bool(const TaskStatus_t &a, const TaskStatus_t &b)> orderBy = nullptr);
|
||||||
|
|
||||||
inline void swapHistory(PSRAMVector<ignitionBoxStatus>* active, PSRAMVector<ignitionBoxStatus>* writable) {
|
inline void swapHistory(PSRAMVector<ignitionBoxStatus>* active, PSRAMVector<ignitionBoxStatus>* writable) {
|
||||||
auto *temp = active;
|
auto *temp = active;
|
||||||
active = writable; // switch active and writable buffers
|
active = writable; // switch active and writable buffers
|
||||||
|
|||||||
Reference in New Issue
Block a user