
目前我们做气密性测试每次录音后都要插usb数据线进入U盘模式手动把录音pcm文件拷贝出来很麻烦因此想实现直接启动录音dump, 用一条指令启动录音和dunp, 可以dump Pcm文件到电脑本地# ATS3089P USB 虚拟串口本功能使用芯片 USB 控制器实现 CDC ACM。开发板 GPIO75/DP、GPIO76/DM 已接到 USB 接口使用能传输数据的 USB 线连接电脑即可不需要 USB 转 UART 板也不需要把 DP/DM 改成 UART 引脚。## 使用指令首次通过现有串口执行textapp usbserial on若当前为 U 盘或 USB 声卡程序先退出旧模式再重新枚举为 USB 串口。电脑串口工具选择新出现的 COM 口设置 **115200、8N1、无硬件流控**DTR 可以为 0 或 1。这里的波特率是 CDC 参数实际数据通过 USB 传输。枚举完成后会输出 CDC console ready打开 COM 后按回车可以显示 shell 提示符原有 app、audio 等命令可以直接从 USB 输入日志和命令响应也通过 USB 输出。设备描述符采用 CDC class 02 / subclass 02匹配 Windows 内置 Usbser 驱动的自动加载条件见[微软说明](https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-driver-installation-based-on-compatible-ids)。实际设备枚举、串口工具兼容性需要上板验证。| 指令 | 作用 || --- | --- || app usbserial on | 切换到 USB 串口未插线时等待连接 || app usbserial off | 关闭 USB 串口 || app usbserial status | 查看启用、枚举、DTR、丢弃字节和开机设置 || app usbserial boot on | 保存开机自动启用 USB 串口 || app usbserial boot off | 取消开机自动启用 || app udisk on | 关闭串口/声卡切换到 U 盘 || app usbaudio on | 关闭串口/U 盘切换到 USB 声卡 |希望以后只插 USB 使用首次设置textapp usbserial boot onapp usbserial onboot 只保存下次启动的偏好不立即切换当前模式。默认未设置时保持原有启动行为。启用自动串口后它优先于开机自动进入 U 盘的逻辑手动切到 U 盘或声卡不修改这个开机偏好。三种模式互斥切换后电脑上的旧设备会消失。如果通过 USB 串口输入切换指令当前 COM 口也会断开切回串口可用原物理 UART 指令或在已保存 boot on 的情况下重启开发板。U 盘切出前先停止电脑文件传输并安全弹出。## 气密性测试录音并保存到电脑本次 ATS3089P 固件outdir/ats3089p_dev_watch/_firmware/ats3089p_dev_watch_261012_usb_cdc_pcm_debug.fw同目录另有完整包 ats3089p_dev_watch_261012_usb_cdc_pcm.fw。如果电脑上已经出现本板的 USB CDC COM 口直接使用即可不需要接串口板可在该 COM 的 shell 中执行一次 app usbserial boot on让以后开机自动进入 CDC。若 CDC 尚未启用首次仍需通过已有控制入口执行 app usbserial boot on 和 app usbserial on。以后只需用 USB 数据线连接电脑在设备管理器中找到 COM 口无需进入 U 盘模式或手动复制文件。电脑安装 Python 和 pyserialtextpython -m pip install pyserial在项目目录执行一条命令把 COMx 换成实际端口textpython application/bt_watch/tools/record/usb_pcm_capture.py --port COMx --seconds 10工具通过 CDC 虚拟串口向板子发送 audio record usb_dump seconds10。板子按现有气密性测试参数录制 16 kHz、16 bit、单声道 PCM录音结束后关闭文件再把完整 PCM 按长度和 CRC 校验信息传给电脑。工具校验后在电脑端执行命令的当前目录自动选择不覆盖旧文件的名称rec.pcm、rec1.pcm、rec2.pcm……板子的 NAND 中也保留本次录音文件。传输在录音**结束后**进行不是边录边传因此不会让 USB 发送速度影响采样。也可以在 CDC 的 shell 中直接执行 audio record usb_dump seconds10需要由配套上位机工具接收并提取 PCM。若录音已完成而电脑端接收失败可用以下命令重传**本次开机期间最近一次 usb_dump 录音**无需重新录音textpython application/bt_watch/tools/record/usb_pcm_capture.py --port COMx --export工具会向板子发送 audio record usb_export。重启后不能恢复此前的重传目标普通 audio record 录音也不是 usb_export 的目标。需要指定电脑端文件名时可追加 --output rec_retry.pcm。UartAssist 等串口助手的“原样保存接收数据”会把命令回显、传输头尾等内容一起写入文件所得文件不能直接当作裸 PCM。请使用上述工具完成长度、CRC 校验和自动命名。每次录音的 PCM/Opus 文件仍保存在板子 NAND 中并自动编号连续产测时需定期清理旧文件避免 NAND 空间耗尽。## USB 串口产测 MAC 查询USB 串口开启并打开 COM 后使用 ASCII 文本发送textATFTESTMAC命令必须以回车 \r、换行 \n 或 \r\n 结束串口工具可以勾选“发送新行”。成功回复一行末尾为 \r\ntextMAC,OK,78:02:B7:13:12:CE上面是格式示例实际返回开发板正在使用的蓝牙本机 MAC大写、冒号分隔与控制器的 BT_MAC 配置一致。蓝牙尚未初始化时读取保存的地址地址缺失或无效时返回 MAC,ERROR,NOT_READY。查询不会生成或修改地址。命令复用现有 shellUSB 接收支持分包原物理 UART 也可使用。USB 上仍有日志、命令回显和提示符产测程序按 MAC,OK, / MAC,ERROR, 响应行识别结果。例如用 Python 的 pyserial 打开已识别的 COM 口并发送pythonimport reimport timeimport serialwith serial.Serial(COM14, 115200, timeout0.2) as port:port.dtr False # DTR is optional; tools that leave it low also work.port.write(bATFTESTMAC\r\n)deadline time.monotonic() 3received bytearray()while time.monotonic() deadline:received.extend(port.read(256))match re.search(rbMAC,OK,([0-9A-F]{2}(?::[0-9A-F]{2}){5})\r\n, received)if match:print(USB RX/TX OK, MAC:, match.group(1).decode(ascii))breakif bMAC,ERROR,NOT_READY\r\n in received:raise RuntimeError(Board MAC is not ready)else:raise TimeoutError(No MAC response from the USB serial port)## 状态和限制- 正常枚举后应看到 enabled1 configured1 owner3DTR 为 0 或 1 均能收发。owner0 空闲、1 U 盘、2 声卡、3 串口。- enabled1 configured0 表示已选择串口模式但尚未完成枚举检查数据线、连接和电脑设备管理器。- configured1 DTR0 表示电脑已枚举且 DTR 为低不代表收发不可用。- 日志队列 4096 字节队列满时丢弃新日志并累加 dropped避免电脑不读取拖住系统。未枚举、挂起或关闭串口功能时丢弃日志。不要同时从 USB 和物理 UART 输入命令以免字符混入同一命令行。- 覆盖应用运行阶段的日志ROM、Bootloader 和 CDC 启动前的日志仍需物理 UART。USB 串口启用期间持有唤醒锁调试后可执行 off 允许系统恢复休眠。- USB 线拔插后会等待重新枚举电脑端可能需要重新打开 COM 口。PCM 导出只在执行 audio record usb_dump 或 audio record usb_export 时启动。- 手动开启串口、U 盘或声卡时模式保持到关闭或切换U 盘也支持电脑安全弹出退出。拔线后可执行 app udisk off 退出 U 盘并重新挂载设备文件系统。## 261010 枚举修复log_26_9_29.txt 中执行 app usbserial on 后状态一直为 configured0电源日志一直报告 dc5v:0 OUT。当前板的 USB 热插拔检测读取外部充电芯片的 DC5V 状态旧版工作线程因此没有初始化 CDC热插拔定时器也会按 DC5V0 断开 USB。现在 on 指令立即初始化 USB 设备不再等待 DC5V。三种模式通过共同的 USB 占用机制暂停自动探测和定时器断开关闭后恢复原有检测。DC5V 的实际读数仍用于诊断。另修复 CDC 描述符末尾缺少 SDK 遍历终止字节、模式切换时字符串残留以及高速连接复位后未恢复全速描述符的问题。烧录 ats3089p_dev_watch_261010_debug.fw 后先用物理串口执行textapp usbserial onapp usbserial status第一条应输出 [usbserial-v2] CDC init0表示驱动已经实际启动。电脑完成枚举时会看到 USB reset、USB configuredstatus 同时输出驱动启动结果、PMU_DC5V、复位次数、配置次数和控制请求次数。此时即使 PMU_DC5V0也应允许正常枚举。## 261010 串口助手收发修复v3上一版运行线程将 DTR 作为 USB 收发的必需条件。有些串口助手打开 COM 后仍保持 DTR0设备虽然已枚举却不读取 OUT 数据也不发送日志和查询回复。现在以 USB 已配置且未挂起作为收发条件DTR 仅用于诊断。打开友善串口调试助手的 COM14 后即可收到日志发送以 CR/LF 结束的 ATFTESTMAC 即可查询地址。开启时应看到 [usbserial-v3] CDC console ready, DTR0 (optional) 或 DTR1。app usbserial status 新增 rx_bytes驱动读到的 USB 字节数和 tx_queued_bytes交给 USB IN 端点的字节数每次重新开启串口功能时清零。若发送后 rx_bytes 增长但未执行命令应检查发送内容末尾是否包含回车/换行助手的“接收自动换行”设置只影响显示。## 实现与验证入口在 src/main/usb_serial_runtime.c。CDC 驱动修正了高速 bulk 最大包长512 字节、全速/高速接收包长、复位与挂起状态、接收背压及发送缓冲的使用周期。日志回调仅入队USB 发送和 shell 输入转交由工作线程处理。U 盘、声卡、串口共用原子 ownership 标记旧模式完成 USB 退出后才释放U 盘还要完成刷盘和重新挂载声卡还要结束延迟工作。关键改动带 //zk 或 //zk- 标记。构建后运行textpython application/bt_watch/tests/usb_serial/run_tests.pypython application/bt_watch/tests/usb_serial/run_core_tests.pypython application/bt_watch/tests/usb_serial/run_factory_tests.pypython application/bt_watch/tests/ringtone/run_tests.pyUSB 测试执行真实 ELF 中的 ARM 代码模拟 USB 硬件及 RTOS 边界覆盖描述符、全速/高速收发、控制请求、复位、挂起恢复、队列溢出、模式占用、工作线程、shell 接收和模拟拔插。它不能替代电脑上的真实 USB 枚举测试。核心枚举测试另外执行 SDK 的真实描述符遍历和字符串注册代码验证全速→高速→全速复位的端点参数以及长字符串切换到短字符串时的终止和返回内容。产测测试执行链接的根命令查找、shell 解析及真实查询处理代码验证 MAC 的字节顺序、缓存优先、开机读取、无效地址及查询不会改写配置。上板建议依次验证打开 COM 收日志并执行 app usbserial status执行原有 app ringtone play 1 / app ringtone stop拔插 USB 并重开 COM切换 U 盘、声卡、串口保存 boot on 后断电重启确认自动出现 COM 口。