-
Notifications
You must be signed in to change notification settings - Fork 2
Description
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.