
ESP-IDF USB 串行/JTAG 控制器控制台完整指南免外部 USB-UART 桥接芯片的串口、烧录与 JTAG 调试方案【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf本文以 ESP-IDF 官方文档《USB 串行/JTAG 控制器控制台》为主体结合仓库内驱动源码与示例系统讲解内置 USB 串行/JTAGUSJ控制器的硬件接线、软件配置、程序烧录、数据缓冲行为、睡眠模式限制以及实际应用帮助开发者在支持该控制器的 ESP 芯片上摆脱外部 USB-UART 桥接芯片直接通过一条 USB 线完成串口监视、固件烧录与 JTAG 调试。USB 串行/JTAG 控制器是什么ESP 芯片通常使用 UART 实现串口并通过外部 USB-UART 桥接芯片连接到主机/PC 上的串口控制台仿真器。而在具备 USB 串行/JTAG 控制器的 ESP 芯片上控制器的 CDC-ACM 部分本身即可实现串口功能该串口直接连接到主机/PC不需要外部 USB-UART 桥接芯片。拥有 USB 串行/JTAG 控制器时芯片支持以下能力双向串行控制台可与 IDF 监视器idf.py monitor或其他串行监视器一起使用使用esptool和idf.py flash烧录固件使用 OpenOCD 等工具进行 JTAG 调试同时进行串行操作。需要注意一个关键事实USB 串行/JTAG 控制器是一个USB 设备其功能固定、完全由硬件实现。即便重新配置它也只能执行串口和 JTAG 调试功能。这不同于某些 ESP 芯片中的 USB OTG 控制器后者经配置可以执行多种 USB 设备功能如 CDC、MSC、HID 等。从源码结构看components/esp_driver_usb_serial_jtag/目录中仅有驱动、VFS 适配与连接监控三个核心源文件功能边界非常清晰usb_serial_jtag.c 中注释也明确指出 The USB-serial-JTAG is a simple device, it shouldnt need anything more than a simple, straightforward driver.硬件要求与接线将芯片连接到 USB 端口时需要按下表连接 GPIO 与 USB 引脚。不同芯片型号对应的 D / D- 引脚不同GPIOUSBD 引脚见下表D绿D- 引脚见下表D-白GNDGND黑5V或由外部提供5V红各芯片的 D/D- 引脚对照如下ESP32-C3D GPIO19D- GPIO18ESP32-S3D GPIO20D- GPIO19ESP32-C6D GPIO13D- GPIO12ESP32-H2D GPIO27D- GPIO26ESP32-P4D GPIO25/27D- GPIO24/26ESP32-C5D GPIO14D- GPIO13ESP32-C61D GPIO13D- GPIO12ESP32-H4D GPIO14D- GPIO13部分开发板会为 USB 串行/JTAG 控制器直接提供 USB 连接器此时无需额外接线直接插入 USB 线即可。软件配置将 USJ 配置为系统控制台主控制台在menuconfig中打开Component config → ESP System Settings → Channel for console output在CONFIG_ESP_CONSOLE_UART选项中选择CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG即可将 USB 串行/JTAG 控制器用作串口控制台。选择该选项后即可正常构建和烧录项目。该选项在 ESP-IDF 内部通过条件编译生效在 usb_serial_jtag_vfs.c 中CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG定义时会通过ESP_SYSTEM_INIT_FN(init_vfs_usj, ...)在系统启动阶段注册 VFS 文件系统挂载点为/dev/usbserjtag注释说明/dev/usb_serial_jtag对 VFS 而言过长并自动安装驱动将printf/scanf等标准 I/O 重定向到 USJ 端口。辅助控制台仅输出另外也可以通过usb_serial_jtag端口访问输出但需要确保在CONFIG_ESP_CONSOLE_SECONDARY选项中选择了CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG。对应源码中该选项会触发ESP_SYSTEM_INIT_FN(init_vfs_usj_sec, ...)将 USJ 注册为辅助 VFS 端口挂载点/dev/secondary见 usb_serial_jtag_vfs.c。警告除输出外如果还想使用控制台输入或使用交互式解释器REPL必须选择CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG选项仅配置辅助端口无法获得输入能力。禁用 USJ 模块省电在components/esp_driver_usb_serial_jtag/Kconfig中还提供了USJ_ENABLE_USB_SERIAL_JTAG选项默认开启其帮助文本说明该模块在芯片上电后默认打开若应用不需要它作为系统控制台或不需要内置 JTAG 调试可以关闭该选项此时模块时钟会在启动时被关闭以节省功耗。注意该选项只在应用阶段禁用 USJbootloader 阶段仍保持启用因此仍可通过下载模式烧录芯片若要完全禁用需要烧录EFUSE_DIS_USB_SERIAL_JTAGeFuse。上传应用程序烧录USB 串行/JTAG 控制器可以自动将芯片置于下载模式用户只需正常烧录芯片但需要在系统上指定 USB 串行/JTAG 控制器端口idf.py flash -p PORT其中PORT是正确的端口名称。USB 串行/JTAG 控制器的串行端口在不同系统上的命名规律Linux显示为/dev/ttyACM*macOS显示为/dev/cu*Windows在设备管理器中显示为COM*端口源码视角数据通路与缓冲原理理解 USJ 的缓冲行为有助于排查输出丢数据、卡顿等现场问题。从 usb_serial_jtag.c 源码可以还原其数据通路硬件层 TX/RX FIFO 最大为64 字节USB_SER_JTAG_ENDP_SIZE宏即一个 USB 端点的最大载荷驱动安装时会创建 TX 与 RX 两个 RingBuffer默认各 256 字节见 usb_serial_jtag.h 的USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT()TX/RX 缓冲区大小均可配置且必须大于 0RX 路径ISR 收到SERIAL_OUT_RECV_PKT中断后将 RX FIFO 中的最多 64 字节搬入 RX RingBuffer应用通过usb_serial_jtag_read_bytes()读取TX 路径ISR 在SERIAL_IN_EMPTY中断时把 TX RingBuffer 中的数据送入 FIFO 并 flush当一次未能全部发送时剩余字节会暂存到tx_stash_bufstash 缓冲区发送满 64 字节的整包后驱动会再次 flush 以发送 0 字节包通知主机本次传输结束否则这 64 字节会滞留在主机缓冲区中usb_serial_jtag.c 的注释详细说明了这一 USB 传输语义。50 ms 输出缓冲超时对于从芯片发送到 PC 终端的数据如 stdout、日志芯片会先写入一个小型内部缓冲区。如果该缓冲区达到最大容量例如没有连接 PC 终端芯片会进行一次等待时长约50 ms。在此期间PC 终端可以请求数据但可能会导致应用程序出现非常短暂的暂停。源码中对应宏为TX_FLUSH_TIMEOUT_US (50*1000LL)见 usb_serial_jtag_vfs.c。实现逻辑是如果没有主机在监听 CDC-ACM 端口TX 缓冲区永远无法 flush 到主机此时发送例程不会无限等待——若缓冲区内数据在 50 ms 内始终未被主机取走就会放弃drop这些字节直到缓冲区重新可写为止。代码注释还给出参考无负载的 USB 总线大约每个 USB 帧1 ms尝试取一次 TX 数据50 ms 的较长超时是为了容忍满载总线的情况。输入方向的流控差异对于从 PC 终端发送到芯片的数据如控制台命令许多 PC 终端会等待芯片接收字节后再允许发送更多数据。这与使用 USB 转串口UART桥接芯片不同UART 桥接芯片始终接收字节并将其发送到可能未在监听的芯片。注意在极少数情况下从芯片发送到主机的数据可能会阻塞在主机内存中。继续发送数据即可取消阻塞但如果应用程序未继续发送数据则需要手动将这些数据刷新到主机。能否继续发送数据取决于驱动程序默认配置的非阻塞驱动程序和 VFS 实现会在换行后自动刷新源码中usb_serial_jtag_tx_char_no_driver()在发送\n时会调用usb_serial_jtag_ll_txfifo_flush()而基于中断的阻塞驱动程序会在发送缓冲区变空时自动刷新。使用限制与注意事项USB 串行/JTAG 控制台功能存在一些限制影响程度取决于开发中的应用程序类型以及开发工作流。重新配置 USB 管脚如果在意外情况下应用程序重新配置了 USB 外设管脚或禁用了 USB 串行/JTAG 控制器设备会从系统消失。应用程序中的问题修复后需要将 BOOT 引脚拉低并重置芯片手动将芯片置于下载模式。BOOT 引脚因芯片而异ESP32-C3 为 GPIO9ESP32-S3 为 GPIO0ESP32-C6 为 GPIO9其余芯片请参考对应芯片的 Boot 引脚定义。如果应用程序进入 Deep-sleep 模式USB 串行/JTAG 设备同样会从系统中消失。睡眠模式考虑因素USB 串行/JTAG 控制器及其关联的 USB PHY 均由特定时钟控制如 APB 和 USB PHY 时钟并属于特定的电源域如数字电源域。因此对 USB 串行/JTAG 控制器关联的时钟和电源域进行任何更改如进入另一睡眠模式都可能影响控制器操作。Deep-sleep进入 Deep-sleep 模式时USB 串行/JTAG 控制器及 USB PHY 关闭导致 USB PHY 的 D 线不再变为高电平。因此进入 Deep-sleep 模式时USB 串行/JTAG 设备会对主机/PC 显示为断开连接即使 USB 电缆在物理层面处于连接状态仍显示为断开退出 Deep-sleep 模式时USB 串行/JTAG 设备会重新连接到主机/PC。Light-sleep对于不支持 Light-sleep 保持的芯片进入 Light-sleep 模式时 APB 和 USB PHY 时钟关闭USB 串行/JTAG 控制器将无法接收或响应任何来自相连主机的 USB 事务包括周期性的 CDC Data IN 事务。因此进入 Light-sleep 模式时USB 串行/JTAG 设备无法响应主机/PC 的 USB CDC 驱动程序主机/PC 可能报告设备已断开连接或连接出错即使 USB 电缆物理层面仍处于连接状态退出 Light-sleep 模式时由于 USB PHY 的 D 线在 Light-sleep 期间始终处于高电平可能导致主机/PC 不会重新枚举重新连接USB 串行/JTAG 设备用户可能需要在物理层面断开并重新连接 USB 电缆。自动与手动进入睡眠模式如果通过esp_light_sleep_start()或esp_deep_sleep_start()手动进入睡眠模式需要注意USB 串行/JTAG 控制器在睡眠期间不工作ESP-IDF没有添加任何拒绝进入睡眠的安全检查即使 USB 串行/JTAG 控制器已连接也会进入睡眠模式。如果在连接了 USJ 的情况下进入睡眠可以通过拔出并重新插入 USB 电缆来重新建立连接。如果通过esp_pm_configure()自动进入睡眠模式请启用CONFIG_USJ_NO_AUTO_LS_ON_CONNECTION选项。该选项支持芯片自动检测 USB 串行/JTAG 控制器与主机的连接情况并在连接持续时阻止程序自动进入睡眠模式。注意此选项会增加功耗。从 Kconfig 可以看到该选项的完整约束依赖PM_ENABLE、ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED、芯片不支持 Light-sleep 保持以及USJ_ENABLE_USB_SERIAL_JTAG默认关闭启用后只要 USJ 处于连接状态驱动就会获取一个ESP_PM_NO_LIGHT_SLEEP电源管理锁阻止系统进入 Light-sleep该选项只能控制自动Light-sleep 行为若程序手动调用esp_light_sleep_start()即使 USJ 正在使用启用该选项也不会阻止进入 Light-sleep。其底层实现位于 usb_serial_jtag_connection_monitor.c芯片通过 FreeRTOS tick 钩子检测主机周期性发送的SOFStart of Frame包来判断连接状态——主机在全速 USB 总线上每 1 ms 发送一次 SOF因此只要每个 tick 周期内 SOF 中断位被置位即认为保持连接为避免 tick 延迟导致的误判代码设置了 3 ms 的容忍窗口USJ_DISCONNECT_CONFIRM_PERIOD_MS。检测到断开时释放 PM 锁检测到重连时重新获取 PM 锁。此外usb_serial_jtag.h 还公开了usb_serial_jtag_is_connected()API 供应用查询连接状态其语义是只要还在接收 SOF 包就算连接——例如 USJ 连到 PC 但串口未打开也算连接而连到移动电源则因没有 SOF 包而不会被判定为连接。注意该 API 会为每个 FreeRTOS tick 增加额外开销。应用示例USJ 回显官方示例peripherals/usb_serial_jtag/usb_serial_jtag_echo演示了使用 USB_SERIAL_JTAG 接口回显其接收到的数据主程序位于 usb_serial_echo_main.c。其核心流程定义usb_serial_jtag_driver_config_t配置结构设置rx_buffer_size与tx_buffer_size为 1024 字节调用usb_serial_jtag_driver_install()安装驱动在循环中调用usb_serial_jtag_read_bytes()读取主机发来的数据超时 20 个 tick再用usb_serial_jtag_write_bytes()原样写回实现回显。仓库中相应的测试用例可参考驱动层测试 test_usb_serial_jtag.c覆盖多任务并发打印、fsync刷新语义usb_serial_jtag_write_bytesusb_serial_jtag_wait_tx_done、驱动安装后 ROMprintf是否仍然可用等场景VFS 层测试 test_vfs_usb_serial_jtag.c覆盖select()读写与超时、阻塞/非阻塞读取行为等。小结USB 串行/JTAG 控制器为支持的 ESP 芯片提供了免桥接芯片的一体化开发体验一条 USB 线即可完成串口监视、固件烧录与 JTAG 调试。使用时的核心要点可归结为四条其一软件配置需选择CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG需要输入则必须选主控制台而非仅辅助端口其二烧录时指定正确的端口Linux 为/dev/ttyACM*其三理解 50 ms 缓冲超时与换行自动刷新的数据语义避免输出假死误判其四睡眠模式下 USJ 会断开若依赖自动 Light-sleep 下的串口监视应启用CONFIG_USJ_NO_AUTO_LS_ON_CONNECTION并在手动睡眠后通过拔插 USB 恢复连接。【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考