All checks were successful
Build ESP32 BMC Firmware / build (push) Successful in 53s
139 lines
2.9 KiB
C
139 lines
2.9 KiB
C
#include "log_handler.h"
|
|
#include "esp_log.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/semphr.h"
|
|
#include <string.h>
|
|
|
|
static const char *TAG = "LOG_HANDLER";
|
|
|
|
// Ring buffer for logs
|
|
#define LOG_BUFFER_SIZE 8192
|
|
static char log_buffer[LOG_BUFFER_SIZE];
|
|
static size_t log_write_pos = 0;
|
|
static size_t log_read_pos = 0;
|
|
static size_t log_count = 0;
|
|
static SemaphoreHandle_t log_mutex = NULL;
|
|
static bool log_initialized = false;
|
|
|
|
// Vprintf callback for capturing logs
|
|
static int log_vprintf_cb(const char *fmt, va_list args) {
|
|
// First, call the default vprintf to output to console
|
|
int ret = vprintf(fmt, args);
|
|
|
|
// Then, capture to our ring buffer
|
|
if (log_mutex && log_initialized) {
|
|
char temp_buf[256];
|
|
int len = vsnprintf(temp_buf, sizeof(temp_buf), fmt, args);
|
|
if (len > 0 && len < (int)sizeof(temp_buf)) {
|
|
xSemaphoreTake(log_mutex, portMAX_DELAY);
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
log_buffer[log_write_pos] = temp_buf[i];
|
|
log_write_pos = (log_write_pos + 1) % LOG_BUFFER_SIZE;
|
|
|
|
if (log_count < LOG_BUFFER_SIZE) {
|
|
log_count++;
|
|
} else {
|
|
// Buffer full, advance read position
|
|
log_read_pos = (log_read_pos + 1) % LOG_BUFFER_SIZE;
|
|
}
|
|
}
|
|
|
|
xSemaphoreGive(log_mutex);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
esp_err_t log_handler_init(void) {
|
|
if (log_initialized) {
|
|
ESP_LOGW(TAG, "Log handler already initialized");
|
|
return ESP_OK;
|
|
}
|
|
|
|
ESP_LOGI(TAG, "Initializing log handler");
|
|
|
|
log_mutex = xSemaphoreCreateMutex();
|
|
if (!log_mutex) {
|
|
ESP_LOGE(TAG, "Failed to create log mutex");
|
|
return ESP_ERR_NO_MEM;
|
|
}
|
|
|
|
log_write_pos = 0;
|
|
log_read_pos = 0;
|
|
log_count = 0;
|
|
memset(log_buffer, 0, LOG_BUFFER_SIZE);
|
|
|
|
// Set our custom vprintf function
|
|
esp_log_set_vprintf(log_vprintf_cb);
|
|
|
|
log_initialized = true;
|
|
ESP_LOGI(TAG, "Log handler initialized");
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t log_handler_deinit(void) {
|
|
if (!log_initialized) {
|
|
return ESP_OK;
|
|
}
|
|
|
|
ESP_LOGI(TAG, "Deinitializing log handler");
|
|
|
|
// Restore default vprintf
|
|
esp_log_set_vprintf(vprintf);
|
|
|
|
if (log_mutex) {
|
|
vSemaphoreDelete(log_mutex);
|
|
log_mutex = NULL;
|
|
}
|
|
|
|
log_initialized = false;
|
|
return ESP_OK;
|
|
}
|
|
|
|
size_t log_get_buffer(char *buf, size_t buf_len) {
|
|
if (!buf || buf_len == 0 || !log_mutex) {
|
|
return 0;
|
|
}
|
|
|
|
xSemaphoreTake(log_mutex, portMAX_DELAY);
|
|
|
|
size_t to_copy = (log_count < buf_len) ? log_count : buf_len;
|
|
size_t copied = 0;
|
|
|
|
for (size_t i = 0; i < to_copy; i++) {
|
|
size_t pos = (log_read_pos + i) % LOG_BUFFER_SIZE;
|
|
buf[copied++] = log_buffer[pos];
|
|
}
|
|
|
|
xSemaphoreGive(log_mutex);
|
|
|
|
return copied;
|
|
}
|
|
|
|
void log_clear_buffer(void) {
|
|
if (!log_mutex) {
|
|
return;
|
|
}
|
|
|
|
xSemaphoreTake(log_mutex, portMAX_DELAY);
|
|
log_write_pos = 0;
|
|
log_read_pos = 0;
|
|
log_count = 0;
|
|
xSemaphoreGive(log_mutex);
|
|
}
|
|
|
|
size_t log_get_size(void) {
|
|
if (!log_mutex) {
|
|
return 0;
|
|
}
|
|
|
|
xSemaphoreTake(log_mutex, portMAX_DELAY);
|
|
size_t count = log_count;
|
|
xSemaphoreGive(log_mutex);
|
|
|
|
return count;
|
|
}
|