logicmso
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSaleae Logic MSO Analysis
Saleae Logic MSO 捕获数据分析
This skill enables analysis of captured signals from Saleae Logic MSO devices using the Python library. It supports loading binary exports, analyzing signal transitions, and decoding common protocols.
saleae-mso-api本技能支持使用 Python库分析来自Saleae Logic MSO设备的捕获信号,可加载二进制导出文件、分析信号转换并解码常见协议。
saleae-mso-apiPrerequisites
前置条件
- Python package — Do NOT blindly pip install. First check if it's already installed:
saleae-mso-apiOnly if that fails, install it:bashpython3 -c "from saleae.mso_api.binary_files import read_file; print('saleae-mso-api is available')"pip install saleae-mso-api - Binary export files from Saleae Logic software (format)
.bin
- Python包 — 请勿盲目使用pip安装。请先检查是否已安装:
saleae-mso-api只有当上述命令执行失败时,才进行安装:bashpython3 -c "from saleae.mso_api.binary_files import read_file; print('saleae-mso-api is available')"pip install saleae-mso-api - 来自Saleae Logic软件的二进制导出文件(格式)
.bin
Quick Reference
快速参考
Loading Binary Files
加载二进制文件
python
from saleae.mso_api.binary_files import read_file
from pathlib import Path
file_path = Path("capture.bin")
saleae_file = read_file(file_path)python
from saleae.mso_api.binary_files import read_file
from pathlib import Path
file_path = Path("capture.bin")
saleae_file = read_file(file_path)Access metadata
访问元数据
print(f"Version: {saleae_file.version}")
print(f"Type: {saleae_file.type}")
print(f"Version: {saleae_file.version}")
print(f"Type: {saleae_file.type}")
Access data
访问数据
contents = saleae_file.contents
undefinedcontents = saleae_file.contents
undefinedDigital Capture Structure
数字捕获数据结构
Digital exports contain with chunks:
DigitalExport_V1python
chunk = saleae_file.contents.chunks[0]数字导出文件包含格式的数据块:
DigitalExport_V1python
chunk = saleae_file.contents.chunks[0]Key attributes:
关键属性:
chunk.initial_state # Starting logic level (0 or 1)
chunk.transition_times # numpy array of transition timestamps (seconds)
chunk.sample_rate # Capture rate in Hz
chunk.begin_time # Capture start time
chunk.end_time # Capture end time
undefinedchunk.initial_state # 初始逻辑电平(0代表低电平,1代表高电平)
chunk.transition_times # 信号转换时间戳的numpy数组(单位:秒)
chunk.sample_rate # 捕获采样率(单位:Hz)
chunk.begin_time # 捕获开始时间
chunk.end_time # 捕获结束时间
undefinedCalculating Pulse Durations
计算脉冲持续时间
python
import numpy as np
times = np.array(chunk.transition_times)
durations_ms = np.diff(times) * 1000 # Convert to millisecondspython
import numpy as np
times = np.array(chunk.transition_times)
durations_ms = np.diff(times) * 1000 # 转换为毫秒If initial_state is 0 (LOW):
如果初始状态为0(低电平):
- Even indices (0, 2, 4...) = HIGH pulse durations
- 偶数索引(0、2、4...)= 高电平脉冲持续时间
- Odd indices (1, 3, 5...) = LOW gap durations
- 奇数索引(1、3、5...)= 低电平间隔持续时间
If initial_state is 1 (HIGH):
如果初始状态为1(高电平):
- Even indices = LOW gap durations
- 偶数索引 = 低电平间隔持续时间
- Odd indices = HIGH pulse durations
- 奇数索引 = 高电平脉冲持续时间
undefinedundefinedHelper Scripts
辅助脚本
This skill includes helper scripts for common analysis tasks:
本技能包含用于常见分析任务的辅助脚本:
Protocol Analyzer
协议分析器
bash
undefinedbash
undefinedAnalyze signal characteristics
分析信号特征
python3 skills/logicmso/analyze_protocol.py capture.bin
python3 skills/logicmso/analyze_protocol.py capture.bin
Show detailed timing histogram
显示详细时序直方图
python3 skills/logicmso/analyze_protocol.py capture.bin --histogram
python3 skills/logicmso/analyze_protocol.py capture.bin --histogram
Show detected timing clusters
显示检测到的时序聚类
python3 skills/logicmso/analyze_protocol.py capture.bin --clusters
python3 skills/logicmso/analyze_protocol.py capture.bin --clusters
Export transitions to CSV
将信号转换数据导出为CSV
python3 skills/logicmso/analyze_protocol.py capture.bin --export transitions.csv
python3 skills/logicmso/analyze_protocol.py capture.bin --export transitions.csv
Show raw transition values
显示原始转换值
python3 skills/logicmso/analyze_protocol.py capture.bin --raw -n 50
undefinedpython3 skills/logicmso/analyze_protocol.py capture.bin --raw -n 50
undefinedCommon Protocol Patterns
常见协议模式
UART (Asynchronous Serial)
UART(异步串行协议)
- Idle state: HIGH
- Start bit: LOW (1 bit period)
- Data bits: 8 bits, LSB first
- Stop bit: HIGH (1-2 bit periods)
- Common baud rates: 9600, 19200, 38400, 57600, 115200
- Bit period calculation: seconds
1/baud_rate - Identifying features: Consistent bit periods, durations are multiples of base period
- 空闲状态:高电平
- 起始位:低电平(持续1个比特周期)
- 数据位:8位,最低有效位(LSB)优先
- 停止位:高电平(持续1-2个比特周期)
- 常见波特率:9600、19200、38400、57600、115200
- 比特周期计算:秒
1/baud_rate - 识别特征:比特周期一致,持续时间为基础周期的整数倍
SPI (Serial Peripheral Interface)
SPI(串行外设接口)
- 4 signals: SCLK (clock), MOSI (master out), MISO (master in), CS (chip select)
- Clock polarity (CPOL): Idle clock state (0=LOW, 1=HIGH)
- Clock phase (CPHA): Sample edge (0=leading, 1=trailing)
- Data: Sampled on clock edges, typically 8 bits per transaction
- Identifying features: Regular clock signal, CS goes LOW during transaction
- 4路信号:SCLK(时钟)、MOSI(主机输出)、MISO(主机输入)、CS(片选)
- 时钟极性(CPOL):时钟空闲状态(0=低电平,1=高电平)
- 时钟相位(CPHA):采样边沿(0=上升沿,1=下降沿)
- 数据:在时钟边沿采样,通常每笔事务传输8位数据
- 识别特征:规律的时钟信号,事务期间CS变为低电平
I2C (Inter-Integrated Circuit)
I2C(集成电路间总线)
- 2 signals: SDA (data), SCL (clock)
- Idle state: Both HIGH (pulled up)
- Start condition: SDA falls while SCL is HIGH
- Stop condition: SDA rises while SCL is HIGH
- Data: 8 bits + ACK/NACK, MSB first
- Address: 7-bit (first byte after START)
- Identifying features: START/STOP conditions, 9 clock pulses per byte (8 data + ACK)
- 2路信号:SDA(数据)、SCL(时钟)
- 空闲状态:两路信号均为高电平(上拉)
- 起始条件:SCL为高电平时,SDA出现下降沿
- 停止条件:SCL为高电平时,SDA出现上升沿
- 数据:8位数据+1位ACK/NACK,最高有效位(MSB)优先
- 地址:7位地址(起始条件后的第一个字节)
- 识别特征:起始/停止条件,每个字节对应9个时钟脉冲(8位数据+1位ACK)
1-Wire
1-Wire(单总线协议)
- Single signal: DQ (data/power)
- Idle state: HIGH (pulled up)
- Reset pulse: Master pulls LOW for 480us minimum
- Presence pulse: Slave responds LOW for 60-240us
- Write 0: LOW for 60-120us
- Write 1: LOW for 1-15us, then release
- Read: Master samples 15us after pulling LOW
- 单路信号:DQ(数据/电源)
- 空闲状态:高电平(上拉)
- 复位脉冲:主机拉低电平至少480微秒
- 存在脉冲:从机响应拉低电平60-240微秒
- 写0:拉低电平60-120微秒
- 写1:拉低电平1-15微秒后释放
- 读操作:主机拉低电平15微秒后采样信号
Analysis Workflow
分析流程
Step 1: Initial Exploration
步骤1:初始探索
python
from saleae.mso_api.binary_files import read_file
import numpy as np
f = read_file("capture.bin")
chunk = f.contents.chunks[0]
print(f"Sample rate: {chunk.sample_rate/1e6:.1f} MHz")
print(f"Duration: {chunk.end_time - chunk.begin_time:.3f}s")
print(f"Initial state: {'HIGH' if chunk.initial_state else 'LOW'}")
print(f"Transitions: {len(chunk.transition_times)}")python
from saleae.mso_api.binary_files import read_file
import numpy as np
f = read_file("capture.bin")
chunk = f.contents.chunks[0]
print(f"采样率:{chunk.sample_rate/1e6:.1f} MHz")
print(f"捕获时长:{chunk.end_time - chunk.begin_time:.3f}秒")
print(f"初始状态:{'高电平' if chunk.initial_state else '低电平'}")
print(f"信号转换次数:{len(chunk.transition_times)}")Step 2: Analyze Timing Patterns
步骤2:分析时序模式
python
times = np.array(chunk.transition_times)
durations_us = np.diff(times) * 1e6 # microsecondspython
times = np.array(chunk.transition_times)
durations_us = np.diff(times) * 1e6 # 转换为微秒Separate HIGH and LOW durations
分离高电平和低电平持续时间
high_idx = 0 if chunk.initial_state == 0 else 1
high_durations = durations_us[high_idx::2]
low_durations = durations_us[(1-high_idx)::2]
print(f"HIGH pulses: min={min(high_durations):.1f}us, max={max(high_durations):.1f}us")
print(f"LOW gaps: min={min(low_durations):.1f}us, max={max(low_durations):.1f}us")
high_idx = 0 if chunk.initial_state == 0 else 1
high_durations = durations_us[high_idx::2]
low_durations = durations_us[(1-high_idx)::2]
print(f"高电平脉冲:最小值={min(high_durations):.1f}us,最大值={max(high_durations):.1f}us")
print(f"低电平间隔:最小值={min(low_durations):.1f}us,最大值={max(low_durations):.1f}us")
Find unique timing values (cluster detection)
查找唯一时序值(聚类检测)
unique_high = sorted(set(round(d, -1) for d in high_durations)) # Round to 10us
unique_low = sorted(set(round(d, -1) for d in low_durations))
print(f"HIGH clusters: {unique_high}")
print(f"LOW clusters: {unique_low}")
undefinedunique_high = sorted(set(round(d, -1) for d in high_durations)) # 四舍五入到10微秒
unique_low = sorted(set(round(d, -1) for d in low_durations))
print(f"高电平聚类:{unique_high}")
print(f"低电平聚类:{unique_low}")
undefinedStep 3: Identify Protocol
步骤3:识别协议
Based on timing patterns:
- UART: Consistent bit periods, durations are multiples of base period, idles HIGH
- SPI/I2C: us-scale timing, needs clock signal analysis, look for regular patterns
- 1-Wire: Reset pulses ~480us, data pulses 1-120us
基于时序模式:
- UART:比特周期一致,持续时间为基础周期的整数倍,空闲状态为高电平
- SPI/I2C:微秒级时序,需要分析时钟信号,寻找规律模式
- 1-Wire:复位脉冲约480微秒,数据脉冲1-120微秒
Step 4: Decode
步骤4:解码
Once protocol is identified, decode based on protocol rules. For unknown/custom protocols, analyze the timing clusters and bit patterns to determine encoding scheme.
确定协议后,根据协议规则进行解码。对于未知/自定义协议,分析时序聚类和比特模式以确定编码方案。
UART Decoding Example
UART解码示例
python
from saleae.mso_api.binary_files import read_file
import numpy as np
f = read_file("uart_capture.bin")
chunk = f.contents.chunks[0]
times = np.array(chunk.transition_times)
BAUD = 115200
BIT_PERIOD = 1 / BAUD
def decode_uart_byte(start_time, times, bit_period):
"""Decode a single UART byte starting at start_time."""
byte_val = 0
for bit_num in range(8):
# Sample at center of each bit (1.5, 2.5, 3.5... bit periods from start)
sample_time = start_time + (1.5 + bit_num) * bit_period
# Find state at sample_time
idx = np.searchsorted(times, sample_time)
state = (chunk.initial_state + idx) % 2
if state:
byte_val |= (1 << bit_num) # LSB first
return byte_valpython
from saleae.mso_api.binary_files import read_file
import numpy as np
f = read_file("uart_capture.bin")
chunk = f.contents.chunks[0]
times = np.array(chunk.transition_times)
BAUD = 115200
BIT_PERIOD = 1 / BAUD
def decode_uart_byte(start_time, times, bit_period):
"""解码从start_time开始的单个UART字节。"""
byte_val = 0
for bit_num in range(8):
# 在每个比特的中间位置采样(从起始点开始1.5、2.5、3.5...个比特周期)
sample_time = start_time + (1.5 + bit_num) * bit_period
# 查找采样时间点的信号状态
idx = np.searchsorted(times, sample_time)
state = (chunk.initial_state + idx) % 2
if state:
byte_val |= (1 << bit_num) # 最低有效位优先
return byte_valFind start bits (falling edges when idle HIGH)
查找起始位(空闲高电平时的下降沿)
decoded_bytes = []
i = 0
while i < len(times) - 1:
# Look for falling edge (start bit)
if chunk.initial_state == 1 or i > 0:
byte_val = decode_uart_byte(times[i], times, BIT_PERIOD)
decoded_bytes.append(byte_val)
# Skip to next potential start bit (after stop bit)
i += 1
while i < len(times) and times[i] < times[i-1] + 10 * BIT_PERIOD:
i += 1
else:
i += 1
print("Decoded:", bytes(decoded_bytes))
undefineddecoded_bytes = []
i = 0
while i < len(times) - 1:
# 查找下降沿(起始位)
if chunk.initial_state == 1 or i > 0:
byte_val = decode_uart_byte(times[i], times, BIT_PERIOD)
decoded_bytes.append(byte_val)
# 跳转到下一个潜在的起始位(跳过停止位)
i += 1
while i < len(times) and times[i] < times[i-1] + 10 * BIT_PERIOD:
i += 1
else:
i += 1
print("解码结果:", bytes(decoded_bytes))
undefinedCTF Tips
CTF技巧
- Unknown protocol: Start with to see timing distribution
analyze_protocol.py --clusters - Multiple channels: Export each channel separately, identify clock vs data lines
- Inverted signals: Some captures have inverted logic levels
- Timing variations: Real hardware has jitter, use threshold-based detection
- Partial captures: Check if capture starts mid-transmission
- Custom protocols: Look for repeating patterns, identify sync/framing bytes
- 未知协议:先运行查看时序分布
analyze_protocol.py --clusters - 多通道数据:单独导出每个通道的数据,区分时钟线和数据线
- 信号反转:部分捕获数据的逻辑电平是反转的
- 时序偏差:实际硬件存在抖动,使用基于阈值的检测方法
- 不完整捕获:检查捕获是否在传输过程中开始
- 自定义协议:寻找重复模式,识别同步/帧字节
Troubleshooting
故障排查
"No module named 'saleae.mso_api'"
提示“No module named 'saleae.mso_api'”
First verify it's truly missing:
bash
python3 -c "from saleae.mso_api.binary_files import read_file"Only if the import fails, install it:
bash
pip install saleae-mso-api先确认库确实未安装:
bash
python3 -c "from saleae.mso_api.binary_files import read_file"只有当导入失败时,再执行安装:
bash
pip install saleae-mso-apiEmpty or corrupt file
文件为空或损坏
Check file size and try re-exporting from Saleae Logic software.
检查文件大小,尝试从Saleae Logic软件重新导出。
No transitions detected
未检测到信号转换
- Signal may be constant (stuck high/low)
- Check if correct channel was exported
- Verify trigger settings in original capture
- 信号可能为恒定电平(一直高/低)
- 检查是否导出了正确的通道
- 验证原始捕获中的触发设置
Timing seems wrong
时序结果异常
- Check sample rate matches original capture settings
- Verify time units (seconds vs milliseconds vs microseconds)
- 检查采样率是否与原始捕获设置一致
- 确认时间单位(秒、毫秒、微秒)是否正确