views:

691

answers:

10

What patterns have you come across as being used frequently with successful results?

Is there a resource of patterns used in embedded programming?

Most patterns books such as the GOF book focus on OOP techniques, surely there are similar patterns in the embedded systems domain.

+15  A: 

Small Memory Software

laalto
+3  A: 

I'm not sure if these qualify as "Design Patterns" but some of things I find myself doing across multiple embedded designs:

  • Custom fixed-block-size memory allocator (as opposed to using malloc() / heap

  • Server threads / tasks for deferred / low-priority processing (e.g., sending chars out UART)

  • when using C++, using RAII for mutex acquisition & release (local object on stack, constructor acquires mutex, destructor releases)

There are more, but unfortunately I'm pressed for time -- I'll try to post back with additional items when I can.

Dan
+1  A: 

This is the book used in my major's modeling of real-time systems class:

Doing Hard Time: Developing Real-Time Systems with UML, Objects, Frameworks, and Patterns

http://www.amazon.com/Doing-Hard-Time-Developing-Addison-Wesley/dp/0201498375

IDreamOf362
+7  A: 

State machines are probably the most common design pattern I find myself using.

There are several ways to implement them, depending on what exactly you're trying to accomplish in a given state machine, and depending on the resources of your embedded platform:

  1. switch statements on a state variable
  2. function look-up table indexed by state variable
  3. look-up tables of input conditions and output states

There are also opportunities and software for auto-generating state machine code from higher-level designs such as UML.

Craig McQueen
+1 for the very clear article link!
sheepsimulator
+1  A: 
  • An OS. The basics around context/task switching, stack management, interprocess communication and scheduling is mostly the same over different CPUs.
  • A simple scheduler for one to ten task with fixed timing. Sometimes a RTOS is overkill. Usually you have a timer generating interrupts to kick of tasks at the appropriate time and a background task doing house keeping.
  • Interrupts. All embedded systems have them and everybody have some idea of how to handle them. There is really only one rule for interrupts, keep it short.
Gerhard
+1  A: 

Patterns for Time-Triggered Embedded Systems - Michael J. Pont. Very nice book with some 70+ patterns.

Pont also has a bibliography page listing some other books, papers, etc. - some available online - related to patterns for embedded systems.

Brandon E Taylor
+2  A: 

An anti-pattern, very common in C is the Function-Call Data-Structure Free-For-All (FCDSFFA). It is characterized by long functions, with long parameter lists and lots of global data all woven together with fine strands of spaghetti.

Avoid this pattern with OO design techniques like this:

In the header file:

//Hide the internal details of the data structure that is being managed with
//this typedef
typedef struct CircularBuffer CircularBuffer;

//Only some functions are allowed to access the hidden data
void CircularBuffer_Init(CircularBuffer*, int capacity);
void CircularBuffer_Destroy(CircularBuffer*);
int CircularBuffer_IsEmpty(CircularBuffer*);
int CircularBuffer_IsFull(CircularBuffer*);
int CircularBuffer_Put(CircularBuffer*, int);
int CircularBuffer_Get(CircularBuffer*);
int CircularBuffer_Capacity(CircularBuffer*);
void CircularBuffer_Print(CircularBuffer*);

James Grenning
+1  A: 

From my experience i can quote

  1. Thread/Task paired with Message queue for independent execution.
  2. HeapManager/Memory Pool for preventing fragmentation.
  3. Notifiers/Callbacks for Asynchronous events to Application other layers.
  4. Custom queues like priority queues if your OS doesn't support
subbul
+2  A: 

The answers so far seem to have neglected architectural patterns, which are arguable more important. The layer pattern is prevalent in embedded systems where it is common to have a hardware abstraction layer, device layer, rtos layer, and several application layers. In many cases the higher layers are application specific and make no direct access to the hardware, whereas the lowest layers are tightly coupled to the hardware. This renders the application layer portable, and the intermediate layers both portable reusable in new applications, and the lowest layers accelerate development of new applications on existing platforms.

Other patterns in the link above are also relevant to embedded systems depending on the problem domain. For example the Blackboard System is often used in AI systems and robotics. Model-View-Controller is relevant to systems having rich or flexible UI devices..

Clifford