mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-04 02:09:30 +02:00
Make performance profiling configurable from webserver
This commit is contained in:
parent
dc4aa95109
commit
13df59f806
8 changed files with 74 additions and 74 deletions
|
@ -42,10 +42,11 @@ const char* version_number = "9.0.RC5experimental";
|
||||||
volatile unsigned long currentMillis = 0;
|
volatile unsigned long currentMillis = 0;
|
||||||
unsigned long previousMillis10ms = 0;
|
unsigned long previousMillis10ms = 0;
|
||||||
unsigned long previousMillisUpdateVal = 0;
|
unsigned long previousMillisUpdateVal = 0;
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
|
||||||
// Task time measurement for debugging
|
// Task time measurement for debugging
|
||||||
MyTimer core_task_timer_10s(INTERVAL_10_S);
|
MyTimer core_task_timer_10s(INTERVAL_10_S);
|
||||||
#endif
|
uint64_t start_time_10ms = 0;
|
||||||
|
uint64_t start_time_values = 0;
|
||||||
|
uint64_t start_time_cantx = 0;
|
||||||
TaskHandle_t main_loop_task;
|
TaskHandle_t main_loop_task;
|
||||||
TaskHandle_t connectivity_loop_task;
|
TaskHandle_t connectivity_loop_task;
|
||||||
TaskHandle_t logging_loop_task;
|
TaskHandle_t logging_loop_task;
|
||||||
|
@ -248,24 +249,24 @@ void core_loop(void*) {
|
||||||
set_event(EVENT_TASK_OVERRUN, (currentMillis - previousMillis10ms));
|
set_event(EVENT_TASK_OVERRUN, (currentMillis - previousMillis10ms));
|
||||||
}
|
}
|
||||||
previousMillis10ms = currentMillis;
|
previousMillis10ms = currentMillis;
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
if (datalayer.system.info.performance_measurement_active) {
|
||||||
START_TIME_MEASUREMENT(time_10ms);
|
START_TIME_MEASUREMENT(10ms);
|
||||||
#endif
|
}
|
||||||
led_exe();
|
led_exe();
|
||||||
handle_contactors(); // Take care of startup precharge/contactor closing
|
handle_contactors(); // Take care of startup precharge/contactor closing
|
||||||
#ifdef PRECHARGE_CONTROL
|
#ifdef PRECHARGE_CONTROL
|
||||||
handle_precharge_control(currentMillis);
|
handle_precharge_control(currentMillis);
|
||||||
#endif // PRECHARGE_CONTROL
|
#endif // PRECHARGE_CONTROL
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
if (datalayer.system.info.performance_measurement_active) {
|
||||||
END_TIME_MEASUREMENT_MAX(time_10ms, datalayer.system.status.time_10ms_us);
|
END_TIME_MEASUREMENT_MAX(10ms, datalayer.system.status.time_10ms_us);
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentMillis - previousMillisUpdateVal >= INTERVAL_1_S) {
|
if (currentMillis - previousMillisUpdateVal >= INTERVAL_1_S) {
|
||||||
previousMillisUpdateVal = currentMillis; // Order matters on the update_loop!
|
previousMillisUpdateVal = currentMillis; // Order matters on the update_loop!
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
if (datalayer.system.info.performance_measurement_active) {
|
||||||
START_TIME_MEASUREMENT(time_values);
|
START_TIME_MEASUREMENT(values);
|
||||||
#endif
|
}
|
||||||
update_pause_state(); // Check if we are OK to send CAN or need to pause
|
update_pause_state(); // Check if we are OK to send CAN or need to pause
|
||||||
|
|
||||||
// Fetch battery values
|
// Fetch battery values
|
||||||
|
@ -285,24 +286,22 @@ void core_loop(void*) {
|
||||||
inverter->update_values();
|
inverter->update_values();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
if (datalayer.system.info.performance_measurement_active) {
|
||||||
END_TIME_MEASUREMENT_MAX(time_values, datalayer.system.status.time_values_us);
|
END_TIME_MEASUREMENT_MAX(values, datalayer.system.status.time_values_us);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
}
|
||||||
|
if (datalayer.system.info.performance_measurement_active) {
|
||||||
START_TIME_MEASUREMENT(cantx);
|
START_TIME_MEASUREMENT(cantx);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
// Let all transmitter objects send their messages
|
// Let all transmitter objects send their messages
|
||||||
for (auto& transmitter : transmitters) {
|
for (auto& transmitter : transmitters) {
|
||||||
transmitter->transmit(currentMillis);
|
transmitter->transmit(currentMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
if (datalayer.system.info.performance_measurement_active) {
|
||||||
END_TIME_MEASUREMENT_MAX(cantx, datalayer.system.status.time_cantx_us);
|
END_TIME_MEASUREMENT_MAX(cantx, datalayer.system.status.time_cantx_us);
|
||||||
END_TIME_MEASUREMENT_MAX(all, datalayer.system.status.core_task_10s_max_us);
|
END_TIME_MEASUREMENT_MAX(all, datalayer.system.status.core_task_10s_max_us);
|
||||||
#endif
|
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
|
||||||
if (datalayer.system.status.core_task_10s_max_us > datalayer.system.status.core_task_max_us) {
|
if (datalayer.system.status.core_task_10s_max_us > datalayer.system.status.core_task_max_us) {
|
||||||
// Update worst case total time
|
// Update worst case total time
|
||||||
datalayer.system.status.core_task_max_us = datalayer.system.status.core_task_10s_max_us;
|
datalayer.system.status.core_task_max_us = datalayer.system.status.core_task_10s_max_us;
|
||||||
|
@ -326,7 +325,7 @@ void core_loop(void*) {
|
||||||
datalayer.system.status.wifi_task_10s_max_us = 0;
|
datalayer.system.status.wifi_task_10s_max_us = 0;
|
||||||
datalayer.system.status.mqtt_task_10s_max_us = 0;
|
datalayer.system.status.mqtt_task_10s_max_us = 0;
|
||||||
}
|
}
|
||||||
#endif // FUNCTION_TIME_MEASUREMENT
|
}
|
||||||
esp_task_wdt_reset(); // Reset watchdog to prevent reset
|
esp_task_wdt_reset(); // Reset watchdog to prevent reset
|
||||||
vTaskDelayUntil(&xLastWakeTime, xFrequency);
|
vTaskDelayUntil(&xLastWakeTime, xFrequency);
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,6 @@
|
||||||
#define WIFIAP //When enabled, the emulator will broadcast its own access point Wifi. Can be used at the same time as a normal Wifi connection to a router.
|
#define WIFIAP //When enabled, the emulator will broadcast its own access point Wifi. Can be used at the same time as a normal Wifi connection to a router.
|
||||||
#define MDNSRESPONDER //Enable this line to enable MDNS, allows battery monitor te be found by .local address. Requires WEBSERVER to be enabled.
|
#define MDNSRESPONDER //Enable this line to enable MDNS, allows battery monitor te be found by .local address. Requires WEBSERVER to be enabled.
|
||||||
#define LOAD_SAVED_SETTINGS_ON_BOOT // Enable this line to read settings stored via the webserver on boot (overrides Wifi credentials set here)
|
#define LOAD_SAVED_SETTINGS_ON_BOOT // Enable this line to read settings stored via the webserver on boot (overrides Wifi credentials set here)
|
||||||
//#define FUNCTION_TIME_MEASUREMENT // Enable this to record execution times and present them in the web UI (WARNING, raises CPU load, do not use for production)
|
|
||||||
|
|
||||||
/* MQTT options */
|
/* MQTT options */
|
||||||
// #define MQTT // Enable this line to enable MQTT
|
// #define MQTT // Enable this line to enable MQTT
|
||||||
|
|
|
@ -297,7 +297,7 @@ void handle_BMSpower() {
|
||||||
|
|
||||||
if (periodic_bms_reset) {
|
if (periodic_bms_reset) {
|
||||||
// Check if 24 hours have passed since the last power removal
|
// Check if 24 hours have passed since the last power removal
|
||||||
if ((currentTime + bmsResetTimeOffset) - lastPowerRemovalTime >= powerRemovalInterval) {
|
if (currentTime - lastPowerRemovalTime >= powerRemovalInterval) {
|
||||||
start_bms_reset();
|
start_bms_reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,7 +329,6 @@ void start_bms_reset() {
|
||||||
if (!datalayer.system.status.BMS_reset_in_progress) {
|
if (!datalayer.system.status.BMS_reset_in_progress) {
|
||||||
lastPowerRemovalTime = currentTime; // Record the time when BMS reset was started
|
lastPowerRemovalTime = currentTime; // Record the time when BMS reset was started
|
||||||
// we are now resetting at the correct time. We don't need to offset anymore
|
// we are now resetting at the correct time. We don't need to offset anymore
|
||||||
bmsResetTimeOffset = 0;
|
|
||||||
// Set a flag to let the rest of the system know we are cutting power to the BMS.
|
// Set a flag to let the rest of the system know we are cutting power to the BMS.
|
||||||
// The battery CAN sending routine will then know not to try guto send anything towards battery while active
|
// The battery CAN sending routine will then know not to try guto send anything towards battery while active
|
||||||
datalayer.system.status.BMS_reset_in_progress = true;
|
datalayer.system.status.BMS_reset_in_progress = true;
|
||||||
|
|
|
@ -144,6 +144,7 @@ void init_stored_settings() {
|
||||||
remote_bms_reset = settings.getBool("REMBMSRESET", false);
|
remote_bms_reset = settings.getBool("REMBMSRESET", false);
|
||||||
use_canfd_as_can = settings.getBool("CANFDASCAN", false);
|
use_canfd_as_can = settings.getBool("CANFDASCAN", false);
|
||||||
|
|
||||||
|
datalayer.system.info.performance_measurement_active = settings.getBool("PERFPROFILE", false);
|
||||||
datalayer.system.info.CAN_usb_logging_active = settings.getBool("CANLOGUSB", false);
|
datalayer.system.info.CAN_usb_logging_active = settings.getBool("CANLOGUSB", false);
|
||||||
datalayer.system.info.usb_logging_active = settings.getBool("USBENABLED", false);
|
datalayer.system.info.usb_logging_active = settings.getBool("USBENABLED", false);
|
||||||
datalayer.system.info.web_logging_active = settings.getBool("WEBENABLED", false);
|
datalayer.system.info.web_logging_active = settings.getBool("WEBENABLED", false);
|
||||||
|
|
|
@ -259,12 +259,13 @@ struct DATALAYER_SYSTEM_INFO_TYPE {
|
||||||
bool can_native_send_fail = false;
|
bool can_native_send_fail = false;
|
||||||
/** bool, MCP2515 CAN failed to send flag */
|
/** bool, MCP2515 CAN failed to send flag */
|
||||||
bool can_2515_send_fail = false;
|
bool can_2515_send_fail = false;
|
||||||
/** uint16_t, MCP2518 CANFD failed to send flag */
|
/** bool, MCP2518 CANFD failed to send flag */
|
||||||
bool can_2518_send_fail = false;
|
bool can_2518_send_fail = false;
|
||||||
|
/** bool, determines if detailed performance measurement should be shown on webserver */
|
||||||
|
bool performance_measurement_active = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DATALAYER_SYSTEM_STATUS_TYPE {
|
struct DATALAYER_SYSTEM_STATUS_TYPE {
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
|
||||||
/** Core task measurement variable */
|
/** Core task measurement variable */
|
||||||
int64_t core_task_max_us = 0;
|
int64_t core_task_max_us = 0;
|
||||||
/** Core task measurement variable, reset each 10 seconds */
|
/** Core task measurement variable, reset each 10 seconds */
|
||||||
|
@ -305,7 +306,6 @@ struct DATALAYER_SYSTEM_STATUS_TYPE {
|
||||||
* This will show the performance of CAN TX when the total time reached a new worst case
|
* This will show the performance of CAN TX when the total time reached a new worst case
|
||||||
*/
|
*/
|
||||||
int64_t time_snap_cantx_us = 0;
|
int64_t time_snap_cantx_us = 0;
|
||||||
#endif
|
|
||||||
/** uint8_t */
|
/** uint8_t */
|
||||||
/** A counter set each time a new message comes from inverter.
|
/** A counter set each time a new message comes from inverter.
|
||||||
* This value then gets decremented every second. Incase we reach 0
|
* This value then gets decremented every second. Incase we reach 0
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
/** Start time measurement in microseconds
|
/** Start time measurement in microseconds
|
||||||
* Input parameter must be a unique "tag", e.g: START_TIME_MEASUREMENT(wifi);
|
* Input parameter must be a unique "tag", e.g: START_TIME_MEASUREMENT(wifi);
|
||||||
*/
|
*/
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
|
||||||
#define START_TIME_MEASUREMENT(x) int64_t start_time_##x = esp_timer_get_time()
|
#define START_TIME_MEASUREMENT(x) int64_t start_time_##x = esp_timer_get_time()
|
||||||
/** End time measurement in microseconds
|
/** End time measurement in microseconds
|
||||||
* Input parameters are the unique tag and the name of the ALREADY EXISTING
|
* Input parameters are the unique tag and the name of the ALREADY EXISTING
|
||||||
|
@ -21,10 +20,5 @@
|
||||||
* This will log the maximum value in the destination variable.
|
* This will log the maximum value in the destination variable.
|
||||||
*/
|
*/
|
||||||
#define END_TIME_MEASUREMENT_MAX(x, y) y = MAX(y, esp_timer_get_time() - start_time_##x)
|
#define END_TIME_MEASUREMENT_MAX(x, y) y = MAX(y, esp_timer_get_time() - start_time_##x)
|
||||||
#else
|
|
||||||
#define START_TIME_MEASUREMENT(x) ;
|
|
||||||
#define END_TIME_MEASUREMENT(x, y) ;
|
|
||||||
#define END_TIME_MEASUREMENT_MAX(x, y) ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -283,6 +283,10 @@ String settings_processor(const String& var, BatteryEmulatorSettingsStore& setti
|
||||||
return settings.getBool("WIFIAPENABLED", wifiap_enabled) ? "checked" : "";
|
return settings.getBool("WIFIAPENABLED", wifiap_enabled) ? "checked" : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (var == "PERFPROFILE") {
|
||||||
|
return settings.getBool("PERFPROFILE") ? "checked" : "";
|
||||||
|
}
|
||||||
|
|
||||||
if (var == "CANLOGUSB") {
|
if (var == "CANLOGUSB") {
|
||||||
return settings.getBool("CANLOGUSB") ? "checked" : "";
|
return settings.getBool("CANLOGUSB") ? "checked" : "";
|
||||||
}
|
}
|
||||||
|
@ -970,6 +974,9 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
||||||
<label>Custom hostname: </label>
|
<label>Custom hostname: </label>
|
||||||
<input type='text' name='HOSTNAME' value="%HOSTNAME%" />
|
<input type='text' name='HOSTNAME' value="%HOSTNAME%" />
|
||||||
|
|
||||||
|
<label>Enable performance profiling: </label>
|
||||||
|
<input type='checkbox' name='PERFPROFILE' value='on' style='margin-left: 0;' %PERFPROFILE% />
|
||||||
|
|
||||||
<label>Enable CAN logging via USB serial: </label>
|
<label>Enable CAN logging via USB serial: </label>
|
||||||
<input type='checkbox' name='CANLOGUSB' value='on' style='margin-left: 0;' %CANLOGUSB% />
|
<input type='checkbox' name='CANLOGUSB' value='on' style='margin-left: 0;' %CANLOGUSB% />
|
||||||
|
|
||||||
|
|
|
@ -411,7 +411,7 @@ void init_webserver() {
|
||||||
const char* boolSettingNames[] = {
|
const char* boolSettingNames[] = {
|
||||||
"DBLBTR", "CNTCTRL", "CNTCTRLDBL", "PWMCNTCTRL", "PERBMSRESET", "SDLOGENABLED", "REMBMSRESET",
|
"DBLBTR", "CNTCTRL", "CNTCTRLDBL", "PWMCNTCTRL", "PERBMSRESET", "SDLOGENABLED", "REMBMSRESET",
|
||||||
"USBENABLED", "CANLOGUSB", "WEBENABLED", "CANFDASCAN", "CANLOGSD", "WIFIAPENABLED", "MQTTENABLED",
|
"USBENABLED", "CANLOGUSB", "WEBENABLED", "CANFDASCAN", "CANLOGSD", "WIFIAPENABLED", "MQTTENABLED",
|
||||||
"HADISC", "MQTTTOPICS", "INVICNT", "GTWRHD", "DIGITALHVIL",
|
"HADISC", "MQTTTOPICS", "INVICNT", "GTWRHD", "DIGITALHVIL", "PERFPROFILE",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handles the form POST from UI to save settings of the common image
|
// Handles the form POST from UI to save settings of the common image
|
||||||
|
@ -914,10 +914,11 @@ String processor(const String& var) {
|
||||||
#endif // HW_STARK
|
#endif // HW_STARK
|
||||||
content += " @ " + String(datalayer.system.info.CPU_temperature, 1) + " °C</h4>";
|
content += " @ " + String(datalayer.system.info.CPU_temperature, 1) + " °C</h4>";
|
||||||
content += "<h4>Uptime: " + get_uptime() + "</h4>";
|
content += "<h4>Uptime: " + get_uptime() + "</h4>";
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
if (datalayer.system.info.performance_measurement_active) {
|
||||||
// Load information
|
// Load information
|
||||||
content += "<h4>Core task max load: " + String(datalayer.system.status.core_task_max_us) + " us</h4>";
|
content += "<h4>Core task max load: " + String(datalayer.system.status.core_task_max_us) + " us</h4>";
|
||||||
content += "<h4>Core task max load last 10 s: " + String(datalayer.system.status.core_task_10s_max_us) + " us</h4>";
|
content +=
|
||||||
|
"<h4>Core task max load last 10 s: " + String(datalayer.system.status.core_task_10s_max_us) + " us</h4>";
|
||||||
content +=
|
content +=
|
||||||
"<h4>MQTT function (MQTT task) max load last 10 s: " + String(datalayer.system.status.mqtt_task_10s_max_us) +
|
"<h4>MQTT function (MQTT task) max load last 10 s: " + String(datalayer.system.status.mqtt_task_10s_max_us) +
|
||||||
" us</h4>";
|
" us</h4>";
|
||||||
|
@ -930,7 +931,7 @@ String processor(const String& var) {
|
||||||
content += "<h4>CAN/serial RX function timing: " + String(datalayer.system.status.time_snap_comm_us) + " us</h4>";
|
content += "<h4>CAN/serial RX function timing: " + String(datalayer.system.status.time_snap_comm_us) + " us</h4>";
|
||||||
content += "<h4>CAN TX function timing: " + String(datalayer.system.status.time_snap_cantx_us) + " us</h4>";
|
content += "<h4>CAN TX function timing: " + String(datalayer.system.status.time_snap_cantx_us) + " us</h4>";
|
||||||
content += "<h4>OTA function timing: " + String(datalayer.system.status.time_snap_ota_us) + " us</h4>";
|
content += "<h4>OTA function timing: " + String(datalayer.system.status.time_snap_ota_us) + " us</h4>";
|
||||||
#endif // FUNCTION_TIME_MEASUREMENT
|
}
|
||||||
|
|
||||||
wl_status_t status = WiFi.status();
|
wl_status_t status = WiFi.status();
|
||||||
// Display ssid of network connected to and, if connected to the WiFi, its own IP
|
// Display ssid of network connected to and, if connected to the WiFi, its own IP
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue