B站演示视频
说明链接

发现一款数据记录仪,方便记录串口的数据
主要功能

1.支持固件升级,双串口接收。
2.RTC毫秒级时间戳。(RTC月误差±15s)
4.支持虚拟串口、U盘功能、独有U盘显示图标。
5.支持中英文记录、CSV记录、TXT记录、HEX记录,时间戳。
6.支持SD卡热插拔。
7.波特率可达2000000(可修改)。
8.双串口缓冲6KB字节。
9.存满覆盖,不丢数据。
10.可双文件存储。

在这里插入图片描述
贴一个自用的简单好用的日志系统

#ifndef __DEBUG_LOG_H
#define __DEBUG_LOG_H

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdio.h>
#include <string.h>
#include "main.h"
#define USE_FREERTOS
#define CURRENT_LOG_LEVEL LOG_LEVEL_DEBUG
// FreeRTOS 支持
#ifdef USE_FREERTOS
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#endif

// 日志等级宏定义
#define LOG_LEVEL_NONE (-1) // 不打印任何信息
#define LOG_LEVEL_ERROR 0   // 错误信息
#define LOG_LEVEL_WARNING 1 // 警告信息
#define LOG_LEVEL_INFO 2    // 一般信息
#define LOG_LEVEL_DEBUG 3   // 调试信息
#define LOG_LEVEL_VERBOSE 4 // 详细调试信息

// 当前日志等级配置
#ifndef CURRENT_LOG_LEVEL
#define CURRENT_LOG_LEVEL LOG_LEVEL_INFO // 默认信息级别
#endif

// 获取短文件名(去掉路径)
#ifdef __FILE_NAME__
#define SHORT_FILE __FILE_NAME__
#else
#define SHORT_FILE (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 \
                                                                                                  : __FILE__)
#endif

// 换行符定义(Windows风格)
#define LOG_NEWLINE "\r\n"

// 互斥锁操作宏
#ifdef USE_FREERTOS
#define LOG_LOCK()                          \
    do                                      \
    {                                       \
        if (log_mutex != NULL)              \
            xSemaphoreTake(log_mutex, 100); \
    } while (0)
#define LOG_UNLOCK()                   \
    do                                 \
    {                                  \
        if (log_mutex != NULL)         \
            xSemaphoreGive(log_mutex); \
    } while (0)
#else
#define LOG_LOCK() ((void)0) // 单线程环境,空操作
#define LOG_UNLOCK() ((void)0)
#endif

// 空打印宏(当设置为NONE等级时使用)
#if CURRENT_LOG_LEVEL == LOG_LEVEL_NONE
// 空打印宏定义
#define debug_printf(level, format, ...) ((void)0)
#define LOG_ERROR(format, ...) ((void)0)
#define LOG_WARNING(format, ...) ((void)0)
#define LOG_INFO(format, ...) ((void)0)
#define LOG_DEBUG(format, ...) ((void)0)
#define LOG_VERBOSE(format, ...) ((void)0)
#define LOG(format, ...) ((void)0)
#define log_printf(level, format, ...) ((void)0)
#else
// 基础调试打印宏(包含文件、行号、函数名)- 线程安全版本
#define debug_printf(level, format, ...)                               \
    do                                                                 \
    {                                                                  \
        if ((level) <= CURRENT_LOG_LEVEL)                              \
        {                                                              \
            LOG_LOCK();                                                \
            printf("[%s:%d %s] ", SHORT_FILE, __LINE__, __FUNCTION__); \
            printf(format, ##__VA_ARGS__);                             \
            printf(LOG_NEWLINE);                                       \
            LOG_UNLOCK();                                              \
        }                                                              \
    } while (0)

// 各等级专用宏
#define LOG_ERROR(format, ...) debug_printf(LOG_LEVEL_ERROR, format, ##__VA_ARGS__)
#define LOG_WARNING(format, ...) debug_printf(LOG_LEVEL_WARNING, format, ##__VA_ARGS__)
#define LOG_INFO(format, ...) debug_printf(LOG_LEVEL_INFO, format, ##__VA_ARGS__)
#define LOG_DEBUG(format, ...) debug_printf(LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
#define LOG_VERBOSE(format, ...) debug_printf(LOG_LEVEL_VERBOSE, format, ##__VA_ARGS__)

// 简化版本(不显示等级,始终打印)- 线程安全版本
#define LOG(format, ...)                                                                             \
    do                                                                                               \
    {                                                                                                \
        LOG_LOCK();                                                                                  \
        printf("[%s:%d %s] " format LOG_NEWLINE, SHORT_FILE, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
        LOG_UNLOCK();                                                                                \
    } while (0)

// 通用打印宏(可指定等级)- 线程安全版本
#define log_printf(level, format, ...) debug_printf(level, format, ##__VA_ARGS__)
#endif

// 强制打印宏(即使设置为NONE等级也会打印)- 线程安全版本
#define LOG_FORCE(format, ...)                                                                       \
    do                                                                                               \
    {                                                                                                \
        LOG_LOCK();                                                                                  \
        printf("[%s:%d %s] " format LOG_NEWLINE, SHORT_FILE, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
        LOG_UNLOCK();                                                                                \
    } while (0)

    // 函数声明
    void log_set_level(int level);
    int log_get_level(void);
    const char *log_level_to_string(int level);
    int log_is_enabled(void);

// FreeRTOS 相关函数
#ifdef USE_FREERTOS
    int log_init_mutex(void);
    void log_deinit_mutex(void);
    SemaphoreHandle_t get_log_mutex(void);
#endif

// 声明互斥锁句柄
#ifdef USE_FREERTOS
    extern SemaphoreHandle_t log_mutex;
#endif

#ifdef __cplusplus
}
#endif

#endif /* __DEBUG_LOG_H */

/**
 * ****************************************************************************************
 * @File Name  : debug_log.c
 * @Author     : Q群 275391353
 * @Version    : v1.0
 * @Creat Date : 2025-09-24
 * @brief      :
 * @License    : Copyright (c) 2025
 * ****************************************************************************************
 * 【未经作者许可,不得用于其它任何用途】
 * Change Logs:
 * Date           Author           Notes
 * 2025-09-24     Q群 275391353    the first version
 * ****************************************************************************************
 * Notice:
 * 1.
 * ****************************************************************************************
 */
#include "debug_log.h"

// 当前日志等级(运行时可修改)
static int current_log_level = CURRENT_LOG_LEVEL;

// FreeRTOS 互斥锁句柄
#ifdef USE_FREERTOS
SemaphoreHandle_t log_mutex = NULL;
#endif

/**
 * @brief  初始化日志互斥锁(FreeRTOS环境使用)
 * @retval 0-成功, -1-失败
 */
#ifdef USE_FREERTOS
int log_init_mutex(void)
{
    if (log_mutex == NULL)
    {
        log_mutex = xSemaphoreCreateMutex();
        if (log_mutex == NULL)
        {
            return -1; // 创建失败
        }
        LOG_DEBUG("日志互斥锁初始化成功");
    }
    return 0;
}
#endif

/**
 * @brief  反初始化日志互斥锁
 */
#ifdef USE_FREERTOS
void log_deinit_mutex(void)
{
    if (log_mutex != NULL)
    {
        vSemaphoreDelete(log_mutex);
        log_mutex = NULL;
        LOG_DEBUG("日志互斥锁已释放");
    }
}
#endif

/**
 * @brief  获取日志互斥锁句柄
 * @retval 互斥锁句柄
 */
#ifdef USE_FREERTOS
SemaphoreHandle_t get_log_mutex(void)
{
    return log_mutex;
}
#endif

/**
 * @brief  设置日志等级
 * @param  level: 要设置的日志等级
 */
void log_set_level(int level)
{
#ifdef USE_FREERTOS
    LOG_LOCK();
#endif

    current_log_level = level;
    if (level != LOG_LEVEL_NONE)
    {
        // 注意:这里使用 printf 直接输出避免死锁
        printf("[LOG_INIT] 日志等级设置为: %s\r\n", log_level_to_string(level));
    }

#ifdef USE_FREERTOS
    LOG_UNLOCK();
#endif
}

/**
 * @brief  获取当前日志等级
 * @retval 当前日志等级
 */
int log_get_level(void)
{
    int level;

#ifdef USE_FREERTOS
    LOG_LOCK();
#endif

    level = current_log_level;

#ifdef USE_FREERTOS
    LOG_UNLOCK();
#endif

    return level;
}

/**
 * @brief  检查日志是否启用
 * @retval 1-启用, 0-禁用
 */
int log_is_enabled(void)
{
    int enabled;

#ifdef USE_FREERTOS
    LOG_LOCK();
#endif

    enabled = (current_log_level != LOG_LEVEL_NONE);

#ifdef USE_FREERTOS
    LOG_UNLOCK();
#endif

    return enabled;
}

/**
 * @brief  将日志等级转换为字符串
 * @param  level: 日志等级
 * @retval 等级对应的字符串
 */
const char *log_level_to_string(int level)
{
    switch (level)
    {
    case LOG_LEVEL_NONE:
        return "NONE";
    case LOG_LEVEL_ERROR:
        return "ERROR";
    case LOG_LEVEL_WARNING:
        return "WARNING";
    case LOG_LEVEL_INFO:
        return "INFO";
    case LOG_LEVEL_DEBUG:
        return "DEBUG";
    case LOG_LEVEL_VERBOSE:
        return "VERBOSE";
    default:
        return "UNKNOWN";
    }
}

串口助手AT指令集
1.usb_shell_en 默认为 1,即打开虚拟串口。
2.通过Type-C接口进行参数设置,丰富的指令集。
3.通过Type-C接口进行固件升级。

在这里插入图片描述
专属U盘
1.专属U盘图标,专属盘符标识。
2.可通过Type-C接口导入和导出文件。
3.通过U盘模式,配置param_config.txt文件。
4.导入固件,重启自动升级固件。

在这里插入图片描述
目录
1.按年月日生成多级目录,方便文件管理。

在这里插入图片描述

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐