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):# 定义一个私有变量countself.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 = dataif self.state == 'IDLE':if cmd in ('START', 'START REPEAT'):# self.putx([1, ['开始']])self.state = 'GET SLAVE ADDR'else:returnelif 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'