Tuesday, October 20, 2015

beta picoWiring Arduino compatible library

Before getting into the technical details, I'm going to start with a bit of history of Arduino.  No, I won't be talking the arduinogate dispute over who makes the hardware, it's the software I want to talk about.  From the way Arduino LLC's mouthpiece Marchese Banzi talks, he and his Arduino team came up with all the ideas that now many others have copied.  However the Arduino library was copied (or forked for those who prefer to speak git) from Wiring.  Wiring also took some ideas from MIT's Processing.  Although there have been a lot of changes to the Arduino library over the past four years, staying compatible with pre-1.0 Arduino has meant staying (mostly) compatible with Wiring.

I suspect if I had not mentioned Wiring, most people would mistake the above screenshot as coming from the Arduino IDE.  But it is actually Wiring 1.0.1.  Both Wiring and Arduino add a lot of code bloat and have examples of bad interface design, but I will use them for quick tests.  Between the two of them I prefer Wiring, since after the Arduino fork, Wiring implemented an optimized digitalWrite that is much faster than Arduino.

While it is the rare Arduino library that is well written, when it comes to testing new electronics the convenience of having something that works is worth holding your nose over the poor coding.  Although digitalWrite may not be the best way to abstract IO, it can be implemented efficiently as demonstrated by Wiring.  The same API can be used on the esp8266 with CHERTS or the esp8266 Arduino core.  For command-line development of Arduino code for the AVR Ino is an option, however the lack of optimization is still a problem.  Therefore I have written a library that has very little overhead and is compatible with the Arduino/Wiring API.

My goals were to make the library as small and as fast as possible, while supporting the ATmega168/328 series.  Since it has the fast digitalWrite, I started with some of the code from the Wiring AVR 8-bit core.  I removed the millis() timer, and implemented delay() using _delay_ms.  I modified the SPI class so it is a static class - instance variables unnecessarily take up memory when only one instance of the SPI class is created.  The Serial class took a lot of work to minimize.  Like the SPI class, I removed instance variables to make it a static class AKA singleton.  The AVR UART has a hardware FIFO, so removed the software FIFO the Serial class was using.

I've posted the code, which I still consider beta, to my github account.  I've done some testing with my (beta as well) piggy-prog project.  Both picoWiring and my dmbs fork are git submodules, so I can easily keep piggy-prog synced with bug fixes and improvements to picoWiring.  For piggy-prog, the code size improvement is significant.  Building piggy-prog with the 1.6.3 Arduino IDE results in a program that requires 4.5KB of flash.  Compiled with avr-gcc 4.9.2 with picoWiring, the flash size is just 1772 bytes.

No comments:

Post a Comment