blob: 13ae89c49fcefaca10d36bdff8a0f8159cd04e9b [file] [log] [blame]
.. toctree::
:maxdepth: 1
flash <flash>
mmc <mmc>
Device drivers in the Mynewt context includes libraries that interface
with devices external to the CPU. These devices are connected to the CPU
via standard peripherals such as SPI, GPIO, I2C etc. Device drivers
leverage the base HAL services in Mynewt to provide friendly
abstractions to application developers.
.. code-block:: console
| app |
| (n)drivers |
| HAL | BSP |
- The Board Support Package (BSP) abstracts board specific
configurations e.g. CPU frequency, input voltage, LED pins, on-chip
flash map etc.
- The Hardware Abstraction Layer (HAL) abstracts architecture-specific
functionality. It initializes and enables components within a master
processor. It is designed to be portable across all the various MCUs
supported in Mynewt (e.g. Nordic's nRF51, Nordic's nRF52, NXP's
MK64F12 etc.). It includes code that initializes and manages access
to components of the board such as board buses (I2C, PCI, PCMCIA,
etc.), off-chip memory (controllers, level 2+ cache, Flash, etc.),
and off-chip I/O (Ethernet, RS-232, display, mouse, etc.)
- The driver sits atop the BSP and HAL. It abstracts the common modes
of operation for each peripheral device connected via the standard
interfaces to the processor. There may be multiple driver
implementations of differing complexities for a particular peripheral
device. For example, for an Analog to Digital Converter (ADC)
peripheral you might have a simple driver that does blocking ADC
reads and uses the HAL only. You might have a more complex driver
that can deal with both internal and external ADCs, and has chip
specific support for doing things like DMA’ing ADC reads into a
buffer and posting an event to a task every ’n’ samples. The drivers
are the ones that register with the kernel’s power management APIs,
and manage turning on and off peripherals and external chipsets, etc.
The Mynewt core repository comes with a base set of drivers to help
the user get started.
General design principles
- Device drivers should have a consistent structure and unified
interface whenever possible. For example, we have a top-level
package, “adc”, which contains the interface for all ADC drivers, and
then we have the individual implementation of the driver itself. The
following source files point to this:
- high-level ADC API: ``hw/drivers/adc/include/adc/adc.h``
- implementation of ADC for STM32F4:
``hw/drivers/adc/adc_stm32f4/src/adc_stm32f4.c`` (As of the
1.0.0-beta release, ADC for nRF51 and nRF52 are available at an
`repo <>`__.
They are expected to be pulled into the core repo on Apache Mynewt
after the license terms are clarified.). The only exported call in
this example is
``int stm32f4_adc_dev_init(struct os_dev *, void *)`` which is
passed as a function pointer to ``os_dev_create()`` in
``hal_bsp.c``, when the adc device is created.
- Device drivers should be easy to use. In Mynewt, creating a device
initializes it as well, making it readily available for the user to
open, use (e.g. read, configure etc.) and close. Creating a device is
simple using
``os_dev_create(struct os_dev *dev, char *name, uint8_t stage, uint8_t priority, os_dev_init_func_t od_init, void *arg)``.
The ``od_init`` function is defined within the appropriate driver
directory e.g. ``stm32f4_adc_dev_init`` in
``hw/drivers/adc/adc_stm32f4/src/adc_stm32f4.c`` for the ADC device
initialization function.
- The implementation should allow for builds optimized for minimal
memory usage. Additional functionality can be enabled by writing a
more complex driver (usually based on the simple implementation
included by default in the core repository) and optionally compiling
the relevant packages in. Typically, only a basic driver that
addresses a device’s core functionality (covering ~90% of use cases)
is included in the Mynewt core repository, thus keeping the footprint
- The implementation should allow a user to be able to instantiate
multiple devices of a certain kind. In the Mynewt environment the
user can, for example, maintain separate contexts for multiple ADCs
over different peripheral connections such as SPI, I2C etc. It is
also possible for a user to use a single peripheral interface (e.g.
SPI) to drive multiple devices (e.g. ADC), and in that case the
device driver has to handle the proper synchronization of the various
- Device drivers should be MCU independent. In Mynewt, device creation
and operation functions are independent of the underlying MCU.
- Device drivers should be able to offer high-level interfaces for
generic operations common to a particular device group. An example of
such a class or group of devices is a group for sensors with generic
operations such as channel discovery, configure, and read values. The
organization of the driver directory is work in progress - so we
encourage you to hop on the dev@ mailing list and offer your
- Device drivers should be searchable. The plan is to have the newt
tool offer a ``newt pkg search`` capability. This is work in
progress. You are welcome to join the conversation on the dev@
mailing list!
The Mynewt core repo includes an example of a driver using the HAL to
provide extra functionality - the UART driver. It uses HAL GPIO and UART
to provide multiple serial ports on the NRF52 (but allowed on other
platforms too.)
The gist of the driver design is that there is an API for the driver
(for use by applications), and then sub-packages to that driver that
implement that driver API using the HAL and BSP APIs.
Implemented drivers
Drivers live under ``hw/drivers``. The current list of supported drivers
| Driver | Description |
| ``adc`` | TODO: ADC driver. |
| ``flash`` | SPI/I2C flash drivers. |
| ``lwip`` | TODO: LWIP. |
| ``mmc`` | MMC/SD card driver. |
| ``sensors`` | TODO: sensors. |
| ``uart`` | TODO: UART driver. |