Skip to content

Replace current SCPI Parser #1

@negentropicdev

Description

@negentropicdev

The SCPI parser I initially used cannot keep up with larger commands, such as would be used when trying to send messages to be forwarded over UART / I2C / SPI. The SCPI parser currently in use also has too large of a footprint to fit onto a chip like the ATmega328p used on an Arduino and is currently blocking the ability to build for that platform. Many optimizations could be made in a new bit of parser code to both drastically shrink the build footprint and increase the execution speed. For instance, the current SCPI parser uses a lot of static non-inlined functions to determine character classes within the lexer and relatively long chains of if conditions in some instances to determine a character type:
static int isqdigit(int c) { if ((c == '0') || (c == '1') || (c == '2') || (c == '3') || (c == '4') || (c == '5') || (c == '6') || (c == '7')) { return 1; } return 0; }

This is a very robust and easy to follow approach but adds significant overhead on the two metrics we care about in addition to the issue with reading larger strings which I don't care to spend any time tracking down since it doesn't fit in Arduino storage anyway. There is also a lot of code built in to the existing parser to parse the SCPI messages to handle whereas a much more efficient way of building up the command more programmatically could be created to leverage the firmware developer doing a bit of "pre-compiling" of the message specifier.

For an example of an optimization of the above character class test approach, a common practice is to create a lookup table array corresponding to the numeric ascii value of a character. Each of these array elements would be a bitmask where each bit signifies a specific character class. In the current parser's method of the character class test functions, different states within the parser/lexer care about subsets of the character classes but there is inevitably a lot of overlap between multiple states so a lot of the class test functions are called in numerous states. With the lookup table bitfield approach, each test is just a simple bitwise and test that is easily inlined and produces significantly smaller builds and is much faster than the many instructions it takes to setup and tear down a function call so higher comms rates will be achievable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions