Hello,

There are several reasons for the desire to develop sigrok protocol
decoders without installing the complete environment that is necessary
to build sigrok, e.g.

 * You have an OS that is not supported as build environment.
 * You want to use PulseView on a PC without the build environment and
   need to investigate what's going on in your decoder.

In some cases it's useful to use the logger to output interesting
information. But with a growing complexity of your decoder, this
approach can cause more and more diagnostic code in your decoder that's
not necessary for its job: decoding.

I use a way to decouple the decoder execution from PulseView and
sigrok-cli. This allows to debug it with single-step and variable view
with my favorite debugger. The decoder needs an environment that can be
setup with a few lines:

   # script to load and debug a protocol decoder
   from sigrokdecode import SRD_CONF_SAMPLERATE
   from mydecoder import Decoder
   from data import data
   import logging

   testee = Decoder()
   testee.applyOptions({'log':'~/decoder.log'},)
   logging.basicConfig(level=logging.DEBUG)
   testee.start()
   testee.metadata(SRD_CONF_SAMPLERATE)

   for d in data:
        testee.decoder(*d)

It still needs a module sigrokdecode. This can be mocked easily:

   # mock the sigrokdecode module, providing the Decoder class and some
   constants
   OUTPUT_ANN = 1
   OUTPUT_PYTHON = 2
   OUTPUT_BINARY = 3
   OUTPUT_META = 4
   SRD_CONF_SAMPLERATE = 10

   class Decoder(object):
        options = ( {'id': 'log',
                    'desc': 'Write log file "/pnet.log"',
                    'default': 'no', 'values': ('yes', 'no')}, )

        def __init__(self):
            pass

        def register(self, output_type):
            return 1000 + output_type

        def put(self, startsample, endsample, output_id, data):
            self.logger.debug('put ss:{} es:{} id:{}
   {}'.format(startsample, endsample, output_id, data))
            pass

        def applyOptions(self, actualValues):
            instanceOpts = {}
            for k in self.options:
                id = k['id']
                try:
                    instanceOpts[id] = actualValues[id]
                except:
                    instanceOpts[id] = k['default']
            self.options = instanceOpts

The test script also needs the data that will be passed to the decoder.
That is imported from a separate file "data.py" with a content like this:

   data = [
        (2204,2217,['STARTBIT', 0, 0]),
        (2334,2347,['STOPBIT', 0, 1]),
        (2203,2347,['FRAME', 0, (304, True)]),
        (2348,2361,['STARTBIT', 0, 0]),
   ]

This data has been generated with another decoder whose decode function
that just writes the parameter values from a real PulseView session to
that file "data.py".

What do you think about this approach to build a debug environment?
Beside the possibility to use any python debugger, you can also create a
unit test environment.

I used this only for stacked protocol decoders. But I think it should be
possible to use a similar way to use it for

Best regards,
Helge

_______________________________________________
sigrok-devel mailing list
sigrok-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sigrok-devel

Reply via email to