系列文章目录
sigrokdecode 模块学习指南 — 准备阶段
通讯协议 - Uart
sigrokdecode 模块
UART协议解码器源码解析
Uart协议解码器源码各个方法
libsigrokdecode(有时简称“srd”)是一个使用C语言编写的共享库,它提供了用于运行sigrok协议解码器的基本API。该库是开源社区为创建一个便携式、跨平台的自由/开源信号分析软件套件的一部分,旨在支持逻辑分析仪、示波器、万用表等多种设备类型。协议解码器自身是以Python编写的,并集成在库中,确保了其作为整体库的一部分遵循GPLv3或更高版本的许可。
前言
libsigrokdecode广泛应用于电子工程和嵌入式开发领域,通过它,开发者可以解析复杂的数据流,比如解读I2C、SPI通信等。最佳实践包括:
- 使用libsigrokdecode结合sigrok-cli或图形界面工具如PulseView来分析硬件通信。
- 在调试嵌入式系统时,利用预定义的解码器来快速验证外设通讯协议。
- 开发自定义解码器时,遵循项目提供的Python接口文档,保证解码器的可维护性和兼容性。
指南
libsigrokdecode是更广泛的sigrok项目的一部分,该项目还包括信号捕获前端(如PulseView)和其他辅助工具。在ecosystem中,典型的关联项目包括:
- PulseView: 是一个图形用户界面,能够显示来自硬件设备的信号数据,并且与libsigrokdecode紧密合作,提供可视化解码。
- libsigrok: 主库,用于采集和处理信号数据,libsigrokdecode作为其重要的扩展提供协议分析功能。
- 各种硬件驱动: 支持大量硬件设备,让libsigrokdecode的解码能力得以在不同设备上应用。
libsigrokdecode 学习
-
sigrok 子项目的构建要求,并包含从源代码构建它们的特定于作系统的说明:https://sigrok.org/wiki/Building
-
您可以从 sigrok.org 下载目录下载以下子项目的最新发布的 tarball:https://sigrok.org/wiki/Downloads#Binaries_and_distribution_packages
-
libsigrokdecode 协议解码器 (PD) 的工作原理: https://sigrok.org/wiki/Protocol_decoder_API
-
libsigrokdecode 协议解码器 (PD) 的编写:https://sigrok.org/wiki/Protocol_decoder_HOWTO
-
协议解码器 API/查询:https://sigrok.org/wiki/Protocol_decoder_API/Queries
一、构建环境
安装libsigrokdecode
- 安装依赖
# Ubuntu/Debian
sudo apt update
sudo apt install -y \
git \
build-essential \
autoconf automake libtool \
python3-dev \
libglib2.0-dev \
check\ # 单元测试工具
# 确保 Python 头文件存在(关键!)
ls /usr/include/python3.*/Python.h # 应返回有效路径
- 获取源码
# 推荐通过 HTTPS 克隆(避免 git:// 协议问题)
git clone https://github.com/sigrokproject/libsigrokdecode.git
cd libsigrokdecode
- 构建脚本
# 若缺少 autogen.sh 权限
chmod +x autogen.sh
# 生成 configure 脚本
./autogen.sh
- 配置编译选项
# 标准配置(默认安装到 /usr/local)
./configure
# 若需指定 Python 版本(例如 Python 3.8)
PYTHON=python3.8 ./configure
- 编译与安装
make -j$(nproc) # 并行编译(加速)
sudo make install # 安装到系统目录
sudo ldconfig # 更新动态库缓存
- 验证安装
# 检查版本信息
sigrok-cli --version
# 列出所有解码器(需至少安装一个)
sigrok-cli --show | grep decoders
安装 sigrok-cli(命令行工具)
- 安装依赖
# Ubuntu/Debian
sudo apt install build-essential git autoconf automake libtool \
pkg-config libglib2.0-dev libzip-dev libcheck-dev
- 获取源码并编译
git clone https://github.com/sigrokproject/sigrok-cli.git
cd sigrok-cli
./autogen.sh
./configure
make -j$(nproc)
sudo make install
sudo ldconfig
- 验证安装
sigrok-cli --version
# 正常输出示例:sigrok-cli 0.7.2
安装 PulseView(图形界面)
- 安装依赖
# Ubuntu/Debian
sudo apt install cmake git qtbase5-dev qttools5-dev \
libboost-dev libboost-system-dev libboost-filesystem-dev \
libboost-thread-dev libqt5svg5-dev libusb-1.0-0-dev
- 获取源码并编译
git clone --depth=1 https://github.com/sigrokproject/pulseview.git
cd pulseview
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
make -j$(nproc)
sudo make install
sudo ldconfig
- 验证安装
pulseview --version
# 正常输出示例:PulseView 0.4.2
关联 libsigrokdecode
- 确保动态库路径正确
# 检查 libsigrokdecode 是否在链接器路径中
sudo ldconfig -p | grep libsigrokdecode
# 若未找到,手动添加路径(假设安装到 /usr/local/lib)
echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/sigrok.conf
sudo ldconfig
- 配置 Python 路径(关键步骤!)
# 检查 Python 绑定路径(假设 Python 3.8)
ls /usr/local/lib/python3.8/dist-packages/sigrokdecode*
# 若路径存在但无法导入,设置 PYTHONPATH
echo "export PYTHONPATH=/usr/local/lib/python3.8/dist-packages:\$PYTHONPATH" >> ~/.bashrc
source ~/.bashrc
完整验证
- 测试硬件检测
sigrok-cli --scan
# 正常输出示例(需连接支持设备):
# The following devices were found:
# demo - Demo device with 8 channels
- 运行完整解码流程
# 生成测试信号(假设已安装 libsigrok)
sigrok-cli --driver=demo --samples=1000 --output=test.sr
# 使用 PulseView 查看
pulseview test.sr
sigrok-cli --driver=demo --config samplerate=1M \
--channels=D0 -P uart:rx=D0,baudrate=9600 \
--output-format=text --samples 1000
参数解释
参数 | 说明 |
---|---|
--driver=demo | 使用虚拟 Demo 设备 |
--config samplerate=1M | 设置采样率为 1MHz(大写 M ) |
--channels=D0 | 仅启用数字通道 D0 |
-P uart:rx=D0,baudrate=9600 | 运行 UART 解码器,指定 RX 引脚为 D0,波特率 9600 |
--output-format=text | 输出格式为文本 |
--samples 1000 | 采集 1000 个样本 |
二、BUG解决
你遇到的 ls: cannot access ... No such file or directory
错误表明以下可能性:
libsigrokdecode
的 Python 绑定未正确安装。- Python 包安装路径不符合预期(如未安装到
/usr/local/lib/...
)。 - 编译时未启用 Python 绑定。
1. 确保编译时启用了 Python 绑定
在编译 libsigrokdecode
时,必须启用 Python 支持并正确安装 Python 绑定。
cd ~/Desktop/libsigrokdecode
# 清理旧编译文件
make distclean
git clean -fdx
# 配置时强制指定 Python 路径
./autogen.sh
./configure PYTHON=/usr/bin/python3
# 编译并安装(需要 sudo 权限)
make -j$(nproc)
sudo make install
2. 检查 Python 绑定的实际安装路径
默认情况下,Python 绑定可能安装到系统目录 /usr/lib/python3/dist-packages/
或 /usr/local/lib/python3.8/site-packages/
,而非 dist-packages
。
# 搜索所有可能的安装路径
sudo find / -name "sigrokdecode*" 2>/dev/null
# 检查常见路径
ls /usr/lib/python3/dist-packages/sigrokdecode*
ls /usr/local/lib/python3.8/site-packages/sigrokdecode*
3. 手动指定 Python 包安装路径
如果绑定未安装到预期路径,可在配置时指定 --prefix
:
# 指定安装到 /usr/local
./configure --prefix=/usr/local PYTHON=/usr/bin/python3
# 重新编译并安装
make -j$(nproc)
sudo make install
# 验证安装路径
ls /usr/local/lib/python3.8/site-packages/sigrokdecode*
4. 设置 PYTHONPATH
环境变量
如果 Python 绑定安装到了非标准路径,需手动添加路径到 PYTHONPATH
:
# 假设绑定安装到了 /usr/local/lib/python3.8/site-packages
export PYTHONPATH="/usr/local/lib/python3.8/site-packages:$PYTHONPATH"
# 验证 Python 能否导入模块
python3 -c "import sigrokdecode; print(sigrokdecode)"
5. 检查 configure
输出日志
确保配置阶段检测到了 Python 绑定支持:
# 查看配置日志中 Python 相关条目
cat config.log | grep -i "python"
# 期望输出类似:
# checking for Python... /usr/bin/python3
# checking Python headers... /usr/include/python3.8
# checking Python library... yes (shared)
三、libsigrokdecode学习步骤
第一阶段:基础准备
1. 理解核心概念
- 协议解码:将原始信号(如数字电平)解析为协议帧(如UART的起始位、数据位、停止位)。
- 采样数据流:硬件采集的时序数据(如逻辑分析仪捕获的二进制信号)。
- 注解(Annotation):解码过程中添加的元数据(如“数据字节: 0x55”)。
2. 必备知识
- Python基础:类、装饰器、列表操作(解码器用Python编写)。
- C基础:指针、结构体、回调函数(核心库用C实现)。
- 信号协议:UART/SPI/I2C等常见协议的时序逻辑(推荐先学习UART)。
3. 工具准备
- 调试工具:
- GDB(调试C代码):
gdb --args python3 your_script.py
- PDB(调试Python解码器):
python3 -m pdb your_decoder.py
- GDB(调试C代码):
- 可视化工具:PulseView(直观查看解码结果)。
第二阶段:源码结构解析
1. 代码仓库目录
libsigrokdecode/
├── contrib/
├── decoders/
├── irmp/
├── m4/
├── tests/
├── tools/
├── .gitattributes
├── .gitignore
├── AUTHORS
├── COPYING
├── Doxyfile
├── HACKING
├── Makefile.am
├── NEWS
├── README
├── autogen.sh
├── configure.ac
├── decoder.c
├── error.c
├── exception.c
├── instance.c
├── libsigrokdecode-internal.h
├── libsigrokdecode.h
├── libsigrokdecode.pc.in
├── log.c
├── module_sigrokdecode.c
├── session.c
├── srd.c
├── type_decoder.c
├── util.c
├── version.c
├── version.h.in
- contrib/: 包含一些贡献者的代码和工具。
- decoders/: 包含各种协议解码器的实现。
- irmp/: 包含与红外协议相关的代码。
- m4/: 包含用于自动配置的 m4 宏文件。
- tests/: 包含项目的单元测试代码。
- tools/: 包含一些实用工具和脚本。
- .gitattributes: Git 属性配置文件。
- .gitignore: Git 忽略文件配置。
- AUTHORS: 项目作者列表。
- COPYING: 项目许可证文件。
- Doxyfile: Doxygen 配置文件,用于生成 API 文档。
- HACKING: 项目开发指南。
- Makefile.am: Automake 配置文件。
- NEWS: 项目更新日志。
- README: 项目介绍和使用说明。
- autogen.sh: 自动生成配置脚本。
- configure.ac: Autoconf 配置文件。
- decoder.c: 解码器核心代码。
- error.c: 错误处理代码。
- exception.c: 异常处理代码。
- instance.c: 实例管理代码。
- libsigrokdecode-internal.h: 内部头文件。
- libsigrokdecode.h: 公共头文件。
- libsigrokdecode.pc.in: pkg-config 配置文件模板。
- log.c: 日志记录代码。
- module_sigrokdecode.c: 模块管理代码。
- session.c: 会话管理代码。
- srd.c: 核心功能代码。
- type_decoder.c: 解码器类型管理代码。
- util.c: 实用工具代码。
- version.c: 版本管理代码。
- version.h.in: 版本头文件模板。
2. 核心模块交互
libsigrokdecode 项目的启动文件主要是 decoder.c
。这个文件包含了项目的主要逻辑和功能实现。启动时,项目会加载并初始化解码器模块,并根据配置文件进行相应的设置。
- 初始化:
lib.c
初始化库并注册全局解码器。 - 会话管理:
session.c
创建解码会话,管理输入数据流。 - 解码器加载:
decoder.c
扫描并加载decoders/
目录下的Python解码器。 - 数据处理:Python解码器通过
decode()
方法逐层解析数据。
3. 项目的配置文件介绍
libsigrokdecode 项目的配置文件主要包括以下几个:
- configure.ac: 用于生成
configure
脚本的 Autoconf 配置文件。 - Makefile.am: 用于生成
Makefile
的 Automake 配置文件。 - Doxyfile: 用于生成 API 文档的 Doxygen 配置文件。
- libsigrokdecode.pc.in: 用于生成 pkg-config 文件的模板。
第三阶段:从简单解码器入手(以UART为例)
1. 文件结构
decoders/uart/
├── pd.py # 解码器主逻辑
└── __init__.py # 解码器元数据
2. 关键代码解析
# pd.py
class Decoder(srd.Decoder):
api_version = 3
id = 'uart'
name = 'UART'
# 定义输入输出类型
inputs = ['logic']
outputs = ['uart']
# 定义可配置参数(如波特率)
options = (
{'id': 'baudrate', 'desc': 'Baud rate', 'default': 115200},
)
def __init__(self):
self.out_python = self.register(srd.OUTPUT_PYTHON)
def start(self):
self.samplerate = self.get_samplerate() # 获取采样率
self.bit_width = self.samplerate // self.options['baudrate']
def decode(self, startsample, endsample, data):
# 核心解码逻辑:检测起始位 → 读取数据位 → 验证停止位
for bit in data:
if self.state == 'WAIT_START':
if bit == 0: # 检测到起始位
self.ss = startsample
self.state = 'READ_DATA'
elif self.state == 'READ_DATA':
self.data_bits.append(bit)
if len(self.data_bits) == 8:
byte = sum(bit << i for i, bit in enumerate(self.data_bits))
self.put(self.ss, endsample, self.out_python, ['DATA', byte])
self.state = 'WAIT_STOP'
# ...(完整逻辑参考源码)
3. 学习重点
-
状态机设计:
decode()
方法中的self.state
管理解码流程。 -
数据传递:
self.put()
将解码结果传递给下一层或输出。 -
采样率计算:
start()
中根据波特率计算每个位的采样点数。
【具体学习在后续文章中】
第四阶段:深入C层源码
1. 解码器注册流程(src/decoder.c)
// 加载Python解码器
SRD_PRIV int srd_decoder_load(const char *decoder_id) {
// 1. 搜索 decoders/ 目录
// 2. 动态加载Python模块
// 3. 验证解码器元数据(api_version, id等)
// 4. 注册到全局列表 decoder_list
}
2. 数据流处理(src/session.c)
// 核心处理循环
void srd_session_run(struct srd_session *sess) {
while (1) {
// 从硬件或文件读取数据
// 调用解码器的 decode() 方法
// 传递数据到下一层解码器(堆叠式解码)
}
}
4. Python与C交互(python/sigrokdecode.c)
- C调用Python:通过
PyObject_CallMethod
执行解码器的decode()
。 - 数据转换:C中的
struct srd_proto_data
转换为Python中的元组。
【具体学习在后续文章中】
第五阶段:实践与调试
1. 编写简单解码器
# mydecoder/pd.py
class Decoder(srd.Decoder):
api_version = 3
id = 'my_protocol'
name = 'My Protocol'
def __init__(self):
self.out_ann = self.register(srd.OUTPUT_ANN)
def decode(self, startsample, endsample, data):
self.put(startsample, endsample, self.out_ann, ['Hello World'])
2. 调试技巧
-
日志输出:
import logging logging.basicConfig(level=logging.DEBUG)
-
断点调试:
# C层断点 gdb --args python3 -m sigrokdecode.cli -i input.sr -P my_protocol # Python层断点 python3 -m pdb -m sigrokdecode.cli -i input.sr -P my_protocol
3. 测试数据生成
使用 sigrok-cli
生成测试信号:
sigrok-cli --generate uart:rx=0:baudrate=9600 -o test.sr