Reusable Embedded Software

Thread Starter

Embededd

Joined Jun 4, 2025
153
I was thinking about how embedded software can be made more reusable across different hardware platforms.

Suppose we design the software in layers. At the top, we have the Application Layer, which contains the actual product logic. Below that, we have an Interface Layer that provides common APIs such as UART send, GPIO write, sensor read, and so on. At the bottom, we have the Hardware Layer, which contains all the microcontroller-specific code.

So the application talks only to the Interface Layer and does not know anything about registers or a specific MCU.

With this approach, I feel that if we change the hardware for example, from an STM32 to an NXP controller we should only need to rewrite the Hardware Layer and maybe adjust a small part of the Interface Layer, while the Application Layer remains exactly the same.

Similarly, if we add new features or change the product logic, we would modify only the Application Layer, without touching the lower layers.

This makes me think that it should be possible to build a mostly hardware-independent software architecture where only a small portion of the code needs to change when moving to a new platform.

Does this understanding make sense? Is this approach practical in real projects, and is this how portable embedded software is typically designed in industry?

I’d really appreciate your thoughts on this.
 

WBahn

Joined Mar 31, 2012
32,821
This is an approach that is used all over the place, including embedded systems. But there are penalties that come along with it in terms of code size, efficiency, and latency. If those penalties can be tolerated, then the approach makes sense. If they can't, which is not uncommon when dealing with resource-starved embedded platforms, the no matter how much sense it makes on paper, it is unworkable in the real world. There are, of course, hybrids of all kinds in which you leverage a layered approach as much as can be tolerated, but no more.
 

Futurist

Joined Apr 8, 2025
748
I was thinking about how embedded software can be made more reusable across different hardware platforms.

Suppose we design the software in layers. At the top, we have the Application Layer, which contains the actual product logic. Below that, we have an Interface Layer that provides common APIs such as UART send, GPIO write, sensor read, and so on. At the bottom, we have the Hardware Layer, which contains all the microcontroller-specific code.

So the application talks only to the Interface Layer and does not know anything about registers or a specific MCU.

With this approach, I feel that if we change the hardware for example, from an STM32 to an NXP controller we should only need to rewrite the Hardware Layer and maybe adjust a small part of the Interface Layer, while the Application Layer remains exactly the same.

Similarly, if we add new features or change the product logic, we would modify only the Application Layer, without touching the lower layers.

This makes me think that it should be possible to build a mostly hardware-independent software architecture where only a small portion of the code needs to change when moving to a new platform.

Does this understanding make sense? Is this approach practical in real projects, and is this how portable embedded software is typically designed in industry?

I’d really appreciate your thoughts on this.
I completely agree with @WBahn

Reusability is almost always desirable but carries a cost and there's a cost/benefit trade off. Operating systems offer some of what you mentioned too. A big change I had to appreciate when first exploring STM32, is there's very little binary reuse, all reuse is source level reuse, that's very different to modern development with say .Net or even native code on Windows (DLLs).

Given that MCUs require source level reuse, I can envisage a world where the solution is expressed in an MCU agnostic manner and tools (AI?) then generate platform specific source, but I suspect the value preposition isn't great.

Just striving for reuseable source on a single platform (like STM32) is a big challenge.
 
I was thinking about how embedded software can be made more reusable across different hardware platforms.

Suppose we design the software in layers. At the top, we have the Application Layer, which contains the actual product logic. Below that, we have an Interface Layer that provides common APIs such as UART send, GPIO write, sensor read, and so on. At the bottom, we have the Hardware Layer, which contains all the microcontroller-specific code.

So the application talks only to the Interface Layer and does not know anything about registers or a specific MCU.

With this approach, I feel that if we change the hardware for example, from an STM32 to an NXP controller we should only need to rewrite the Hardware Layer and maybe adjust a small part of the Interface Layer, while the Application Layer remains exactly the same.

Similarly, if we add new features or change the product logic, we would modify only the Application Layer, without touching the lower layers.

This makes me think that it should be possible to build a mostly hardware-independent software architecture where only a small portion of the code needs to change when moving to a new platform.

Does this understanding make sense? Is this approach practical in real projects, and is this how portable embedded software is typically designed in industry?

I’d really appreciate your thoughts on this.
I don't think it is possible to make fully hardware-independent architecture because hardware is the heart of project. If one STM MCU is to be replaced with another STM MCU, changes may be minor. But if one STM is supposed to be replaced with an NXP that is a complete different story.
 

Irving

Joined Jan 30, 2016
5,109
If you use a real-time operating system like FreeRTOS then there is significant reuse across different platforms for things like timers, UART I/O, queues, lists, task management and other constructs. And there are portable implementations for common devices like NVRAM, EEPROM, ADC, DAC, etc. if you can afford the inevitable overheads compared to bare-metal programming.

But effective and efficient reuse at the application level is much harder to achieve as has been already discussed .
 
Top