Table of Contents
At Team Spatzenhirn, the Carolo-Cup (1:10 scale autonomous driving competition) team at Ulm University, we use Zephyr for the software on our interface board. Recently, we had the need to connect an PMW3389 sensor to the board, for which we didn’t find any already existing Zephyr drivers. This is not the first Zephyr driver we built, but the previous drivers have all been built in-tree, inside our fork of Zephyr. While it would be cool to upstream those eventually, the main goal would be to make the drivers easily usable by other Zephyr users, even if the driver is not included in Zephyr by default.
This post intends to give an overview of the layout of an out-of-tree sensor driver for zephyr, following our PMW3389 driver as an example:
Zephyr makes use of the west tool to load external components, we even use west to download zephyr itself in our
To make the driver usable as a west module, a file
required in the repository.
It defines how the module is built, where to find additional Kconfig files and devicetree sources:
Now, an application wishing to use the driver can add the following to its own west manifest. Our manifest looks something like this (the parts downloading zephyr itself omitted):
- name: teamspatzenhirn
- name: pmw3389_zephyr_driver
As with an in-tree driver, the DTS binding is defined at
dts/bindings/sensor/vendor,device.yaml, in our case that
Here is the DTS binding for our sensor, which is just the same as every other sensor DTS binding:
Resolution in counts per inch, multiples of 50, from 50 to 16000
Note that the vendor must be in the list of known vendor prefixes, so if the vendor is not known yet in upstream
zephyr, you can just provide
dts/bindings/vendor-prefixes.txt, which will be merged with the upstream file at build
pixart PixArt Imaging Inc.
(Note that the separator between the vendor prefix and the description is a tab…)
Kconfig file just includes the sensor-specific Kconfig file next to the sources:
The driver sources at
drivers/sensor/pmw3389/ are just the same as any other in-tree driver.
Take a look at
our driver sources
or any other sensor driver as an example.
As far as I can tell, the in-tree drivers don’t handle the headers in a special way, since the driver directory
is in the include path anyway.
For many drivers, the header is not needed by the application anyway, since the application just uses the generic sensor
We did however need a header to make custom sensor channels and an additional raw-data readout function available,
see the header
The only addition we had to make to the usual
add_subdirectory_ifdef(CONFIG_PMW3389 drivers/sensor/pmw3389) was to
make the header mentioned above available.
See the full CMake file at
These blog posts and samples have been helpful in figuring this out: