Quick Tips to Fake Your Way Through C++ As A C Programmer

In 2020, many things were just unusual. My previous project had a mixture of C and modern C++ but two things were clear: It was one person who setup everything (and since left the day I arrived) who was driving the more interesting (and difficult to understand) C++ and most of the team was truly more comfortable with C.

I am definitely part of the larger group of C programmers who remember the 90’s and 00’s where C++ was still considered an excess memory user. When the team doubled and many felt more comfort with modern C++, there was a push to go full C++ and at least go C++ 17 or better. I felt this was a great time to update since so many of the team would need to do so. Here’s a handful of things I learned that give you some “C++ ness”.

Warning: I’m still just a noob here despite technically learning C++ before C. If you are already rolling C++ deep, you’ll likely find this boring, annoying, or worse case feel the need to “well actual” me. None of us is there for that, so let’s just part ways and meet up on twitter.

Additional observation before we begin: After spending the better part of 2020 in C++, I have observed that even those with years of experience in a professional setting, cannot easily explain the intricacies of C++. It seemed that C++14 onward provided some new interesting features, but also created some inconsistencies. It was easy to notice this in a few weeks and no one was great at explaining the “whys” or “how do you know when to…’s” and so I won’t be addressing this. The fact is this language has evolved and continues to evolve.

Namespaces

Perhaps you are aware of this concept from Linux kernel work or are a lover of the keyword extern. The names matter and vagueness is a problem. Modern C++ uses namespaces to scope limit modules including functions, classes, constants, etc…

namespace MyNewSpace {
  // All your favorite code stuff in here.
  int kFavoriteInt = 13;
  void FavoriteFunction(int input) {}
 
} // MyNewSpace

MyNewSpace::FavoriteFunction(MyNewSpace::kFavoriteInt);

You can nest namespaces too. You can use the same namespaces for a device driver, a subsystem and the unit tests. Consider it a way to organize your code.

Also there are anonymous namespaces which act as a replacement for the keyword static in C. This is particularly true if you want your static functions that are not part of a class.

Speaking of … how do you include your well-vetted C libraries?

Integrating C Libraries

So you are dedicated to using the C++ compiler but all you have are your C headers and libraries? Try this one. Just wrap your headers like this:

#ifdef __cplusplus
extern "C" {
#endif

// All your C code declarations.

#ifdef __cplusplus
}
#endif

Now just include the file as usual. You can find more details here.

#define No More!

Sure you could just keep on #define away but you wanna keep people wondering “Hey aren’t they just a C programmer!?!?” Try this to keep them guessing. Replace your #define and avoid the preprocessor by using constexpr (I would read up as this has changed several times since C++11).

#define MAX_FAVORITE_VALUE (0xFF)
// Becomes ...
constexpr uint8_t kMaxFavoriteValue = 0xFF;

Notice that above that value is now const AND typed. Pretty simple and straightforward. You can also have derived expressions. One benefit is debugging is easier. I was no longer buried trying to figure out what was wrong in an obfuscated code.

Typecasting

My opinion is that this is where C++ gets cluttered. You DON’T HAVE to do this but it will let people wonder. You have 4 types of casts:

  • static_cast – pretty much use it in 95% of all cases
  • const_cast – add/removes const from target expression
  • reinterpret_cast – less restrictive casting than previous two. Use cautiously and read up.
  • dynamic_cast – casting a class up/down its hierarchy.
int array[5];  // Using a c-style array here. No biggie.
byte * ptr = static_cast<byte*> (array);

References Are the New Hotness

References aren’t really new or hot, but for a C programmer, we are really used to passing pointers and references are a new concept. Maybe you just need to pass a class instance to call a function later on, so just pass the reference or a pointer to the class and save the instance as <type>& instead of a <type>*. It will mean you don’t need to check for NULL pointers (in C++ nullptr) anymore.

Quicky Classes

So you want to use classes but are used to passing in a big struct with the “class” details to your function, classes are just flipping the script.

  1. Everything you passed in to modify and keep track of in your C code, is going to become a private member variable in your C++ class. Note: Don’t go struct crazy.
  2. The Init, Read, Write, Verb etc… functions are your public member functions.
  3. Any other functions that were static or only called by the public member functions are now your private functions.

Bonus Faker Topic

You still here? Clearly you ran out of stuff to do during this pandemic or you are begging to change things up. It’s ok to check in on your sourdough starter or garden instead of this. But if you insist, let’s do it.

Getting out of the “Just C” mode means you have more options in modern software development. Namely, you have more options for doing unit tests since many assume you are using C++. With this in mind, if you are looking for a C supported one, Unity works and can support Mocks. However, now that you are faking… and making it… why not try CppUtest or GTest? I highly recommend reading “Test Driven Development in Embedded C” by James Grenning.

What can you do to easily set yourself up for more than just a quick host unit test using mocks? Well, if you make a virtual base class for the type module you are making (ex. audio driver class as virtual base class) and then later a concrete class (ex. audio driver class for a specific chip ) inheriting the previously mentioned virtual base class, now you have some options. With that virtual base class you can now:

  • Make as many audio drivers as you need in the event you are swapping in/out a bunch of audio chips.
  • Anyone using the driver class instance should use a reference of the virtual base class. It can take in any of the new audio driver classes you made based on this virtual base class and they ALL share the same API.
  • When you need a fake of a particular audio driver to support the unit test of another module, it is easily whipped up (by you) as long as the class type needed by the module under test needs an instance of type virtual base class.

Read more about fakes, mock, and doubles here.

Ok. That’s all I had on my mind. Not too many things and most of them didn’t make you have to learn a bunch of new things.

What I learned from Barbie

Initially when this Hello Barbie was announced I was super eager to do a teardown and even try to do a reverse engineering attempt. However, the Somerset Recon team did a great job of this and I cannot even attempt to match it (I extracted the binary if anyone wants to bring me a decompiler and join in otherwise I need more time than I’m willing to put in at the moment). Instead I’m looking at how they deal with manufacturing issues and basic interfacing here. I initially did this back in December so at this point this is more to make sure my thoughts get collected than anything else. Let’s dive in.

WARNING: There are weird, art school-ish photos of a dissection of Barbie even before we get to the electronics. 

Continue reading “What I learned from Barbie”

Getting Your Bitmaps Converted for Simple Display in Your Firmware

Perhaps you finally got a snazzy display for your latest project. I highly recommend the AdafruitGFX library as well as GIMP, and for making your own fonts, MikroElcktronika GLCD Font Creator (optional and not covered here).

If you are looking for a project to get you started, AdaFruit has a lovely wearable project.

Setup

  • GIMP
  • Access to your lovely bitmaps

Process

  1. Open the target bitmap into GIMP.
  2. Assume it is trimmed to the size you desire.
  3. Take note of the dimensions of the bitmap
  4. From the GIMP menu, select Colors->Rearrange colormap so it is appears a below (BLACK = 1; WHITE = 0) and click OK.

map2

  1. Select from the menu Image->Mode->Indexed. Choose 1-bit palette and click “ Dithering is optional.

dialog

  1. Save the file by selecting File->Export As. Choose c header file (.h) and name appropriately. Now use this however needed in your required firmware infrastructure. Personally, I make sure everything is “const” and indexable with sizes and offsets.Here is an example(rebelbot_bw.h).