serial log on webserver
Some checks failed
ESP32 Build & Release / build (push) Failing after 15s

This commit is contained in:
2026-09-16 17:08:26 +02:00
parent dd04016fc3
commit 9c5f62b6de
7 changed files with 469 additions and 8 deletions

152
main/serial_log.c Normal file
View File

@@ -0,0 +1,152 @@
/*
* MTG RFID Companion - In-memory Serial Log Ring Buffer
*/
#include "serial_log.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define LOG_BUFFER_SIZE (16 * 1024)
static vprintf_like_t s_prev_vprintf = NULL;
static char s_ring_buffer[LOG_BUFFER_SIZE];
static uint32_t s_write_idx = 0;
static uint32_t s_total_bytes = 0;
static portMUX_TYPE s_log_mux = portMUX_INITIALIZER_UNLOCKED;
static int serial_log_vprintf(const char *fmt, va_list args)
{
int ret = 0;
/* Maintain original console/UART output */
if (s_prev_vprintf != NULL) {
va_list copy1;
va_copy(copy1, args);
ret = s_prev_vprintf(fmt, copy1);
va_end(copy1);
} else {
va_list copy1;
va_copy(copy1, args);
ret = vprintf(fmt, copy1);
va_end(copy1);
}
/* Format message into local buffer */
char line_buf[512];
va_list copy2;
va_copy(copy2, args);
int written = vsnprintf(line_buf, sizeof(line_buf), fmt, copy2);
va_end(copy2);
if (written > 0) {
size_t len = (size_t)written;
if (len >= sizeof(line_buf)) {
len = sizeof(line_buf) - 1;
}
portENTER_CRITICAL(&s_log_mux);
size_t space_to_end = LOG_BUFFER_SIZE - s_write_idx;
if (len <= space_to_end) {
memcpy(&s_ring_buffer[s_write_idx], line_buf, len);
s_write_idx = (s_write_idx + len) % LOG_BUFFER_SIZE;
} else {
memcpy(&s_ring_buffer[s_write_idx], line_buf, space_to_end);
memcpy(&s_ring_buffer[0], line_buf + space_to_end, len - space_to_end);
s_write_idx = (uint32_t)(len - space_to_end);
}
s_total_bytes += (uint32_t)len;
portEXIT_CRITICAL(&s_log_mux);
}
return ret;
}
esp_err_t serial_log_init(void)
{
portENTER_CRITICAL(&s_log_mux);
s_total_bytes = 0;
s_write_idx = 0;
memset(s_ring_buffer, 0, sizeof(s_ring_buffer));
portEXIT_CRITICAL(&s_log_mux);
s_prev_vprintf = esp_log_set_vprintf(serial_log_vprintf);
return ESP_OK;
}
size_t serial_log_read(uint32_t from_offset, char *dest, size_t max_len, uint32_t *next_offset)
{
if (!dest || max_len == 0) {
if (next_offset) {
*next_offset = from_offset;
}
return 0;
}
size_t copied = 0;
portENTER_CRITICAL(&s_log_mux);
uint32_t total = s_total_bytes;
uint32_t oldest = (total > LOG_BUFFER_SIZE) ? (total - LOG_BUFFER_SIZE) : 0;
if (from_offset < oldest || from_offset == 0) {
from_offset = oldest;
}
if (from_offset >= total) {
if (next_offset) {
*next_offset = total;
}
dest[0] = '\0';
portEXIT_CRITICAL(&s_log_mux);
return 0;
}
uint32_t to_read = total - from_offset;
if (to_read > (uint32_t)(max_len - 1)) {
to_read = (uint32_t)(max_len - 1);
}
size_t start_idx = from_offset % LOG_BUFFER_SIZE;
size_t chunk1 = LOG_BUFFER_SIZE - start_idx;
if (to_read <= chunk1) {
memcpy(dest, &s_ring_buffer[start_idx], to_read);
} else {
memcpy(dest, &s_ring_buffer[start_idx], chunk1);
memcpy(dest + chunk1, &s_ring_buffer[0], to_read - chunk1);
}
copied = to_read;
dest[copied] = '\0';
if (next_offset) {
*next_offset = from_offset + (uint32_t)to_read;
}
portEXIT_CRITICAL(&s_log_mux);
return copied;
}
void serial_log_clear(void)
{
portENTER_CRITICAL(&s_log_mux);
s_total_bytes = 0;
s_write_idx = 0;
memset(s_ring_buffer, 0, sizeof(s_ring_buffer));
portEXIT_CRITICAL(&s_log_mux);
}
uint32_t serial_log_get_total_bytes(void)
{
uint32_t total;
portENTER_CRITICAL(&s_log_mux);
total = s_total_bytes;
portEXIT_CRITICAL(&s_log_mux);
return total;
}