#include "log.h" #include "24c02.h" #include #include "FreeRTOS.h" #include "task.h" #include "semphr.h" static LogLevel current_level = LOG_DEBUG; // LOG_WARN;//LOG_DEBUG; /* 日志输出互斥锁:多任务并发打印时防止日志交织(调度器启动前为空操作) */ static SemaphoreHandle_t s_log_mutex = NULL; void log_lock_init(void) { s_log_mutex = xSemaphoreCreateMutex(); } /* 日志等级 EEPROM 偏移(160,避开其它占用) */ #define LOG_LEVEL_ADDR 160 /* 开机读取保存的日志等级(非法值回退 DEBUG 并落盘) */ void log_load_level(void) { uint8_t lv = LOG_DEBUG; eepromReadData(LOG_LEVEL_ADDR, &lv, 1); if (lv > LOG_FATAL) { lv = LOG_DEBUG; eepromWriteData(LOG_LEVEL_ADDR, &lv, 1); } current_level = (LogLevel)lv; } LogLevel log_get_level(void) { return current_level; } void log_set_level(LogLevel level) { current_level = level; uint8_t lv = (uint8_t)level; /* 断电不丢 */ eepromWriteData(LOG_LEVEL_ADDR, &lv, 1); } /* Output log message via USART1 (HAL) */ static void _log_print(LogLevel level, const char *tag, const char *fmt, va_list args) { if (current_level <= level) { char buf[256]; int len = vsnprintf(buf, sizeof(buf) - 2, fmt, args); uint8_t locked = 0; if (s_log_mutex && xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) { xSemaphoreTake(s_log_mutex, portMAX_DELAY); locked = 1; } /* USART1 already inited when log is called */ extern UART_HandleTypeDef huart1; HAL_UART_Transmit(&huart1, (uint8_t *)"[", 1, 100); HAL_UART_Transmit(&huart1, (uint8_t *)tag, strlen(tag), 100); HAL_UART_Transmit(&huart1, (uint8_t *)"] ", 2, 100); HAL_UART_Transmit(&huart1, (uint8_t *)buf, len, 500); HAL_UART_Transmit(&huart1, (uint8_t *)"\r\n", 2, 100); if (locked) xSemaphoreGive(s_log_mutex); } } void log_debug(const char *fmt, ...) { va_list args; va_start(args, fmt); _log_print(LOG_DEBUG, "DEBUG", fmt, args); va_end(args); } void log_info(const char *fmt, ...) { va_list args; va_start(args, fmt); _log_print(LOG_INFO, "INFO", fmt, args); va_end(args); } void log_warn(const char *fmt, ...) { va_list args; va_start(args, fmt); _log_print(LOG_WARN, "WARN", fmt, args); va_end(args); } void log_error(const char *fmt, ...) { va_list args; va_start(args, fmt); _log_print(LOG_ERROR, "ERROR", fmt, args); va_end(args); }