Protocol decoder HOWTO
Revision as of 23:37, 14 June 2012 by Uwe Hermann (talk | contribs)
This page serves as a quick-start guide for people who want to write their own sigrok protocol decoders (PDs).
It is not intended to replace the Protocol decoder API page, but rather to give a short overview/tutorial and some tips.
Introduction
TODO.
Files
- __init_.py
- <decodername>.py
- ...
Protocol decoder skeleton
This is a minimalistic framework/example for a sigrok protocol decoder (license header, comments, and some other parts omitted):
import sigrokdecode as srd ''' <Module-level docstring, accessible by frontends via the libsigrokdecode API> ''' class Decoder(srd.Decoder): api_version = 1 id = 'i2c' name = 'I2C' longname = 'Inter-Integrated Circuit' desc = '<Short, one-line description>' longdesc = '<Long, multi-line description>' license = 'gplv2+' inputs = ['logic'] outputs = ['i2c'] probes = [ {'id': 'scl', 'name': 'SCL', 'desc': 'Serial clock line'}, {'id': 'sda', 'name': 'SDA', 'desc': 'Serial data line'}, ] optional_probes = [] options = { 'addressing': ['Slave address size (in bits)', 7], } annotations = [ ['ASCII', 'Annotations in ASCII format'], ] def __init__(self, **kwargs): self.state = 'IDLE' def start(self, metadata): self.samplerate = metadata['samplerate'] self.out_proto = self.add(srd.OUTPUT_PROTO, 'i2c') self.out_ann = self.add(srd.OUTPUT_ANN, 'i2c') def report(self): # ... def decode(self, ss, es, data): for samplenum, (scl, sda) in data: # ...
Random notes, tips and tricks
- You should only use raise in a protocol decoder to raise exceptions in cases which are a clear bug in the protocol decoder.
- A simple and fast way to calculate a parity (i.e., count the number of 1 bits) over a number (0x55 in this example) is: ones = bin(0x55).count('1').
- A simple function to convert a BCD number (max. 8 bits) to an integer is: def bcd2int(b): return (b & 0x0f) + ((b >> 4) * 10).
- A nice way to construct method names according to (e.g.) protocol commands is: fn = getattr(self, 'handle_cmd_0x%02x' % cmd); fn(arg1, arg2, ...).