Blog Posts

Technology, etc.




Untangle Software From Hardware

header image

Embedded developers must fight the siren call of hardware. Our whole job is to write code that interacts with the hardware, that talks back and forth and changes the world. But we’re seduced by the notion that we can get away with leaking hardware into our design.

Developing software for embedded devices is taught as an exercise in “getting it to work”. You’re done once your code can talk to the peripheral and it doesn’t crash. This works for the classroom. For the professional software engineer it’s a dangerous pattern. You’re building a hardware dependency into your code. This will increase the cost of everything that you do for the life of the product, and probably have a negative effect on future products as well.

What do we get when we naively build hardware into our embedded code?

  1. A waterfall development process: hardware must be ready before software can be developed
  2. Reuse for product variations or entirely new products becomes difficult or impossible
  3. New code is and untested code is blindly released, or goes through a slug fest of manual testing
  4. A collection of bug reports from the field labeled “Can not reproduce”

We can combat this by making a few changes to how we develop software. The fundamental change is changing our development process from experimentation to thinking. This change will address the points raised above by making it easier to develop and maintain the application. As a bonus for the individual developer this also allows offsite development.

We’ll cover how to untangle hardware from your code in three different phases of your development process:

  1. Design: architect the application to isolate hardware
  2. Develop: simulate hardware with mocks
  3. Maintain: instrument the application to log data

We’ll never be able to decouple 100% of development from the hardware, but we can certainly get most of the way there.

Read More

Using pre-commit for good

header image

Git has the ability to add hooks to common actions like committing. This allows you to run custom checks and stop the commit if something looks bad. I customize the pre-commit hook based on the particular project, but at a minimum I like to always have a staged file check and link check as baseline sanity checks.

I added the features discussed in the post to the pre-commit hook for this site.

Read More

Building Embedded Linux Images for Internal Tools

building linux header image

Often when I’m developing software for distributed systems, I run into a situation where I have a small Python script that “just” needs to run on a Linux system. A laptop or RaspberryPi would be fine, but how do you go about setting everything up? You could just flash Raspbian onto an SD card, copy over the application script, and call it a day. But what if you need to make 10 of these? And then, in 3 months, do an update and build 5 more? Is it easy enough to train an intern to reproduce the setup and make more? Beyond a few devices, it makes sense to formalize the process of making the root file system. In this post I’ll detail some methods to do that.

Read More

JSON Configuration - Transforming through Merging and Patching

json plus json catcher image

JSON is a nearly universal standard for configuration files. From web servers to IoT, JSON is used to store settings and values to configure the behavior of systems. Good practice for complex systems dictates that we separate the concerns of our configuration into multiple files. This post talks about how to merge those files back together into a single representation that an application can use.

The techniques in this post can also be used to create a hierarchy of configuration files. This allows you to replicate (to a point) the inheritance mechanism found in object oriented programming languages. While an inheritance mechanism is overkill for a simple web server, many other applications (such as configuring physical products) could benefit from a hierarchical configuration design.

We’ll cover two main techniques: merging and patching. Merging is simple and very common, but suffers from some flaws that severely limit it’s applicability. Patching allows the programmer to completely and precisely specify the changes needed, but suffers from poor readability.

Read More

My Programming Statistics

header image

I’ve been contracting for most of the last year. As part of this, I’ve been keeping careful record of my hours and how much code I write. I thought it would be interesting to dig deep through the data and answer an age old question: how fast am I?

Read More

Dockerfile Composition

Dockerfiles are great when you have one image that you need to generate. But what happens if you need to generate several images that are substantially similar, but differ in a few aspects? This post will talk about how to compose your Dockerfiles so that you can reduce complexity and duplication, but still have flexibility to generate multiple final images from a single project.

Read More

Make a Robust Codebase

robust code base header image

Maintaining and managing a project that spans dozens of contributors and years of usage isn’t simple. However, there are a few tips that can help make it easier. In this post, I examine my top four tips to make it easier to work with big projects. By following these tips, you’ll have a codebase that is more robust to external shocks, easier to change, and just more fun to work with.

Read More

Startup Postmortem - The Red9 Story

Red9 Logo

Most startups fail. Red9 was one of those, and this is that story.

I want to share a story about three years of my life. Three years trying to create something where there was nothing before, from the ground up, and with a small team of enthusiastic and passionate people. We set out to quantify the athlete and help them perform better. By the end, we realized that our approach was ineffective, and we could not create the company that we wanted.

SCAD mockup on surfboard

Read More