Add UART SET_LOG_LEVEL for runtime master ESP-IDF logging.
Expose the command via goTool CLI/REST and dashboard controls so log verbosity can be tuned without reflashing. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -28,6 +28,7 @@ idf_component_register(
|
||||
"pod_reboot.c"
|
||||
"cmd/cmd_led_ring.c"
|
||||
"cmd/cmd_battery.c"
|
||||
"cmd/cmd_set_log_level.c"
|
||||
"cmd/cmd_ota.c"
|
||||
"cmd/cmd_ota_slave_progress.c"
|
||||
"ota_uart.c"
|
||||
|
||||
@@ -228,6 +228,8 @@ Host and master speak nanopb-encoded `UartMessage` inside UART frames (byte 0 =
|
||||
| 25 | `ACCEL_STREAM` | Implemented — enable/disable slave ESP-NOW accel stream to master |
|
||||
| 27 | `TAP_NOTIFY` | Implemented (`cmd/cmd_tap_notify.c`) — get/set which tap kinds notify via ESP-NOW |
|
||||
| 29 | `CACHE_STATUS` | Implemented (`cmd/cmd_cache_status.c`) — subscribed accel + tap cache (one UART round-trip) |
|
||||
| 30 | `ESPNOW_ECHO_PING` | Implemented (`cmd/cmd_espnow_echo_ping.c`) — ESP-NOW timestamp echo (latency test) |
|
||||
| 31 | `SET_LOG_LEVEL` | Implemented (`cmd/cmd_set_log_level.c`) — get/set global `esp_log_level_set("*", …)` on master |
|
||||
|
||||
Regenerate C code:
|
||||
|
||||
@@ -390,6 +392,30 @@ go run . -port /dev/ttyUSB0 find-me
|
||||
go run . -port /dev/ttyUSB0 find-me -client 16
|
||||
```
|
||||
|
||||
### SET_LOG_LEVEL command
|
||||
|
||||
Read or set the **global** ESP-IDF log filter on the master (`esp_log_level_set("*", level)`). Does not affect the host UART protocol (UART1); `esp_log_*` output goes to the **debug console UART0** (USB, 115200).
|
||||
|
||||
**Request:** framed `31` (`0x1f`) + `set_log_level_request` (`write`, `level` 0–5).
|
||||
|
||||
**Response:** `set_log_level_response` (`success`, `level`).
|
||||
|
||||
| `level` | `esp_log_level_t` |
|
||||
|---------|-------------------|
|
||||
| 0 | NONE |
|
||||
| 1 | ERROR |
|
||||
| 2 | WARN |
|
||||
| 3 | INFO |
|
||||
| 4 | DEBUG |
|
||||
| 5 | VERBOSE |
|
||||
|
||||
Boot default follows `CONFIG_LOG_DEFAULT_LEVEL` in `sdkconfig` (not persisted across reboot).
|
||||
|
||||
```bash
|
||||
go run . -port /dev/ttyUSB0 log-level
|
||||
go run . -port /dev/ttyUSB0 log-level -set -level 0
|
||||
```
|
||||
|
||||
### RESTART command
|
||||
|
||||
Reboot the master (`client_id=0`) or one slave via ESP-NOW (`client_id` = registry id). The device sends the UART response, then restarts after ~150 ms.
|
||||
@@ -541,6 +567,7 @@ Target: ESP32-S3. Close serial monitor on the UART adapter port before running `
|
||||
| `pod_settings.c/h` | NVS persistence (accel deadzone, …) |
|
||||
| `led_ring.c/h` | LED ring (digit display, progress bar) |
|
||||
| `cmd/cmd_led_ring.c` | UART `LED_RING` progress command |
|
||||
| `cmd/cmd_set_log_level.c` | UART `SET_LOG_LEVEL` — runtime ESP-IDF log level |
|
||||
| `proto/uart_messages.proto` | UART protocol schema |
|
||||
| `proto/esp_now_messages.proto` | ESP-NOW protocol schema |
|
||||
| `esp_now_proto.c/h` | Encode/decode `EspNowMessage` |
|
||||
|
||||
@@ -59,6 +59,8 @@ static const char *message_type_name(uint16_t id) {
|
||||
return "CACHE_STATUS";
|
||||
case alox_MessageType_ESPNOW_ECHO_PING:
|
||||
return "ESPNOW_ECHO_PING";
|
||||
case alox_MessageType_SET_LOG_LEVEL:
|
||||
return "SET_LOG_LEVEL";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "cmd_set_log_level.h"
|
||||
#include "esp_log.h"
|
||||
#include "uart_cmd.h"
|
||||
|
||||
static const char *TAG = "[LOG_LVL]";
|
||||
|
||||
static bool valid_level(uint32_t level) { return level <= ESP_LOG_VERBOSE; }
|
||||
|
||||
static void reply(uint32_t level, bool success) {
|
||||
alox_UartMessage response;
|
||||
uart_cmd_init_response(&response, alox_MessageType_SET_LOG_LEVEL,
|
||||
alox_UartMessage_set_log_level_response_tag);
|
||||
response.payload.set_log_level_response.success = success;
|
||||
response.payload.set_log_level_response.level = level;
|
||||
uart_cmd_send(&response, TAG);
|
||||
}
|
||||
|
||||
static void handle_set_log_level(const uint8_t *data, size_t len) {
|
||||
alox_UartMessage uart_msg;
|
||||
alox_SetLogLevelRequest req = alox_SetLogLevelRequest_init_zero;
|
||||
|
||||
if (uart_cmd_decode(data, len, &uart_msg) != ESP_OK) {
|
||||
ESP_LOGW(TAG, "decode failed");
|
||||
reply((uint32_t)esp_log_level_get("*"), false);
|
||||
return;
|
||||
}
|
||||
|
||||
const alox_SetLogLevelRequest *req_ptr = UART_CMD_REQ(
|
||||
&uart_msg, alox_UartMessage_set_log_level_request_tag, set_log_level_request);
|
||||
if (req_ptr != NULL) {
|
||||
req = *req_ptr;
|
||||
}
|
||||
|
||||
if (req.write) {
|
||||
if (!valid_level(req.level)) {
|
||||
ESP_LOGW(TAG, "invalid level %lu", (unsigned long)req.level);
|
||||
reply((uint32_t)esp_log_level_get("*"), false);
|
||||
return;
|
||||
}
|
||||
esp_log_level_set("*", (esp_log_level_t)req.level);
|
||||
ESP_LOGI(TAG, "global log level set to %lu", (unsigned long)req.level);
|
||||
reply(req.level, true);
|
||||
return;
|
||||
}
|
||||
|
||||
reply((uint32_t)esp_log_level_get("*"), true);
|
||||
}
|
||||
|
||||
void cmd_set_log_level_register(void) {
|
||||
uart_cmd_register(alox_MessageType_SET_LOG_LEVEL, handle_set_log_level);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef CMD_SET_LOG_LEVEL_H
|
||||
#define CMD_SET_LOG_LEVEL_H
|
||||
|
||||
void cmd_set_log_level_register(void);
|
||||
|
||||
#endif
|
||||
+2
-3
@@ -14,6 +14,7 @@
|
||||
#include "cmd_ota_slave_progress.h"
|
||||
#include "cmd_led_ring.h"
|
||||
#include "cmd_battery.h"
|
||||
#include "cmd_set_log_level.h"
|
||||
#include "esp_now_comm.h"
|
||||
#include "powerpod.h"
|
||||
#include "driver/gpio.h"
|
||||
@@ -73,9 +74,6 @@ uint8_t reverse_high_nibble_lut(uint8_t n) {
|
||||
}
|
||||
|
||||
void app_main(void) {
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_NONE);
|
||||
|
||||
if (pod_settings_init() != ESP_OK) {
|
||||
ESP_LOGW(TAG, "settings NVS init failed; using defaults");
|
||||
}
|
||||
@@ -196,6 +194,7 @@ void app_main(void) {
|
||||
cmd_battery_register();
|
||||
cmd_ota_register();
|
||||
cmd_ota_slave_progress_register();
|
||||
cmd_set_log_level_register();
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "LED ring: UART LED_RING commands only (no local demo loop)");
|
||||
|
||||
@@ -111,6 +111,12 @@ PB_BIND(alox_RestartRequest, alox_RestartRequest, AUTO)
|
||||
PB_BIND(alox_RestartResponse, alox_RestartResponse, AUTO)
|
||||
|
||||
|
||||
PB_BIND(alox_SetLogLevelRequest, alox_SetLogLevelRequest, AUTO)
|
||||
|
||||
|
||||
PB_BIND(alox_SetLogLevelResponse, alox_SetLogLevelResponse, AUTO)
|
||||
|
||||
|
||||
PB_BIND(alox_OtaStartPayload, alox_OtaStartPayload, AUTO)
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,9 @@ typedef enum _alox_MessageType {
|
||||
/* * Combined cached accel + tap poll (one UART round-trip, ~16 ms cadence). */
|
||||
alox_MessageType_CACHE_STATUS = 29,
|
||||
/* * Host → master → slave → master: timestamp echo round-trip (latency test). */
|
||||
alox_MessageType_ESPNOW_ECHO_PING = 30
|
||||
alox_MessageType_ESPNOW_ECHO_PING = 30,
|
||||
/* * Host → master: get/set ESP-IDF log level for tag "*" (global). */
|
||||
alox_MessageType_SET_LOG_LEVEL = 31
|
||||
} alox_MessageType;
|
||||
|
||||
typedef enum _alox_TapKind {
|
||||
@@ -307,6 +309,18 @@ typedef struct _alox_RestartResponse {
|
||||
uint32_t client_id;
|
||||
} alox_RestartResponse;
|
||||
|
||||
/* * Host → master: read/write global log level (esp_log_level_set("*", …)). */
|
||||
typedef struct _alox_SetLogLevelRequest {
|
||||
bool write;
|
||||
/* * esp_log_level_t: 0=NONE, 1=ERROR, 2=WARN, 3=INFO, 4=DEBUG, 5=VERBOSE */
|
||||
uint32_t level;
|
||||
} alox_SetLogLevelRequest;
|
||||
|
||||
typedef struct _alox_SetLogLevelResponse {
|
||||
bool success;
|
||||
uint32_t level;
|
||||
} alox_SetLogLevelResponse;
|
||||
|
||||
/* Host → device: begin UART OTA (erase inactive OTA slot; device replies OTA_STATUS). */
|
||||
typedef struct _alox_OtaStartPayload {
|
||||
uint32_t total_size;
|
||||
@@ -391,6 +405,8 @@ typedef struct _alox_UartMessage {
|
||||
alox_CacheStatusResponse cache_status_response;
|
||||
alox_EspNowEchoPingRequest espnow_echo_ping_request;
|
||||
alox_EspNowEchoPingResponse espnow_echo_ping_response;
|
||||
alox_SetLogLevelRequest set_log_level_request;
|
||||
alox_SetLogLevelResponse set_log_level_response;
|
||||
} payload;
|
||||
} alox_UartMessage;
|
||||
|
||||
@@ -401,8 +417,8 @@ extern "C" {
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _alox_MessageType_MIN alox_MessageType_UNKNOWN
|
||||
#define _alox_MessageType_MAX alox_MessageType_ESPNOW_ECHO_PING
|
||||
#define _alox_MessageType_ARRAYSIZE ((alox_MessageType)(alox_MessageType_ESPNOW_ECHO_PING+1))
|
||||
#define _alox_MessageType_MAX alox_MessageType_SET_LOG_LEVEL
|
||||
#define _alox_MessageType_ARRAYSIZE ((alox_MessageType)(alox_MessageType_SET_LOG_LEVEL+1))
|
||||
|
||||
#define _alox_TapKind_MIN alox_TapKind_TAP_NONE
|
||||
#define _alox_TapKind_MAX alox_TapKind_TAP_TRIPLE
|
||||
@@ -451,6 +467,8 @@ extern "C" {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -490,6 +508,8 @@ extern "C" {
|
||||
#define alox_EspNowFindMeResponse_init_default {0, 0}
|
||||
#define alox_RestartRequest_init_default {0}
|
||||
#define alox_RestartResponse_init_default {0, 0}
|
||||
#define alox_SetLogLevelRequest_init_default {0, 0}
|
||||
#define alox_SetLogLevelResponse_init_default {0, 0}
|
||||
#define alox_OtaStartPayload_init_default {0}
|
||||
#define alox_OtaPayload_init_default {0, {0, {0}}}
|
||||
#define alox_OtaEndPayload_init_default {0}
|
||||
@@ -532,6 +552,8 @@ extern "C" {
|
||||
#define alox_EspNowFindMeResponse_init_zero {0, 0}
|
||||
#define alox_RestartRequest_init_zero {0}
|
||||
#define alox_RestartResponse_init_zero {0, 0}
|
||||
#define alox_SetLogLevelRequest_init_zero {0, 0}
|
||||
#define alox_SetLogLevelResponse_init_zero {0, 0}
|
||||
#define alox_OtaStartPayload_init_zero {0}
|
||||
#define alox_OtaPayload_init_zero {0, {0, {0}}}
|
||||
#define alox_OtaEndPayload_init_zero {0}
|
||||
@@ -655,6 +677,10 @@ extern "C" {
|
||||
#define alox_RestartRequest_client_id_tag 1
|
||||
#define alox_RestartResponse_success_tag 1
|
||||
#define alox_RestartResponse_client_id_tag 2
|
||||
#define alox_SetLogLevelRequest_write_tag 1
|
||||
#define alox_SetLogLevelRequest_level_tag 2
|
||||
#define alox_SetLogLevelResponse_success_tag 1
|
||||
#define alox_SetLogLevelResponse_level_tag 2
|
||||
#define alox_OtaStartPayload_total_size_tag 1
|
||||
#define alox_OtaPayload_seq_tag 1
|
||||
#define alox_OtaPayload_data_tag 2
|
||||
@@ -705,6 +731,8 @@ extern "C" {
|
||||
#define alox_UartMessage_cache_status_response_tag 34
|
||||
#define alox_UartMessage_espnow_echo_ping_request_tag 35
|
||||
#define alox_UartMessage_espnow_echo_ping_response_tag 36
|
||||
#define alox_UartMessage_set_log_level_request_tag 37
|
||||
#define alox_UartMessage_set_log_level_response_tag 38
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define alox_UartMessage_FIELDLIST(X, a) \
|
||||
@@ -739,7 +767,9 @@ X(a, STATIC, ONEOF, MESSAGE, (payload,tap_notify_response,payload.tap_noti
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,cache_status_request,payload.cache_status_request), 33) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,cache_status_response,payload.cache_status_response), 34) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,espnow_echo_ping_request,payload.espnow_echo_ping_request), 35) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,espnow_echo_ping_response,payload.espnow_echo_ping_response), 36)
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,espnow_echo_ping_response,payload.espnow_echo_ping_response), 36) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,set_log_level_request,payload.set_log_level_request), 37) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload,set_log_level_response,payload.set_log_level_response), 38)
|
||||
#define alox_UartMessage_CALLBACK NULL
|
||||
#define alox_UartMessage_DEFAULT NULL
|
||||
#define alox_UartMessage_payload_ack_payload_MSGTYPE alox_Ack
|
||||
@@ -773,6 +803,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload,espnow_echo_ping_response,payload.es
|
||||
#define alox_UartMessage_payload_cache_status_response_MSGTYPE alox_CacheStatusResponse
|
||||
#define alox_UartMessage_payload_espnow_echo_ping_request_MSGTYPE alox_EspNowEchoPingRequest
|
||||
#define alox_UartMessage_payload_espnow_echo_ping_response_MSGTYPE alox_EspNowEchoPingResponse
|
||||
#define alox_UartMessage_payload_set_log_level_request_MSGTYPE alox_SetLogLevelRequest
|
||||
#define alox_UartMessage_payload_set_log_level_response_MSGTYPE alox_SetLogLevelResponse
|
||||
|
||||
#define alox_Ack_FIELDLIST(X, a) \
|
||||
|
||||
@@ -1034,6 +1066,18 @@ X(a, STATIC, SINGULAR, UINT32, client_id, 2)
|
||||
#define alox_RestartResponse_CALLBACK NULL
|
||||
#define alox_RestartResponse_DEFAULT NULL
|
||||
|
||||
#define alox_SetLogLevelRequest_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, write, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, level, 2)
|
||||
#define alox_SetLogLevelRequest_CALLBACK NULL
|
||||
#define alox_SetLogLevelRequest_DEFAULT NULL
|
||||
|
||||
#define alox_SetLogLevelResponse_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, success, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, level, 2)
|
||||
#define alox_SetLogLevelResponse_CALLBACK NULL
|
||||
#define alox_SetLogLevelResponse_DEFAULT NULL
|
||||
|
||||
#define alox_OtaStartPayload_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, total_size, 1)
|
||||
#define alox_OtaStartPayload_CALLBACK NULL
|
||||
@@ -1117,6 +1161,8 @@ extern const pb_msgdesc_t alox_EspNowFindMeRequest_msg;
|
||||
extern const pb_msgdesc_t alox_EspNowFindMeResponse_msg;
|
||||
extern const pb_msgdesc_t alox_RestartRequest_msg;
|
||||
extern const pb_msgdesc_t alox_RestartResponse_msg;
|
||||
extern const pb_msgdesc_t alox_SetLogLevelRequest_msg;
|
||||
extern const pb_msgdesc_t alox_SetLogLevelResponse_msg;
|
||||
extern const pb_msgdesc_t alox_OtaStartPayload_msg;
|
||||
extern const pb_msgdesc_t alox_OtaPayload_msg;
|
||||
extern const pb_msgdesc_t alox_OtaEndPayload_msg;
|
||||
@@ -1161,6 +1207,8 @@ extern const pb_msgdesc_t alox_OtaSlaveProgressResponse_msg;
|
||||
#define alox_EspNowFindMeResponse_fields &alox_EspNowFindMeResponse_msg
|
||||
#define alox_RestartRequest_fields &alox_RestartRequest_msg
|
||||
#define alox_RestartResponse_fields &alox_RestartResponse_msg
|
||||
#define alox_SetLogLevelRequest_fields &alox_SetLogLevelRequest_msg
|
||||
#define alox_SetLogLevelResponse_fields &alox_SetLogLevelResponse_msg
|
||||
#define alox_OtaStartPayload_fields &alox_OtaStartPayload_msg
|
||||
#define alox_OtaPayload_fields &alox_OtaPayload_msg
|
||||
#define alox_OtaEndPayload_fields &alox_OtaEndPayload_msg
|
||||
@@ -1210,6 +1258,8 @@ extern const pb_msgdesc_t alox_OtaSlaveProgressResponse_msg;
|
||||
#define alox_OtaStatusPayload_size 24
|
||||
#define alox_RestartRequest_size 6
|
||||
#define alox_RestartResponse_size 8
|
||||
#define alox_SetLogLevelRequest_size 8
|
||||
#define alox_SetLogLevelResponse_size 8
|
||||
#define alox_TapEvent_size 16
|
||||
#define alox_TapNotifyRequest_size 16
|
||||
#define alox_TapNotifyResponse_size 20
|
||||
|
||||
@@ -31,6 +31,8 @@ enum MessageType {
|
||||
CACHE_STATUS = 29;
|
||||
/** Host → master → slave → master: timestamp echo round-trip (latency test). */
|
||||
ESPNOW_ECHO_PING = 30;
|
||||
/** Host → master: get/set ESP-IDF log level for tag "*" (global). */
|
||||
SET_LOG_LEVEL = 31;
|
||||
}
|
||||
|
||||
message UartMessage {
|
||||
@@ -67,6 +69,8 @@ message UartMessage {
|
||||
CacheStatusResponse cache_status_response = 34;
|
||||
EspNowEchoPingRequest espnow_echo_ping_request = 35;
|
||||
EspNowEchoPingResponse espnow_echo_ping_response = 36;
|
||||
SetLogLevelRequest set_log_level_request = 37;
|
||||
SetLogLevelResponse set_log_level_response = 38;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,6 +333,18 @@ message RestartResponse {
|
||||
uint32 client_id = 2;
|
||||
}
|
||||
|
||||
/** Host → master: read/write global log level (esp_log_level_set("*", …)). */
|
||||
message SetLogLevelRequest {
|
||||
bool write = 1;
|
||||
/** esp_log_level_t: 0=NONE, 1=ERROR, 2=WARN, 3=INFO, 4=DEBUG, 5=VERBOSE */
|
||||
uint32 level = 2;
|
||||
}
|
||||
|
||||
message SetLogLevelResponse {
|
||||
bool success = 1;
|
||||
uint32 level = 2;
|
||||
}
|
||||
|
||||
// Host → device: begin UART OTA (erase inactive OTA slot; device replies OTA_STATUS).
|
||||
message OtaStartPayload {
|
||||
uint32 total_size = 1;
|
||||
|
||||
Reference in New Issue
Block a user