e6a9965d22
- debug_log.h/cpp: ring buffer with 100 entries in SDRAM, dual output to serial - main.cpp: add log_init() initialization - packer_ui.cpp: add LOG_INFO at start/reset/minus/plus/pack-complete events - tools/capture_log.py: PC-side serial log capture with timestamped files
109 lines
2.7 KiB
C++
109 lines
2.7 KiB
C++
#include "debug_log.h"
|
|
#include <rtthread.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
static log_entry_t log_buf[LOG_BUF_SIZE] __attribute__((section(".sdram")));
|
|
static uint32_t write_idx = 0;
|
|
static uint32_t total_count = 0;
|
|
static bool initialized = false;
|
|
|
|
void log_init(void)
|
|
{
|
|
if (!initialized)
|
|
{
|
|
memset(log_buf, 0, sizeof(log_buf));
|
|
write_idx = 0;
|
|
total_count = 0;
|
|
initialized = true;
|
|
LOG_INFO("Debug log system initialized, %d entries buffer", LOG_BUF_SIZE);
|
|
}
|
|
}
|
|
|
|
void log_write(log_level_t level, const char *file, int line, const char *func, const char *fmt, ...)
|
|
{
|
|
if (!initialized) return;
|
|
|
|
uint32_t idx = write_idx % LOG_BUF_SIZE;
|
|
log_entry_t *entry = &log_buf[idx];
|
|
|
|
entry->tick = rt_tick_get();
|
|
entry->level = level;
|
|
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
rt_snprintf(entry->message, LOG_MSG_MAX, "[%s:%d] ", file, line);
|
|
uint32_t prefix_len = strlen(entry->message);
|
|
rt_vsnprintf(entry->message + prefix_len, LOG_MSG_MAX - prefix_len, fmt, args);
|
|
va_end(args);
|
|
|
|
write_idx++;
|
|
total_count++;
|
|
|
|
const char *level_str = "I";
|
|
if (level == LOG_LEVEL_WARN) level_str = "W";
|
|
else if (level == LOG_LEVEL_ERROR) level_str = "E";
|
|
|
|
printf("[%lu][%s] %s\r\n",
|
|
(unsigned long)entry->tick,
|
|
level_str,
|
|
entry->message);
|
|
}
|
|
|
|
void log_dump(void)
|
|
{
|
|
printf("\r\n========== DEBUG LOG DUMP ==========\r\n");
|
|
printf("Total entries: %lu, Buffer slots: %d\r\n",
|
|
(unsigned long)total_count, LOG_BUF_SIZE);
|
|
printf("====================================\r\n");
|
|
|
|
if (total_count == 0)
|
|
{
|
|
printf("(no log entries)\r\n");
|
|
return;
|
|
}
|
|
|
|
uint32_t start = 0;
|
|
uint32_t count = LOG_BUF_SIZE;
|
|
if (total_count < LOG_BUF_SIZE)
|
|
{
|
|
start = 0;
|
|
count = total_count;
|
|
}
|
|
else
|
|
{
|
|
start = write_idx % LOG_BUF_SIZE;
|
|
}
|
|
|
|
for (uint32_t i = 0; i < count; i++)
|
|
{
|
|
uint32_t idx = (start + i) % LOG_BUF_SIZE;
|
|
const log_entry_t *entry = &log_buf[idx];
|
|
if (entry->tick == 0 && entry->message[0] == '\0')
|
|
continue;
|
|
|
|
const char *level_str = "INFO";
|
|
if (entry->level == LOG_LEVEL_WARN) level_str = "WARN";
|
|
else if (entry->level == LOG_LEVEL_ERROR) level_str = "ERROR";
|
|
|
|
printf("[%06lu][%s] %s\r\n",
|
|
(unsigned long)entry->tick,
|
|
level_str,
|
|
entry->message);
|
|
}
|
|
|
|
printf("========== DUMP END ==========\r\n");
|
|
}
|
|
|
|
uint32_t log_count(void)
|
|
{
|
|
return total_count;
|
|
}
|
|
|
|
const log_entry_t *log_get_entry(uint32_t index)
|
|
{
|
|
if (index >= LOG_BUF_SIZE) return NULL;
|
|
return &log_buf[index];
|
|
}
|