Libraries are only useful to you if they are flexible enough to be used to solve your design problems. MPLAB® Harmony libraries are flexible enough to support the variety of different environments that may be required.
Supported Configurations:
- Bare Metal (No Operating System)
- RTOS Based
- Peripheral Driver Configurations:
Super-Loop Polled
In a Super-Loop Polled system, all active state machines, including the peripheral drivers, must periodically poll for the events important to their job. An event is signaled when a flag is set by hardware using a peripheral interrupt event (interrupt events can be flagged without interrupts enabled), or by software.
Interrupt-Driven
In an interrupt-driven system, a peripheral driver state machine uses its associated peripheral Interrupt Service Routines (ISRs) to respond to events. These events are immediately processed by the ISR as they occur (no polling required).
The interrupt configuration file, system_interrupt.c, implements the raw ISR vector function that calls an interrupt-driven module’s state machine or Tasks function. As long as the Tasks function is carefully implemented so as to be interrupt-safe, it does the same thing whether it is polled or interrupt-driven. The only logical difference is whether or not the driver enables the interrupt.
A peripheral driver is made interrupt-driven by setting its Interrupt Mode to true. This is done in the system_config.h file (e.g., #define DRV_TMR_INTERRUPT_MODE true).
In this example, the Timer 1 ISR stub calls the timer driver’s Tasks function. In a polled system, the timer driver’s tasks would be called by the super-loop (implemented by the SYS_Tasks() function). Since SYS_Tasks and the ISR stub are both implemented as part of the system configuration, the library code stays the same in both cases. As long as it checks the flag first, it can be polled or interrupt-driven. The library is designed to be flexible enough to do either.
Less flexible, more optimized implementations are possible, but this example illustrates the concept.
RTOS Based
This same sort of flexibility extends to a Real-Time Operating System (RTOS) support. In an RTOS environment, instead of having a single main loop, the configuration will have multiple daemon threads, each with its own loop. Most of the time, you will still want drivers to be interrupt-driven. Interrupts usually support the best real-time response latency and hardware usually provides mechanisms for setting interrupt priorities. Additionally, an RTOS usually provides the ability to prioritize the threads that would otherwise be polled.
MPLAB Harmony libraries are RTOS safe. The Operating System Abstraction Layer (OSAL) will help you integrate the RTOS of your choice with these libraries.
The OSAL is a lightweight OS Compatibility layer. It supports a minimal feature set extracted from many different RTOS products to enable maximal RTOS compatibility. Its focus is on providing mechanisms for the safe operation of libraries in a multi-threaded environment.
The primary mechanisms used to provide thread-safe operation are:
- Mutexes
- Semaphores
- Critical Sections
- Memory allocation
Static or Dynamic Drivers
An MPLAB Harmony driver may control a single instance of a hardware peripheral (static driver) or may control multiple instances of a peripheral (dynamic driver).
In a static driver implementation, each peripheral instance is controlled by its own dedicated driver. For example, you cannot use the USART 2 driver to control USART 1. Note that each instance of a specific static driver requires a certain amount of program memory to implement the driver. In other words, two static drivers for a specific peripheral consume twice as much program memory as one static driver for that peripheral.
In a dynamic driver implementation, many peripheral instances can be controlled by the same driver. This capability obviously makes a dynamic driver bigger (consumes more program memory) than its associated static driver, but only one copy of it is needed (not one driver for each instance).
When only one peripheral instance is needed, a static implementation is appropriate. When multiple instances are needed, a dynamic implementation may be a better choice because it may use less program memory than multiple static implementations.
MPLAB Harmony peripheral driver libraries will provide just a static implementation, just a dynamic implementation, or both types depending on the specific peripheral. In any case, the API for static and dynamic drivers will be similar if not the same.
Dynamic driver example: DRV_USART_ReadByte()
Static driver example: DRV_USART0_ReadByte()
Single-Client or Multi-Client Drivers
You might have a need for multiple client modules to use the same instance of a peripheral at the same time. To manage this need, MPLAB Harmony has driver implementations that are intelligent enough to manage requests from multiple clients. This is particularly useful for bus type peripherals such as UARTs, I²C, and SPI. However, writing a driver that can support multiple clients requires additional resources (code and data) and has implications on the API. To make multi-client support possible at all, the API must be designed to be multi-client and must be common across all implementations.
On the other hand, your needs may be simpler than that. Single client drivers are also available to help reduce the amount of code and data storage needed for your system.