picoclaw 硬件支持现状与 serial 串口 Tool 实战指南 picoclaw 硬件支持现状与 serial 串口 Tool 实战指南【免费下载链接】picoclawTiny, Fast, and Deployable anywhere — automate the mundane, unleash your creativity项目地址: https://gitcode.com/gh_mirrors/pi/picoclaw导读本文聚焦 picoclaw 当前硬件支持能力的整体版图并围绕新增内建serial串口/UARTTool 展开从设计到落地的完整讲解。你将了解项目已有的 Linux USB 热插拔事件监控、I2C/SPI 总线控制能力掌握serialTool 的三种动作list/read/write、全部公共参数、跨平台实现边界与安全约束并能够在真实主机上通过配置与调用与串口设备交互。本文以设计文档 current-hardware-support-and-serial.zh.md 为主线结合 pkg/tools/hardware 目录下的源码实现进行佐证。现状结论项目已有的硬件能力两条线picoclaw 的硬件相关能力目前分为两条相互独立的线二者定位不同、职责互补。1. 设备事件监控发现与通知pkg/devices已经实现设备事件服务但目前只有Linux USB 热插拔事件源usb_linux.go非 Linux 平台由 usb_stub.go 提供占位实现。这条线的能力定位是“发现和通知”——感知 USB 设备的插入/拔出并产生事件不是“总线读写控制”。也就是说它回答“设备什么时候来了”而不管“怎么和设备通信”。2. 硬件控制 Tool总线读写pkg/tools/hardware下实现了两类硬件控制 ToolTool实现文件支持动作平台限制i2ci2c.go / i2c_linux.godetect枚举总线、scan扫描设备、read读寄存器、write写数据仅 Linux直接依赖/dev/i2c-*spispi.go / spi_linux.golist发现设备、transfer全双工收发、read读字节仅 Linux直接依赖/dev/spidev*以 i2c.go 的Execute为例两个 Tool 都会在非 Linux 平台显式返回错误如I2C is only supported on Linux...并在参数层面做了防御性校验I2C 地址限定 7-bit 范围0x03-0x77、总线 ID 必须是纯数字字符串防止路径注入SPI 的设备标识必须是X.Y格式如2.0对应/dev/spidev2.0、速率范围1 Hz ~ 125 MHz、模式 0-3、字长 1-32 bit。能力矩阵小结因此项目在“硬件支持能力”上已经具备Linux USB 设备插拔感知Linux I2C 总线控制Linux SPI 总线控制但此前仍缺少串口/UART 控制本次新增serialTool 补齐macOS / Windows 下可直接使用的硬件控制 Tool面向统一硬件抽象的跨总线能力模型本次新增内建 serial Tool 的接入点本次新增内建serialTool并完整接入现有 Tool 体系共涉及四个层面的落地配置项tools.serial.enabled默认关闭false。可在 config/config.example.json 中看到示例serial: { enabled: false }与i2c、spi同样默认禁用。Tool 注册在 pkg/agent/agent_init.go 中agent 初始化时会依据cfg.Tools.IsToolEnabled(serial)决定是否注册tools.NewSerialTool()与 I2C/SPI 的注册逻辑保持一致。Web 工具页/api/tools接口能展示并切换serial的启用状态。其平台状态解析逻辑在 web/backend/api/tools.go 的resolveSerialToolSupport中Linux、macOS、Windows 返回enabled其他平台返回blockedrequires_serial_platform未启用时返回disabled。前端状态文案新增requires_serial_platform状态键各语言包的文案如 en.json、zh.json统一说明“该工具当前支持 Linux、macOS 和 Windows且要求主机可访问对应串口”并在 web/backend/api/tools_test.go 中有对应测试用例验证。Serial Tool 设计无状态调用模型serial采用无状态调用模型每一次请求都自行打开和关闭串口端口不在 agent 回合之间维护串口会话状态。这意味着 LLM 每次调用read/write都是一次独立的“打开 → 配置 → 读写 → 关闭”完整周期避免了串口被长时间占用、会话残留导致端口锁定等问题。SerialTool的实现位于 serial.goExecute根据action分发到list/read/write三个动作serial.go未知动作会返回unknown action: ... (valid: list, read, write)。支持的动作list枚举主机串口。Linux/macOS 通过 glob 匹配/dev/ttyS*、/dev/ttyUSB*、/dev/ttyACM*、/dev/ttyAMA*、/dev/rfcomm*、/dev/tty.*、/dev/cu.*并去重、过滤目录后排序返回serial_unix.goWindows 通过注册表HARDWARE\DEVICEMAP\SERIALCOMM枚举serial_windows.go。无端口时返回No serial ports found on this host.有端口时返回 JSON 格式的ports数组与count。read从串口读取指定长度字节。length必填取值范围 1-4096见常量maxSerialReadBytes。write向串口写入字节数组或 UTF-8 文本。必须显式传入confirm: true。公共参数详解serialTool 的参数模式定义在 serial.go完整参数如下参数类型必填默认值取值范围 / 说明actionstring是-list/read/writeportstringread/write 时-串口路径或名称如/dev/ttyUSB0、/dev/cu.usbserial-0001、COM3baudinteger否115200波特率Linux/macOS 仅支持标准 termios 速率最高 230400Windows 工具层接受 50-4000000data_bitsinteger否8数据位5/6/7/8paritystring否none校验位none/even/oddstop_bitsinteger否1停止位1/2timeout_msinteger否1000读写超时毫秒范围 1-60000lengthintegerread 时-读取字节数范围 1-4096dataarrayintwrite 时与text二选一-要写入的字节每个元素 0-255textstringwrite 时与data二选一-要写入的 UTF-8 文本confirmbooleanwrite 时-必须为true否则拒绝写入参数校验集中在 serial.go 的parseSerialConfig/parseSerialTimeout/parseSerialWritePayload中超出范围会直接返回带明确提示的ToolResult错误例如baud不在 50-4000000baud must be between 50 and 4000000data_bits非法data_bits must be one of 5, 6, 7, or 8timeout_ms非法timeout_ms must be between 1 and 60000data元素非整数或越界data[N] X is out of byte range (0-255)text非法 UTF-8text must be valid UTF-8一个典型的write调用参数示例{ action: write, port: /dev/ttyUSB0, baud: 115200, data_bits: 8, parity: none, stop_bits: 1, timeout_ms: 2000, confirm: true, text: AT\r\n }写入成功后工具返回 JSON 结果包含action、port、baud、data_bits、parity、stop_bits、timeout_ms、实际写入字节数written以及payload摘要长度、字节数组、十六进制表示若为合法 UTF-8 还会附上text便于 LLM 与调试者核对收发内容见serialPayloadSummaryserial.go。波特率实现边界跨平台可移植取值建议波特率是串口通信中最容易踩坑的跨平台差异点当前实现边界如下Windows工具层接受的范围是50-4000000DCB.BaudRate直接填入用户传入的数值Windows 驱动层会自行协商。Linux / macOS仅支持标准 termios 波特率实际最高支持到230400。在 serial.go 中定义了白名单unixSerialBaudRates50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400映射函数serialBaudToUnixserial_unix.go将这组数值逐一对到unix.B50...unix.B230400常量。尚未扩展460800、921600、1000000、2000000等更高速率。校验函数validateSerialBaudserial.go会先做全局范围检查再对 Linux/macOS 做白名单检查并提示unsupported baud rate on this platform: X (supported up to 230400)。因此baud的跨平台可移植取值应优先使用 230400 及以下的常见标准速率如 9600、19200、57600、115200、230400这样同一份调用参数在 Linux、macOS、Windows 上都能生效。安全约束三层防线serialTool 内置了三层安全约束防止误操作与路径攻击写入必须显式确认write动作若未传confirm: true直接返回write operations require confirm: true. Please confirm with the user before sending bytes to a serial device.serial.go。这条约束要求 LLM 在向真实设备发送数据前必须先获得用户确认。单次读写负载限制常量maxSerialPayloadBytes/maxSerialReadBytes均为4096 字节。read的length和write的text/data长度超过 4096 都会被拒绝避免一次调用携带超大负载。端口白名单port只接受白名单串口名由normalizeSerialPortserial.go按平台执行Linux / macOS仅允许/dev/tty*、/dev/cu.*及对应简写设备名。正则unixSerialPortPattern精确匹配ttyS\d、ttyUSB\d、ttyACM\d、ttyAMA\d、rfcomm\d、tty.xxx、cu.xxx可带/dev/前缀简写会被自动补全为/dev/前缀。Windows仅允许COM\d或\\.\COM\d正则^(?:\\\\.\\)?COM[1-9]\d*$传入的COM3会被规范化为\\.\COM3。明确拒绝..、普通文件绝对路径、盘符路径等非串口设备路径从入口杜绝路径穿越或误打开任意文件。跨平台实现边界serial的底层实现按//go:build构建标签拆分为多平台文件Linux/macOS 共用一个 termios 通路Windows 使用 kernel32 串口 API其他平台显式返回 unsupported。Linux / macOS基于 termios底层依赖golang.org/x/sys/unix。Linux 使用TCGETS/TCSETSioctlserial_linux.gomacOS 使用TIOCGETA/TIOCSETAserial_darwin.goTermios结构的速度字段类型不同Linux 为uint32Darwin 为uint64但配置语义一致。端口配置流程serial_unix.go先以O_RDWR|O_NOCTTY|O_NONBLOCK打开设备随后清除输入/输出/本地标志位设置CREAD|CLOCALVMIN/VTIME置 0再按参数设置CS5-CS8、PARENB/PARODD、CSTOPB与波特率。读写采用poll 驱动的可取消模式通过unix.Poll等待POLLIN/POLLOUT每次轮询不超过 100ms见serialPollInterval在每次轮询间隙检查context是否已取消serialContextErr因此turn context cancellation 能及时打断阻塞中的读写超时则由timeout_ms总 deadline 兜底。通过/dev/...枚举和访问设备。Windows基于 kernel32 串口 API底层依赖golang.org/x/sys/windows通过kernel32.dll的GetCommState、SetCommState、SetCommTimeouts、PurgeComm配置串口serial_windows.go。配置DCB结构BaudRate、ByteSize、Parity0none、1odd、2even、StopBits01bit、22bits并通过sanitizeWindowsSerialFlags清掉流控位后强制置位fBinary标志serial_windows.go。通过COMMTIMEOUTS设置读写总超时ReadIntervalTimeout、ReadTotalTimeoutConstant、WriteTotalTimeoutConstant均为timeout_ms并在配置完成后PurgeComm清空收发缓冲区。重要边界当前读写仍使用同步ReadFile/WriteFile。一旦 syscall 已进入执行turn context cancellation 不能立即打断只能等待COMMTIMEOUTS触发后返回。这与 Linux/macOS 的 poll 可取消模型不同意味着在 Windows 上串口读写的最坏阻塞时长受timeout_ms约束源码注释也明确记录了这一点serial_windows.go。通过注册表HARDWARE\DEVICEMAP\SERIALCOMM枚举端口端口名统一转为大写。其他平台显式 unsupported非 Linux/macOS/Windows 平台由 serial_other.go 提供构建list/read/write一律返回serial is not supported on this platform不做静默降级——调用方会明确感知到平台不支持而不是得到误导性的空结果。对应地Web 工具页在非支持平台会将该工具标记为blockedrequires_serial_platform。相关测试与验证serialTool 配备了较完整的单元测试可在仓库中直接查看与运行serial_test.go参数解析、动作分发、安全校验等公共逻辑测试。serial_unix_test.goUnix 平台 termios 配置与 poll 读写路径测试。serial_windows_test.goWindows 平台 DCB/超时配置测试。serial_other_test.go非支持平台 unsupported 行为测试。serial_write_common_test.goserialWriteAll写入循环与超时/取消语义的共享测试。Web 侧工具状态断言见 web/backend/api/tools_test.go。启用与使用建议在配置中开启serial后重启或热加载agent 即可使用{ tools: { serial: { enabled: true } } }使用链路为config→ agent_init.go 注册SerialTool→ LLM 在回合中按工具 schema 发起list/read/write调用 →Execute分发并落到平台实现。硬件工具统一通过 hardware_facade.go 暴露给上层 Tool 体系。后续建议设计文档给出了三个方向的演进建议持续交互式串口会话如果后续需要 LLM 与设备长时间交互如进入设备 REPL、监控日志流建议再增加session 型 Tool而不是让 LLM 反复做短连接轮询。无状态模型在短调用场景下足够但高频轮询会引入大量打开/配置/关闭开销。统一硬件抽象层如果要继续支持 CAN、GPIO、PWM 等总线建议抽出统一的hardware capability 描述层而不是继续只靠 Tool 名称区分。这样 LLM 与上层路由可以基于能力描述如“该平台支持哪些总线、哪些地址”做更通用的调度。生产级稳定性测试建议补真实串口回环测试至少覆盖Linux PTY和Windows COM 模拟场景以验证端到端收发、超时与取消语义在真实设备上的表现。总结picoclaw 的硬件支持版图由“设备事件监控发现与通知”与“硬件控制 Tool总线读写”两条线构成。本次新增的serialTool 补齐了串口/UART 控制能力采用无状态调用模型、三层安全约束并在 Linux/macOStermios poll 可取消与 Windowskernel32 DCB COMMTIMEOUTS之间做了清晰的平台边界划分其他平台显式 unsupported。实际使用中优先选择 230400 及以下的标准波特率即可获得最佳跨平台可移植性。相关设计与实现均可从 docs/design/current-hardware-support-and-serial.zh.md 及 pkg/tools/hardware 源码继续深入阅读。【免费下载链接】picoclawTiny, Fast, and Deployable anywhere — automate the mundane, unleash your creativity项目地址: https://gitcode.com/gh_mirrors/pi/picoclaw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考