Protocol decoder HOWTO
Protocol decoder API
串口示例
逻辑分析仪 怎么添加自己需要的协议?
背景
使用逻辑分析仪时候,发现可以自定义协议,使用的 libsigrokdecode ,那事情就简单了
步骤
路径
找到安装路径的decoders
在此文件夹下就是各种协议,新增协议在此文件夹直接增加就好,可以参考例子example
其中文件:
- init.py 是必须的,从别的地方拷贝一个就好
- pd.py 是你的实现
代码
pd.py 中 class Decoder(srd.Decoder):就可以进行实现,抄例子就好
设置参数和获取参数值
参数是可以做成下拉菜单或者输入方式
想要获取设置的值是通过self.options[‘你的字段’]
# 开始执行解码任务时,由c底层代码自动调用一次
# 这里,完成一些解码结果项annotation类型的注册
# 类型有: OUTPUT_ANN,OUTPUT_PYTHON,OUTPUT_BINARY,OUTPUT_META
# self.register函数是c底层类提供的
def start(self):
self.out_ann = self.register(srd.OUTPUT_ANN)
self.rl78 = self.options['rl78_addr']
self.tp_mode = self.options['tp_mode']
解析显示
这里的annotation_rows 我认为是分行显示,annotations是数据属性,比如一行有多个属性可以显示,几行是由annotation_rows 指定
解码函数
def decode(self):
def decode(self, ss, es, data):
这里的有两种,一种是叠加协议的时候,是使用def decode(self, ss, es, data):,如果底层协议则使用 def decode(self):
显示注释函数
def putx(self, data):
self.put(self.ss, self.es, self.out_ann, data)
实际使用的就是self.put函数,ss 是开始位置,es是结束位置,out_ann输出的类型,这里是out_ann是屏幕,有其他参数可选
状态机
状态机比预期简单好多,每一步都是进入decode一次,比如在i2c上层的叠加协议,则是,每个都进来一次
# CMD: [annotation-type-index, long annotation, short annotation]
proto = {
'START': [0, 'Start', 'S'],
'START REPEAT': [1, 'Start repeat', 'Sr'],
'STOP': [2, 'Stop', 'P'],
'ACK': [3, 'ACK', 'A'],
'NACK': [4, 'NACK', 'N'],
'BIT': [5, 'Bit', 'B'],
'ADDRESS READ': [6, 'Address read', 'AR'],
'ADDRESS WRITE': [7, 'Address write', 'AW'],
'DATA READ': [8, 'Data read', 'DR'],
'DATA WRITE': [9, 'Data write', 'DW'],
}
ss es之间显示注释
cmd, databyte = data
cmd是START这些, data是传入的字节,data不一定有值,有的cmd下没有值
判断可以使用 in 多个判断
def reset(self):
# 定义一个私有变量count
self.state = 'IDLE'
def start(self):
self.out_ann = self.register(srd.OUTPUT_ANN)
self.rl78 = self.options['rl78_addr']
self.tp_mode = self.options['tp_mode']
def decode(self, ss, es, data):
cmd, databyte = data
if self.state == 'IDLE':
if cmd in ('START', 'START REPEAT'):
# self.putx([1, ['开始']])
self.state = 'GET SLAVE ADDR'
else:
return
elif self.state == 'GET SLAVE ADDR':
if cmd == 'ADDRESS WRITE':
if databyte == self.rl78:
self.putx([1, ['mcu 7位地址:0x%02X' % self.rl78]])
self.state = 'IDLE'
elif cmd == 'ADDRESS READ':
if databyte == self.rl78:
self.putx([1, ['mcu 7位地址:0x%02X' % self.rl78]])
self.state = 'IDLE'
对于ACK NACK时候也是进入的,假如不进行判断,所以状态机没变化,可以用以下方式,将状态机回归到初始状态
elif cmd in ('NACK', 'STOP'):
self.state = 'IDLE'