逻辑分析仪能够记录信号,工程问题却仍然悬而未决。有的仪器要先上传固件,系统才能枚举;有的藏在串口之后;还有的虽使用 USB 通信,导出的文件却为厂商专有格式。即使采集已经成功,屏幕上密布的跳变沿仍未成为 I²C 事务、MIDI 消息或存储器命令。
sigrok 的价值,在于它把这些问题拆到多个相互衔接的部分中处理。硬件驱动、采集会话、标准化数据流、已保存的采样记录、前端和协议解码器各自承担明确职责。不同仪器由此汇入同一条测量流水线,而结果容易出错的每一道分界仍清晰可见。
上图摄于 2011 年,Saleae Logic 分析仪的探头线夹在 E-mu Emulator II 采样器的存储板上。[12] 这幅照片记录的远不止电子工作台的气氛。sigrok 文档说明,第一代 Saleae Logic 以 FX2 为基础,并由开放的 fx2lafw 固件方案支持。[7] 探头、电路板和分析仪始终受制于物理条件;软件所做的工作,是让穿过探头的信号变成可携带、可复用的记录。
探头掌握着第一手事实
整条流水线从软件之外开始。接地缺失、电压不安全、探头接错引脚,或采样率低到无法分辨重要跳变,这些问题都超出驱动的修复能力。初代 Saleae Logic 的页面把这条分界写得格外具体:8 个通道,最高 24 MHz 采样率,固定数字阈值,没有板载采集存储器,触发完全由软件完成。[7] 在这套设计中,主机既是查看工具,也是采集链路的一部分。
因此,“硬件受支持”只是一项兼容性说明,无法担保测量结果。本文发布时,项目的硬件索引列出 258 款受支持设备,另有 27 款正在开发、144 款列入计划;页面同时提醒,这张表依据最新的 libsigrok 开发树,正式发布版支持的设备数量会更少。[6] 同一设备的各项功能也会处于不同完成度。逻辑通道已经开放时,模拟模式、触发功能或某项配置仍会留有缺口。
首要问题应当落在“这套硬件在当时的电气条件下究竟采到了什么”。至于“PulseView 是否显示了波形”,还要放在这项核查之后。通道标签、阈值假设、固件、采样率和触发行为都应随采样记录一同保存,因为后续每一层都会继承这些条件。
驱动把设备变成仪器实例
在 libsigrok 的分界处,每个硬件驱动都注册一组通用操作。正式发布的 libsigrok 0.5.2 头文件中,sr_dev_driver 约定涵盖发现与生命周期操作——scan、dev_open、dev_close——以及配置和采集启停回调。[1] USB 驱动可以按标识符搜索;串行设备则会要求显式传入 conn 值,例如设备路径和串口参数。前端向驱动请求一个仪器实例,仪器所用的线路协议仍由驱动掌握。
架构上的第一次归并由此完成。PulseView 通过共同的驱动层使用所有受支持的分析仪和示波器;sigrok-cli 面向更多设备类别,也共享同一组驱动。枚举、固件交接、传输细节以及原生数据包转换归设备专用代码处理,前端负责选择设备并表达操作意图。
配置仍然保留设备差异。逻辑分析仪会接受 samplerate 和采样数量上限,仪表会给出记录间隔,串行仪器会要求 conn。共享 API 统一这些能力的发现和设置方式,具体能力集合仍由各仪器决定。[1] 这种抽象承认设备各异的现实,没有虚构出一台“最低共同能力”设备。
数据流是整套系统的窄腰
采集开始后,驱动会把带类型的数据包发布到 libsigrok 的会话数据流中。正式发布的头文件定义了头部、元数据、触发、帧边界、逻辑、模拟和结束等数据包类型。[1] 硬件专用的 USB 帧向上游传递时,已经转化为采样数据,并带有足够的上下文,让使用方能够判断它们在会话中的位置。
这处窄腰让前端可以彼此替换。在当前 PulseView 源码中,pv::Session 负责协调 libsigrok 会话,并通过分段对象持有采集到的逻辑和模拟数据。[5] sigrok-cli 沿用同一条采集链路,可以脱离 GUI 驱动采集、把样本写入标准输出,或将其保存以供后续处理。[9] 自定义程序也可以调用库绑定,无意伪装成 PulseView。
文件同样可以像仪器一样进入流水线。版本 2 的 .sr 会话是一个 ZIP 容器,内含版本记录、INI 风格元数据和采样数据文件。[2] 再次打开文件时,已记录的证据会重新流经软件各层。此时设备已经离线,采样流和采集上下文仍可继续使用。
实验室由此可以养成一种实用习惯:采集一次,多次解释。最简洁的两遍工作流程如下:
sigrok-cli --driver fx2lafw --config samplerate=1m \
--channels 0=RX --time 3s -o uart-capture.sr
sigrok-cli -i uart-capture.sr \
-P uart:rx=RX:baudrate=115200
第一条命令采集证据,第二条命令为其提出一种解释。CLI 文档也为复杂任务划出了同样的分界:在一个 -P 参数中列出多个解码器,会让它们组成一组解码栈;分别使用多个 -P 参数,则会建立并行运行的多组解码栈。[9] Hackaday 的一项独立调查把这套方法用于实际工作:研究者先从 Openbench Logic Sniffer 保存一份经过触发的 .sr 采样记录,随后分别执行 SPI 解码,从一枚激光传感器中提取出两条二进制数据流。[11]
协议解码器解释含义,不负责采集
libsigrokdecode 把协议解释作为独立子系统处理。解码器是 Python 模块,以分块方式接收流式样本或文件中的样本,可以输出注释、元数据、二进制内容或更高层协议数据。多个解码器还可以层叠,让一个解码器的输出成为另一个解码器的输入。[3]
这是架构上的第二次归并。I²C 解码器只需处理跳变沿,无论它们来自廉价的 FX2 电路板、台式混合信号仪器,还是旧 .sr 文件。EEPROM 解码器也可以直接位于 I²C 解码器之上,沿用后者识别出的起始条件和应答,省去重复识别。CLI 文档中的 i2c,eeprom24xx 和 uart,midi 示例清楚展示了这种分层方式。[9]
版本 3 解码器 API 也改善了内部循环。逐一样本检查从 Python 代码中移出;解码器通过 self.wait() 表达等待条件,由 C 后端向前推进,直到相关跳变沿或状态出现。[4] 解码器作者依然编写状态机,重复度最高的样本遍历工作则移到了 Python 分界之下。
其覆盖范围相当可观:本文发布时,项目的解码器索引列出了 131 个受支持的协议解码器。[8] 其中更重要的性质是可组合性。新设备驱动接入后,现有解码器随即可以处理它的数据;新解码器加入后,也能直接读取现有驱动留下的采样记录。硬件与协议覆盖面由此相乘,摆脱了成对集成的线性增长方式。
每一道分界都有自己的故障特征
层次划分清楚,测量仍会出错;它带来的变化,是故障能够被准确命名。
- 物理故障: 引脚、阈值、接地、探头负载或采样率选择错误,会留下质量低劣的证据。未被采集的跳变,任何解码器设置都无法恢复。
- 驱动故障: 权限、缺失的固件、含混的 USB 标识符,或
conn一类传输选项都会阻断设备发现。可信数据流尚未出现,故障已经发生。[1][7] - 吞吐故障: 样本到达速度超出主机链路的处理或存储能力。sigrok CLI 文档明确建议先采集、后处理,并警告其单线程链路在格式化或解码负载过高时会提前终止;面对高采样率,文档建议采用开销较低的二进制采集和带缓冲的压缩。[9]
- 会话故障: 一份波形记录若缺少通道名称、采样率上下文、固件来源或生成它的命令,证据的保管链便会残缺。
.sr容器会保留规范中定义的元数据,却无法记录实验人员从未写下的实验室事实。[2] - 解码器故障: 通道映射、波特率、极性、字长或解码器次序一旦选错,真实跳变便会生成听来合理、实则虚假的解释。层叠会让风险继续累积:底层的一次误读,将成为上层确信无疑的输入。[3][9]
- 前端故障: 渲染或导航问题会增加检查正确采样记录的难度,却不能直接证明驱动或解码器也有问题。PulseView 的会话与已存数据对象同库中的采集回调彼此分开,原因正在于此。[5]
这套词汇改变了调试方式。“sigrok 错了”的范围过于宽泛,无法指导排查。“驱动在 SR_DF_END 之前停止”“采样使时钟发生混叠”或“EEPROM 解码器收到错误的 I²C 通道映射”,都能把问题指向职责明确的一层,并给出可复现的测试起点。
采用 sigrok,需要锁定一套经过验证的组合
对于固件团队、维修实验室、硬件再利用项目或教学工作台,当多种仪器都要接入同一套证据工作流程时,sigrok 最能发挥作用。团队可以统一一套已验证的探测方式,记录驱动与采集选项,在执行开销较高的解码前保存原始 .sr 文件,把解码器配置与采样记录放在一起,并用含义已经明确的总线事务检验结果。
运行环节同样需要关注。下载页面目前推荐 nightly builds 作为获取最新版本的途径,同时列出 libsigrok 0.5.2、libsigrokdecode 0.5.3、sigrok-cli 0.7.2 和 PulseView 0.4.2 等正式版本。[10] 与此同时,硬件和解码器索引展示的是开发树快照。[6][8] 团队若依赖近期新增的驱动,就应锁定已经验证的具体软件包或构建版本;“sigrok 支持这台设备”没有说明哪一份发行产物包含这项支持。
这样的发布形态本身不足以成为弃用项目的理由,它提醒使用者把测试过的软件组合纳入实验室配置,其中包括库、固件、前端、解码器树、操作系统权限和硬件修订版。两人规模的嵌入式团队可以提交采集命令,并固定一份工作站镜像。规模更大的验证实验室则会需要打包构建、基准波形、自动化解码器测试,以及职责明确的升级管理。
sigrok 真正的成就,远不止让一个 GUI 识别多种仪器。一次物理测量可以经过数份独立而可检查的约定:从设备到驱动,从驱动到数据流,从数据流到会话,从会话到文件或前端,再从样本到层叠解码器。这套架构无法把质量低劣的采样变成事实,却能充分展现从探头到结论的链路,让人得以质疑、重放并改进它。
来源
- sigrok 项目,正式发布的 libsigrok 0.5.2 提交中的
libsigrok.h——sr_dev_driver、数据流数据包类型及数据包载荷的组织方式。 - sigrok 项目,“File format: sigrok/v2”——
.srZIP 容器、版本记录、元数据和采样数据文件规范。 - sigrok 项目,“Protocol decoder API”——Python 解码器模块、流式分块、输出类别和解码器层叠。
- sigrok 项目,“Protocol decoder API/Queries”——版本 3 查询模型与
self.wait()执行分界。 - sigrok 项目,提交
af02198中的 PulseViewsession.hpp——当前pv::Session的归属分界与逻辑/模拟分段状态。 - sigrok 项目,“Supported hardware”——开发树设备数量、完成状态和正式版本提示。
- sigrok 项目,“Saleae Logic”——第一代设备的通道、采样率、阈值、触发与存储限制,以及
fx2lafw支持。 - sigrok 项目,“Protocol decoders”——受支持的解码器数量与解码栈输入/输出标识符。
- sigrok 项目,“sigrok-cli”——驱动与通道选择、采集限制、已保存的采样记录、层叠解码器和高吞吐处理建议。
- sigrok 项目,“Downloads”——正式组件版本、nightly build 建议、平台软件包、固件和设备权限说明。
- Elliot Williams,“What's Inside A Neonode Laser Sensor?”,Hackaday,2018 年 3 月 6 日——先保存 sigrok 采样记录、再分别执行 SPI 解码的独立实践案例。
- John R. Southern,“E-mu Systems Emulator II memory option board with Saleae Logic analyzer”,Wikimedia Commons,摄于 2011 年 1 月 22 日——本文档案照片的来源页面。