Arduino C++ Investigations - Introduction

As mentioned in the last Wideband Transmission, I recently viewed a presentation from CppCon 2016 which convinced me that a lot of my preconceived notions about the (lack of) suitability of C++ for use in microcontroller applications might be misplaced.

The standard lore (go ask Wes Hayward W7ZOI his opinion of lore) states that C++ is inefficient in generating the compact binaries that are required when using a device with very limited program storage and RAM space, as you will find with microcontrollers (especially 8-bit controllers). Given that C is a probably fairly categorized as a mid-level language, and that C++ easily falls into the high-level language category with its much larger feature set, it seems natural to believe that there has to be an overhead cost to pay when using C++ over C. Yet, if you take the time to watch that video, you can see that it is possible to use advanced features of C++ and incur little to no overhead in the binary.

Not to say that you can just blithely use C++ without the possibility of incurring an overhead penalty. I've tried it and had some horrible results, and chalked my experience up to the old lore being correct as a general case. But that's obviously not true.

Goals

What I intend to do with this series is to look into ways that the features of C++ (mostly C++11 at this point) can be leveraged in the Arduino environment to take advantage of the advanced features of the language (and perhaps even things such as the Standard Template Library) while incurring no or perhaps a very small penalty in flash and RAM usage.

As most of you are probably aware, Arduino is based on C++, and every Arduino library coder has to use at least minimal C++ functionality in order to create a library. However, in the name of abstracting away much complexity, Arduino sketches are written more in C-style than modern C++. That being the default case, there's no reason we can't incorporate more C++ coding techniques into our Arduino sketches, as long as doing so serves our purposes of being able to use the higher-level abstractions without paying a penalty.

Before seeing the above presentation, I had already been thinking about this topic because good old Hackaday has been running a series of articles about it. While I may cover some areas previously addressed by said articles, I notice that many (but not all) of the previously mentioned posts don't delve into making the measurements of how implementing the C++ coding patterns affect code and RAM size (or perhaps execution speed). Data is king, so I intend to provide as much of it as possible so that you can see actual proof of the effects of migrating to C++ coding.

Just so you know where I'm coming from, let me tell you about where I'm at in my journey as a coder. I've been writing C for microcontrollers for a fair bit of time now, and I think I'm at least proficient at it, but not an expert by any means. I've dabbled in C++, but never really written any major programs in it, so I'm on a learning journey here as well. I'm sure I probably won't do everything perfectly or the most efficiently, but by holding to what the data tells me, I think I can provide some useful information to all while I learn some new things for myself.

Areas of Investigation

At this point, I don't have a list of topics for this series that is set in stone. I do have some initial ideas for investigation, but plan to follow other leads as they present themselves and as I learn more about this topic. From my initial notes, here are some potential topics you may see in future posts:

  • Using constexpr
  • C++ Standard Library and Standard Template Library usage
  • Using lambda functions/inline functions
  • Variable declaration: auto vs explicit
  • Other C++11 features, such as the new for loop syntax that functions as a foreach

Please feel free to comment below if you have some other topics of potential interest.

Tools

In order to maintain consistency across the series, I intend to use the same microcontroller platform in all articles. The controller of choice will be my Empyrean Alpha board, which is basically an Arduino Zero minus the debugging circuitry on a form factor that can be plugged into a solderless breadboard, just like the Arduino Nano and related products. The Empyrean Alpha uses an Atmel ATSAMD21G18A microcontroller, which runs with a 48 MHz clock speed and has 256 kB of flash program memory and 32 kB of RAM, which is ample for many types of projects.

Hopefully in the near future, I'll be selling the Empyrean Alpha and its little brother Beta through Etherkit, so stay tuned for further news on that.

The Arduino environment for ATSAMD microcontrollers uses the arm-none-eabi-gcc toolchain, which has a variety of very nice tools that are available in addition to the compiler. One of those is arm-none-eabi-size, which can give a breakdown of the flash and RAM usage of a sketch simply by feeding it the file name of the ELF file that the compiler generates. For example:

jason@oberon /tmp/arduino_build_994621 $ arm-none-eabi-size -B foreach_test.ino.elf
   text    data     bss     dec     hex filename
   9732     256    1780   11768    2df8 foreach_test.ino.elf

From the above, you can see the text section, which indicates size of the program in flash memory, the data section, which is the initialized variable storage in RAM, and the bss section, which is allocated but uninitialized variable storage in RAM. Pretty easy to use and interpret. We'll talk about this tool a bit more in the first investigation so that we have a good understanding about it.

Most likely, I'll also be using the Compiler Explorer tool, as was used in the video above. It looks like a very handy way to quickly and roughly demonstrate how code changes affect the assembler output from the compiler.

Onward

Now that we have the preliminaries out of the way, I'm ready to start tackling this series. Watch this blog for the first installation, which will be coming soon. My patrons will have early draft access to articles in the series, and will have a chance to chime in there with suggestions to help me with the final article on nt7s.com. See you soon!

Wideband Transmission #10

OpenTechLab

If you've been reading my blog for any amount of time, you've probably observed that I'm a big fan of all things open source, especially on the hardware side of things. One area where OSHW seems to be lagging a bit is in the test & measurement department, so it was a very pleasant surprise for me to stumble upon a fairly new channel on YouTube about a month ago.

As you can see from the first video, the presenter (sorry, I couldn't find the name of the bloke who makes these videos) gives an overview of the cheap logic analyzers on the market that can be loaded with open source firmware and then gives a very detailed demonstration on how to use the devices with the nifty open source Sigrok T&M suite (especially the PulseView GUI tool) and how to use a Linux environment and scripting to take measurements.

If you have any interest in this space, this is definitely a channel to which you should subscribe. There is also a show notes site that has links and other resources for the videos.

Using C++ in Arduino

In another case of me stumbling upon something which takes me down a rabbit hole, last week I was watching coding videos on YouTube when this one was recommended in the comments of another:

It's quite a long video, but if you have any interest in coding and are an old fart who grew up with 8-bit personal computers (or are at least a fan of retrocomputing), then the time will pass quickly on this one. It sounds crazy, but the presenter (Jason Turner) of this talk was able to make a game for the Commodore 64 in modern C++! The way he did it was to create a tool to convert from the 80386 flavor of x86 assembler to 6502 assembler (well really 6510 in this case), which apparently is more feasible than you may think. His development environment is an online tool called Compiler Explorer, which for some reason I only learned about with this video. It automagically spits out assembler from C++ compiled from a variety of different compilers. In this case, the Turner created a custom local version of this tool to do the 6502 conversion.

I was gobsmacked at multiple times in this video. Many of the newest C++ features (from the C++17 standard) were used. With some careful coding, Turner was able to produce code with literally no overhead from all of the C++ features. The compiler was able to optimize many lines of C++ down to a handful of assembler op codes. Just watch it, you'll be amazed as well.

This video, in conjunction with the series of posts that Hackaday has been running about using C++11 in Arduino, has convinced me that it would worth it to investigate the use of C++ in the Arduino coding environment. Arduino library coders already have to use a base level of C++ when they write for the ecosystem, but most people who write sketches do it in vanilla C-style (well, the bastardized Arduino version of it anyway). After seeing that talk, I had a lot of preconceptions of C++ overhead blown away. The ability to use the modern features of C++11 sound tempting indeed, so I plan to do some investigations into the feasibility of incorporating more C++ patterns into Arduino sketches, and I'll be posting my findings here. Stay tuned.

KiCad PCB Rendering Tool

I have a habit of skimming my RSS reader (yes, I'm one of those old fogies who still uses one) in the morning while drinking my coffee, opening tabs of interesting things to examine in further detail later, while simply reviewing the rest of the new posts. Sometimes that means it takes me a bit to get back around to something intriguing among my many browser tabs.

Such is the case with this article from Hackaday. It's just a short blurb about a new open source Python tool for making 2D renderings of KiCad boards. The attached demonstration image certainly looked nice. When I finally got around to downloading the code from GitHub and trying it out on one of my designs, I was pleasantly surprised. The script made a very sharp SVG rendering of my board, but unfortunately, there are only a handful of components in the PcbDraw-Lib library, which meant that most of my stuff didn't get rendered.

Since I've been looking for a way to make nice illustrations of my PCBs for documentation and promotional purposes, I decided that I'd invest some time in adding components to the library, since I think the project has a lot of promise. After about half a day of muddling through making component drawings in Inkscape by studying datasheet engineering drawings, I was able to output a complete render of my Empyrean board, which you can see above. I'm quite happy with the result.

I've got a pull request in for the components that I've created so far, and as I continue to use the tool and fill out more of the library, I will continue to submit them upstream. While it's still pretty rough around the edges, this project gets a strong recommend from me.