What is it about creating firmware that can make a seasoned journeyman software developer forget everything he or she ever learned about software design?

There must be some mystical quality about ROM-able code that makes it okay to forget about the tried and true rules, because I see it again and again. For so many first-time firmware developers, and even some veterans; coupling and cohesion seem to have no meaning, magic numbers become the rule, and separation of concerns becomes separated from practice.

I’m not talking about the hardware developers who have crossed over; I can forgive them their lack of formal software education, as I hope they will forgive my short-comings when I stumble into their yard. I’m talking about veteran software guys (and/or gals) with years of application development experience in C++, C, Java, etc. In general, I’m talking about software professionals who should know better.

Since they apparently don’t, I now present a few of the simple rules that should always be applied:

  1. Firmware is software . It interracts more closely with hardware than your typical e-commerce application; and there are a few more restrictions applied to make it work from ROM; but in every way that is important it is software. When it comes to principles of design, don’t treat it as something else.
  2. Unless you are trying to accomplish something entirely trivial, you cannot fit it all in one brute-force loop. Don’t even think about it if you’re managing LED’s and communications.
  3. Understand the resources made available to you. Every micro-controller has a unique feature set, and as a firmware developer you should exploit all of them that will aid your task. Interrupts, ADCs, timers, and counters can all be invaluable in making your firmware better. Maybe you have an RTOS, maybe just raw hardware; either way make the most effective use of what you’ve got.
  4. Don’t assume the hardware folks always know what’s best. You can often make change requests for the next board revision that have no adverse affects for them, but will make your job much easier; for example rerouting an input to an unused interrupt-enabled pin.
  5. Separation of concerns is good. Software, firmware, or any other-ware; modularize the functionality. It improves the maintainability; and often reveals opportunities for enhanced functionality and/or performance.
  6. Tight coupling is bad. Modules should know as little about the internals of the others as is practicable. Even if you’re not seeking portability, this helps ward off inter-dependencies that can greatly increase the complexity of code, and make the inevitable evolution of the application much more difficult. Along this line, I also recommend that you also keep the API to the module as light-weight as possible. I prefer to limit the connections to a module to one or two calls. This makes a plug-n-play replacement much easier should the underlying hardware be altered during the course of the project.
  7. High cohesiveness is great. Don’t separate the concerns too far. If a given table exists for the sole benefit of one module; there is no need to break it out. Carrying the separation too far can result in unneeded overhead, especially if the loose coupling principle is maintained. Keep it functional. In general, tables, structures, and datatypes are not functional and do not rate consideration for separation. They should, however, be encapsulated within the module to the greatest possible extent.
  8. Magic numbers just plain suck. PLEASE Use symbolic values; enums, constants, and #defines; everywhere. Other than the occasional zero; I don’t ever like seeing numbers within the code. This can be difficult, after you have memorized key values, and sometimes, I even slip up; but I’m not too proud or lazy to fix it during refactoring or clean-up.

Follow these rules, most of which you’ve always known, and you’ll see the quality and performance of your firmware improve dramatically.

Good luck, and code safely!

About Max H:
Max is a father, a husband, and a man of many interests. He is also a consulting software architect with over 3 decades experience in the design and implementation of complex software. View his Linked-In profile at http://www.linkedin.com/pro/swarchitect