[GN] sigrokdecode 模块学习指南 --- 准备阶段

系列文章目录

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

  1. 安装依赖
# 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  # 应返回有效路径
  1. 获取源码
# 推荐通过 HTTPS 克隆(避免 git:// 协议问题)
git clone https://github.com/sigrokproject/libsigrokdecode.git
cd libsigrokdecode

  1. 构建脚本
# 若缺少 autogen.sh 权限
chmod +x autogen.sh

# 生成 configure 脚本
./autogen.sh
  1. 配置编译选项
# 标准配置(默认安装到 /usr/local)
./configure

# 若需指定 Python 版本(例如 Python 3.8)
PYTHON=python3.8 ./configure
  1. 编译与安装
make -j$(nproc)        # 并行编译(加速)
sudo make install      # 安装到系统目录
sudo ldconfig          # 更新动态库缓存
  1. 验证安装
# 检查版本信息
sigrok-cli --version

# 列出所有解码器(需至少安装一个)
sigrok-cli --show | grep decoders

安装 sigrok-cli(命令行工具)

  1. 安装依赖
# Ubuntu/Debian
sudo apt install build-essential git autoconf automake libtool \
    pkg-config libglib2.0-dev libzip-dev libcheck-dev
  1. 获取源码并编译
git clone https://github.com/sigrokproject/sigrok-cli.git
cd sigrok-cli
./autogen.sh
./configure
make -j$(nproc)
sudo make install
sudo ldconfig
  1. 验证安装
sigrok-cli --version
# 正常输出示例:sigrok-cli 0.7.2

安装 PulseView(图形界面)

  1. 安装依赖
# 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
  1. 获取源码并编译
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
  1. 验证安装
pulseview --version
# 正常输出示例:PulseView 0.4.2

关联 libsigrokdecode

  1. 确保动态库路径正确
# 检查 libsigrokdecode 是否在链接器路径中
sudo ldconfig -p | grep libsigrokdecode

# 若未找到,手动添加路径(假设安装到 /usr/local/lib)
echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/sigrok.conf
sudo ldconfig
  1. 配置 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

完整验证

  1. 测试硬件检测
sigrok-cli --scan
# 正常输出示例(需连接支持设备):
# The following devices were found:
# demo - Demo device with 8 channels
  1. 运行完整解码流程
# 生成测试信号(假设已安装 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 错误表明以下可能性:

  1. libsigrokdecode 的 Python 绑定未正确安装
  2. Python 包安装路径不符合预期(如未安装到 /usr/local/lib/...)。
  3. 编译时未启用 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
  • 可视化工具: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。这个文件包含了项目的主要逻辑和功能实现。启动时,项目会加载并初始化解码器模块,并根据配置文件进行相应的设置。

  1. 初始化lib.c 初始化库并注册全局解码器。
  2. 会话管理session.c 创建解码会话,管理输入数据流。
  3. 解码器加载decoder.c 扫描并加载 decoders/ 目录下的Python解码器。
  4. 数据处理: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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GGood_Name

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值