the scapegoat dev

Embedded development is not like web development

When I wrote Embedded programming is like web development, I thought it would be a pretty uncontroversial article—I expected the response to be along the lines of "geez manuel, that's pretty obvious."

It turns out that that was far from the case—most feedback I got was that both were significantly different. This puzzles me deeply: I switch back and forth between both domains weekly, yet I feel like I am using the same techniques and writing almost identical code.

To gain a better perspective, I wrote up all the reasons I could think of why embedded development is not like web development. I hope that this gives some context to the previous article and helps me provide more clarity moving forward.

Skills of a bare-metal embedded developer

I will use bare-metal microcontroller-oriented work as a stand-in for "embedded development." While a fair amount of embedded development these days involves Linux system programming, cloud computing, graphical UIs, and data processing, I don't want to blur the boundaries too much and muddy my examples.

If you do bare-metal programming, you need to know a certain set of tools and practical skills:

The code and runtime requirements are very different:

Skills of a web full-stack developer

Similarly, web development has its own tools, technologies, workflows, and constraints.

So, why did I say that embedded development is just like web development?

I think that the day-to-day of a programmer differs significantly depending on which domain they work with. The set of skills, the onboarding, and the learning experience are tremendously different. You can't just put a junior embedded developer before a web application and have them contribute meaningfully.

However, once you become a seasoned developer (at a senior+/staff level), your work becomes much more abstract: you think in systems more than in the minutiae of actual code.

In fact, with the decreasing amount of coding you do, you can quickly become rusty. It's been years since I have written a kernel driver or a bare-metal firmware, and I have to fight with webpack every time I get back into front-end development. My CSS knowledge—poor in the best of times—evaporates every few weeks. However, I know that I can pick up whatever current knowledge is required to build them, and I know where they fit in the system and what tradeoffs can be made. I can also provide guidance and advice to more junior developers on the team and help them grow.

Overall, higher-level patterns transpose very effectively from one domain to the other. Someone knowledgeable about "real-time" WebRTC, WebSockets, HTTP, and gRPC will have no trouble understanding the nuances of USB or how a network protocol might fit the problem at hand. Similarly, a frontend developer that is knowledgeable in building complex asynchronous applications using state reducers, promises, and state machines will have no problem designing and code reviewing some more intricate firmware—even writing one after having been shown the nitty-gritty of flashing and debugging by an experience embedded develop.

I hope to give concrete code examples to make this admittedly abstract statement much more tangible in my next few posts.

(thanks to Ed for taking the time to give me feedback!)