When we develop embedded software, we see time and again the same class of problems. Legacy code that is costly to maintain, changing one piece of code results in unexpected behavioral changes in other places, code that breaks in unexpected ways.
All of this results in source code that becomes exponentially more difficult to work with.
What this all comes down to is lack of clear architectural guidelines for writing the software. Things like "How do we define an object?" or "What basic methods should every object have?". These things aren’t enforced by compilers and probably will never be. This is something that we must enforce with clear guidelines and code review.
This is why we have a list of guidelines that we apply to every project and we make sure that all developers know about these guidelines and point out to each other during code review when these guidelines are not being followed. This results in code that is clean, easy to maintain, easy to test and easy to understand too.
Patterns make it possible for us to infer things about our code - this is why it is also very important that patterns are followed.
In this text we will go over powerful patterns for embedded C programming that will help you make your code more maintainable and minimize technical complexity associated with mental effort that goes into understanding and otherwise debugging code that was previously developed without applying any patterns.
- Object Pattern. This is a way to group data into objects that can be instantiated and destroyed. We also introduce concept of classes and member functions.
- Opaque Pattern. This pattern gives us three ways of making the implementation of the object private and exposing only a handle to the object. This can also be referred to as opaque objects pattern.
- Callback Pattern. Deals with object oriented callbacks that are bound to instances of objects. Allows callbacks to operate on specific instances of objects.
- Containment Pattern. Containment pattern a way of implementing inheritance by embedding the base object into the derived object and aggregating the objects using the base class.
- Virtual API Pattern. Virtual API pattern is a way of implementing virtual functions in C and making the handles to opaque objects also "smart". The virtual api pattern gives us polymorphism - where we can use the same interface for several implementations without knowing about these implementations.
Data Integrity Patterns
- Spinlock / Interrupt Masking Pattern. Masking interrupts is the simplest pattern for data integrity has to do with protecting shared data that is accessed by interrupts. A generic implementation of this is often done in the form of spinlock. Here we look at how we need to protect data from corruption by making sure interrupt never runs when we are modifying it.
- Semaphore Pattern. Semaphore the most basic pattern that we can use to synchronize between asynchronous signals and our main flow of execution.
- Mutual Exclusion Pattern. This pattern helps us to protect sections where multiple code paths may access the same data concurrently. This builds on our structural patterns. This pattern is only applicable for mutual exclusion between threads - it is not applicable to mutual exclusion between interrupts and thread code.
- Conditional Variable Pattern. Conditionals is a way to signal one or more threads that something more complex has occurred.
- Global Component Pattern. A structural way of implementing global functions.
- Configuration Data Pattern. A pattern for organizing configuration options.
- Event Processor Pattern.
- Return Value Pattern. Standardize your return values so that it is easy to know what to expect in your code.
- Background Service Pattern. Services are automatically started background tasks that operate independently of your application. Services provide asynchronous handling of operations simplifying the design of the main application.
- Testing Pattern. Thorough unit testing of each logical path through your driver code is the only way to make sure that your code really works according to your expectations.
Reasons to do this training
This training is specially relevant for you if:
- You want to understand how to structure C code - so that you can build larger and more complex software easily.
- You want to understand patterns that are useful in C - so you can improve your C programming skills.
How to enroll
This training is available to paid members only.
Membership offers you additional benefits such as:
Get started today by registering a monthly membership account here on the site. Click to sign up