Written by Shawn Prestridge, Industry profile and Senior Field Application Engineer/Team Leader for US FAEs at IAR Systems
This article is part of IAR Systems article series focused on the importance of code quality.“Move fast and break things” is the approach that Mark Zuckerberg said he inculcates into the development culture at Facebook. While it sounds wonderful for getting new features up and running quickly (even if they are not perfect), it loses its luster if you try to apply that same approach to embedded development. The reason is that the domains are completely different: Facebook is based around web- and database-centric development with many function points that probably don’t suffer too greatly if the hot new feature doesn’t work correctly. Embedded systems are – by their nature – resource-constrained and generally intended to only do one function, or perhaps a few functions. Therefore, the philosophy of “move fast and break things” when applied to an embedded system can potentially render the entire system useless. Depending on what function that embedded system is providing, the results can be embarrassing at best and disastrous at worst. Does this mean you can’t use Rapid Application Development (RAD) methods in embedded systems? You can use RAD, but you need to be very careful about how you do it.
“Rushing makes us neither faster, nor more productive”
Moving fast implies that code quality takes a back seat to getting the code delivered quickly, and is what is sometimes called the WISCY (pronounced “whiskey”) syndrome: Why Isn’t Somebody Coding Yet? It also implies that testing of said code is either not done at all or practiced with a high degree of informality. Both of these can get your project into trouble and you therefore should adhere to best practices on Software Quality Assurance.
When developers are rushed to add functionality (or even to fix bugs), they tend to skip any sort of integration testing with the rest of the system and only do desk-checking of their code by running a handful of tests that only target the code they have just created. The reason is a culture of rushing to get the code out the door. As Lemi Ergin says, “Rushing makes us neither faster, nor more productive; it increases stress and distracts focus. We need creativity, effectiveness, and focus.” [1] The ability to be fast at deploying software starts with code quality.
Embedded development needs scalability
When developers craft code, they need to focus on development processes that promote scalability, minimize system complexity, and they should always look for ways to reduce “technical debt”. By keeping the system simple, it is easier for developers to add functionality or scale up the system when necessary. However, doing this takes time to design the software properly.
The temptation in a RAD situation is to go for a “quick and dirty” solution that solves the current problem facing the development team, and this is exactly why the term “technical debt” was introduced. By not planning out an extensible solution, developers essentially doom themselves to rewriting applications for follow-on projects and also make fixing bugs or adding features a nightmare because of the tight coupling of the software. Coupling refers to how dependent the software modules are on one another such that changing any line of code (or in embedded systems, even the timing of the code) can make the whole system break. But this level of planning can seem like an extravagance when you’re staring at a deadline and can lead to what Kelsie Anderson calls “cowboy coding”. This behavior cuts corners on software quality for the sake of expediency and over time increases the system complexity through tight coupling and higher technical debt. Therefore, it actually slows down development and makes projects more expensive. [2] As Ergin states, “Without having a quality codebase, you cannot be agile.” [1]
Everything starts with code quality – it’s just that simple
How can you improve your code quality when you barely have time to even slap code together to meet the schedule? Fortunately, there are coding standards such as MISRA, CWE, and CERT C that can help you do that. We have covered these standards in a previous paper, but the crux of these standards is that they promote safe and reliable coding practices by avoiding both risky coding behavior and holes in the C and C++ language standards.
By using code analysis tools that can automatically scan your code looking for deviations from these standards, you can quickly find and fix these problems while you are still desk-checking your code. In other words, you get instantaneous feedback on your code while you are still “in the zone”. This instantaneous feedback results in the developer fixing the bugs more than 50% more often than they would if the feedback came later from a build server. [3] Following these standards helps you to instantly up your code quality game which in turn helps you reduce the technical debt in your solution. Concordantly, you inject fewer bugs into the code and what bugs do exist can be both found and fixed faster. This structured approach to coding also makes it easier to add functionality which means you can do it much faster. But that is only half of the equation because even with a quality codebase, you still have to test properly.
A combination of code quality and testing is essential
In his seminal work Code Complete, Steve McConnell ruminates on the relationship between testing and code quality: