ESP-IDF / STM32 开发环境与调试组件备忘(WSL 串口 · EasyLogger · Console 控制台)

3533 字约 9 分钟更新于 2026-10-010 次阅读#wsl#esp-idf#stm32#easylogger#console#嵌入式

这篇把三份「环境与调试组件」的备忘合在一起:WSL 里共享 USB 串口、STM32F1 上接 EasyLogger 日志、ESP-IDF 里加可交互控制台。都是开箱即用的最小步骤,需要的时候翻到对应小节即可。

一、WSL 里把 USB 串口共享给 ESP-IDF(usbipd)

相关命令必须在管理员权限打开的终端里运行,否则会失败。

  1. 先列出 USB 设备:
usbipd list

可以看到类似输出(要记下 BusID,例如 3-2):

3-2    303a:1001  USB 串行设备 (COM8), USB JTAG/serial debug unit               Shared (forced)
  1. 绑定设备:
usbipd bind --busid 3-2
  1. 挂载设备到 WSL:
usbipd attach --wsl --busid 3-2

WSL 串口共享

WSL 串口共享

之后在 WSL 里的 ESP-IDF 工程就能直接看到并烧录设备了。

二、STM32F1 上接入 EasyLogger(基于 USB 虚拟串口)

1. 资源下载

EasyLogger 的精简版(对我来说够用的那份),直接加入工程即可使用。

2. 配置打印函数

在 USB 虚拟串口实现中已经有 printf 了,把 EasyLogger 的输出接到它上面:

/**
 * output log port interface
 *
 * @param log output of log
 * @param size log size
 */
void elog_port_output(const char *log, size_t size) {
    /* add your code here */
    usb_printf("%.*s", size, log); //elog 的输出
}

如果是普通串口重定向,只要把 usb_printf 替换成自己的实现:

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
 
PUTCHAR_PROTOTYPE {
  HAL_UART_Transmit(&huart5, (uint8_t *) &ch, 1, HAL_MAX_DELAY);
  return ch;
}

3. 初始化并使用

#include "elog.h"
 
 
  /* USER CODE BEGIN 2 */
  easylogger_init();  // 初始化EasyLogger
  /* USER CODE END 2 */
 
 
 
  /* USER CODE BEGIN WHILE */
 
  while (1)
  {
    elog_info("main","Hello World!");
    HAL_Delay(1000);
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

下载运行,串口里就能看到日志了。

三、ESP-IDF:用 console_simple_init 加一个可交互控制台

调 ESP32 项目时常遇到这些场景:想临时执行一个命令看状态、想在线触发某个动作(比如开关某个外设)、又不想每次都改代码—烧录—看日志。这时候一个可交互 Console 就很有价值。这里记录一个通用做法:在任何 ESP-IDF 项目里用 espressif/console_simple_init 快速接入命令行控制台。

1. 为什么用它

原生 esp_console 功能很完整,但初始化流程相对分散。console_simple_init 的价值在于把常用步骤封装成了 4 个 API:

  • console_cmd_init():初始化控制台
  • console_cmd_user_register():注册用户命令
  • console_cmd_all_register():自动注册插件命令
  • console_cmd_start():启动 REPL

一句话:快速可用,适合先跑通再扩展。

2. 接入步骤

2.1 添加组件依赖

idf.py add-dependency "espressif/console_simple_init^1.1.0"

或者在 idf_component.yml 里手动添加:

dependencies:
  idf: ">=5.0"
  espressif/console_simple_init: ^1.1.0

2.2 在 CMake 里声明依赖

在你的组件 CMakeLists.txt(例如 main/CMakeLists.txt)里:

idf_component_register(
    SRCS "main.c"
    INCLUDE_DIRS "."
    REQUIRES console_simple_init console
)

这里建议把 console 显式写上,能避免一类常见的 include/IntelliSense 问题(后文会讲)。

2.3 在代码里初始化并注册命令

#include <stdio.h>
#include "esp_check.h"
#include "console_simple_init.h"
 
static int cmd_hello(int argc, char **argv)
{
    (void)argc;
    (void)argv;
    printf("hello from console\n");
    return 0;
}
 
void app_main(void)
{
    // 你的项目里需确保 NVS 和默认事件循环已初始化
 
    ESP_ERROR_CHECK(console_cmd_init());
    ESP_ERROR_CHECK(console_cmd_user_register("hello", cmd_hello));
    ESP_ERROR_CHECK(console_cmd_all_register()); // 可选
    ESP_ERROR_CHECK(console_cmd_start());
}

2.4 烧录后验证

idf.py flash monitor

在 esp> 提示符输入 help、hello,如果能看到输出,说明接入成功。

3. 一个很常见的坑:include 报错

现象:#include "console_simple_init.h" 报 include 错,或提示找不到 esp_console.h。

本质:console_simple_init.h 会依赖 esp_console.h,如果你的组件没有显式依赖 console,编辑器索引有时会解析不到。

解决:

  1. CMake 增加 REQUIRES console
  2. 执行:
idf.py reconfigure
idf.py build
  1. 在 VS Code 刷新索引(Reset IntelliSense Database + Reload Window)

4. 另一个常见坑:串口写入超时

现象:Monitor 日志里反复出现 Writing to serial is timing out...

本质:Console 所用的通道(UART / USB CDC / USB Serial/JTAG)和你当前 monitor 连接的端口不一致。

解决:在 menuconfig 里把 console 输出通道配置成和实际连接一致:

  • Component config -> ESP System Settings -> Channel for console output

改完后重新 build + flash。

5. 为什么它适合做「运维入口」

当项目复杂起来后,你会很自然地需要这些命令:

  • status:看系统状态
  • sensor:看传感器实时值
  • pump on/off:控制执行器
  • wifi status:看联网状态

有了 console,这些能力都能在不改 UI 的情况下快速加上。

6. 我建议的演进路线

  1. 先做 1~2 个命令跑通链路
  2. 加参数解析和错误提示
  3. 按模块分组命令(sensor/io/net)
  4. 给危险动作加确认机制

7. 小结

console_simple_init 的优势不是「功能比 esp_console 更多」,而是把接入门槛降得很低:依赖加上、几个 API 调用,很快就能得到可交互的调试入口。对于早期开发和现场调试,它能显著减少反复烧录的成本。

相关文章


评论