Are you one of those embedded engineers who operates in a very low-level world
of direct register accesses? Or are you in the high-level world where the
hardware is highly abstracted and differentiating features get lost?
It’s possible to bridge both of these worlds by leveraging a layered
approach with software components and the RTOS. This helps you get the basic
software done, leaving you with more time and resources for unique application
level software. The end result? Your device will be differentiated from
similar ones on the market.
Let’s start with a view of embedded software sliced into layers of
functionality. Each layer maps to your application’s requirements.
Different aspects of an application can also access multiple layers, from high-level functionality to low-level hardware access.
Lowest layer: the microcontroller
The lowest layer is, of course, the microcontroller hardware itself. The
unique features of MCU peripherals open the door for differentiating and
For instance, take the Kinetis K22 and compare it to Kinetis KL03. Because
Kinetis K22 uses the Arm Cortex-M4 core with floating point unit and adds
crystal-less USB functionality, it’s ideal for the broadest range of
applications including sophisticated activity monitors and building control.
Kinetis KL03, on the other hand offers ultra low power and smaller physical
size making it ideal for the smallest portable, battery-powered applications
where stand-by time needs to be measured in months — not days.
Enter the hardware access layer
Each MCU peripheral is controlled through a set of memory-mapped registers
that are part of the hardware. Directly above the hardware registers, we
introduce a set of register access macros. These macros provide the programmer
a consistent interface to accessing registers that is mapped 1-to-1 to the
documentation in the hardware reference manual.
Building on the register macros, a hardware access layer (HAL) is added.
Multiple register operations are combined into single function calls, and API
names are abstracted. The HAL is a powerful layer that gives you the ability
to directly access differentiating hardware features, while not having to
think in terms of registers and bitfields.
And the peripheral driver layer
On top of the HAL sits the peripheral driver layer. Many developers are
familiar with this layer, as it appears in slightly different variants in most
applications. The driver layer fully abstracts the hardware into generic
terms. For instance, an I2C driver has an API defined in terms of I2C-bus
Sitting next to the driver layer is an optional RTOS, such as MQX RTOS.
Drivers need to be aware of an RTOS, if present, in order to have the best
performance. Atop the RTOS is middleware, such as USB or TCP/IP stacks, an
SMBus driver, a Graphic UI system and so on.
Finally, the embedded application builds on all the layers below it.
So, you can see, it’s possible to bridge both of these worlds by using
high-level, abstracted peripheral drivers for parts of your application that
do not require special features. This may be typical access to a standard
communications bus like SPI, I2C, UART or Ethernet, among many others. For
atypical use cases or special performance requirements, you can dive down to
the lower-level HAL layer to access unique hardware features. Consider use
cases that includes special ADC or DAC features such as automatic triggering
from other peripherals, or to enable certain low-power capabilities of the
hardware. The two approaches can even be combined for a single type of
peripheral, where a high-level driver is used for one ADC instance but the HAL
is used for another.
Using a layered approach to software provides the ultimate flexibility for
software designers and can significantly improve time to market. The
Kinetis software development kit (SDK)
is the software solution that enables this type of multi-layered access. The
picture below illustrates how the layers are organized to optimize the
software solution for the microcontroller.