The Art of Designing Embedded Systems
Authors: Jack Ganssle
Publisher: Newnes, 2008 (Second Edition)
When I picked up this book, I half expected to read about a serious subject written in a serious textbook style. Within the first few paragraphs it was clear that this book surprises and interests, not least by its almost chatty informal style. It's a book written by an engineer for engineers. It's a book written by a practitioner with many years of solid experience. The author is not presenting here a theoretical framework or a wish list. He is rather condensing many years of experience from which readers can directly benefit. He gives loads of tips and tricks that engineers can start applying in their daily work.
The relevance of this book is of course obvious. Embedded systems are everywhere: in home electronics, in personal devices, in industrial automation and increasingly in tiny devices that are going to come in their billions as part of the Internet-of-Things. Now more than ever firmware developers need to learn from the experiences of others and adopt best practices. To learn from self-experience through mistakes and mishaps is something neither engineers nor their employers can afford.
The focus of the book is on the different aspects of building firmware. It's about software and its interaction with hardware. It's about building something that not just works but also does its job within defined time bounds. It's also about writing code that can be maintained by other teams in the future. While all these are expected in a book of this nature, the author backs all his discussions with interesting anecdotes and examples. Sometimes he shows us code but none of this is scary enough to put off newbies. In fact, even managers and hardware engineers can comfortably read this book.
Beyond the technical points, the author gives due importance to aspects of project management and process. He talks about managing big complex projects. He talks about how best to partition the system or schedule projects. He makes a bold claim that its best to partition a large project into smaller components that will each run on its own CPU. This might surprise hardware engineers whose main aim is to keep cost down. The real fact is that transistors are cheap but development time is expensive. In the same vein, running a system close to 95% of its performance limit is not worth the pain. It's better to upgrade the hardware. Another piece of advice is to put your best developers not on large teams because their efficiency drops to match those of their team members. When it comes to effort estimation, the opinion of a few experts will avoid biases and also "follow-the-leader" syndrome.
To write quality code, the author mentions many useful techniques. There must be a firmware standard. The project can even adopt the MISRA standard. Avoid use of globals. Instead use techniques of encapsulation. Write good comments out of habit. Use Lint to flag possible errors even before testing. In fact, code inspection is probably the most important weapon in catching bugs early, particularly when we know that it's tough for any testing plan to achieve 100% coverage. The author quotes various industry measurements that show the enormous benefit of code inspections. Most developers know about the use of assertions. The author goes beyond this and talks about Design by Contract, which is about defining clearly the contract between a function and its caller. Such contracts perform checks at execution time. There may be some performance drop but the benefits are obvious.
One of the biggest challenges in embedded systems is the asynchronous nature of interactions. Interrupts come in to preempt current execution. There could be race conditions. Interrupts could go missing. A flood of interrupts can cripple the system. The author gives many examples and provides solutions. Write reentrant code. Don't disable interrupts for too long. Keep interrupt service routines (ISR) short. Use techniques of debouncing. Use a logic analyzer to measure interrupt latency and ISR execution times. Terminate pins to eliminate reflections, particularly when these pins are edge triggered. Use numerical approximations to speed up complex mathematical calculations.
These days engineers work with tools, APIs and libraries. As a result, they no longer solve problems from first principles. Abstraction has distanced us so much that we no longer have a "feel" for problems. It's important for engineers to retain this intuition. We should be able to look at a PCB and tell that the ground plane doesn't look right. We should be able to look at ISR code and estimate that this should take about 500 microseconds. We should combine this intuition with basic arithmetic to make a "guesstimate" of the problem. This must be every engineer's essential skill.
There's no doubt that this book is an essential read for every firmware engineer.
- Rethinking Your Software Implementation
- The Joy and Pain of Debugging Hardware
- Leveraging Modularity in Embedded Design to Accelerate IoT Proliferation
About the Author
Arvind Padmanabhan graduated from the National University of Singapore with a master’s degree in electrical engineering. With more than fifteen years of experience, he has worked extensively on various wireless technologies including DECT, WCDMA, HSPA, WiMAX and LTE. He is passionate about tech blogging, training and supporting early stage Indian start-ups. He is a founder member of two non-profit community platforms: IEDF and Devopedia. In 2013, he published a book on the history of digital technology: http://theinfinitebit.wordpress.com.