Structure
Create a new directory dm163_example
to host your new application and driver code. Once we are done, the file structure will look like this:
dm163_example
├── boards
│ └── disco_l475_iot1.overlay
├── CMakeLists.txt
├── dm163_module
│ └── zephyr
│ ├── CMakeLists.txt
│ ├── dm163.c
│ ├── Kconfig
│ └── module.yml
├── dts
│ └── bindings
│ └── siti,dm163.yaml
├── prj.conf
└── src
└── main.c
(you do not need to create this hierarchy right now, you'll be guided when it is time to do that)
Here are some explanations of the structure:
- You are already familiar with
CMakeLists.txt
,prj.conf
andsrc/main.c
. - The
dm163_module
directory contains the DM163 device driver. - The
dts/bindings
directory contains thesiti,dm163.yaml
file which describes what is permitted and what is required in a node marked compatible with our device driver, whose name is, as you guessed,siti,dm163
(from its maker SiTI and its model DM163). boards/disco_l475_iot1.overlay
contains the device-tree part describing how the DM163 device is connected to our board.
From now on, all file names we indicate in the instructions will be relative to the top of the dm163_example
folder.
What is in Zephyr's struct device
?
A struct device
in Zephyr is made of several fields, including:
- A
config
pointer, which points to read-only data describing the configuration gathered from the device tree and theKconfig
options. In our case, the configuration will be a structure containing information about the pins to use in order to drive the DM163 chip. - A
data
pointer, which points to data describing the current state of the device driver. In our case, it will contain the brightness and color information for the leds. - A
api
pointer, which points to a read-only data structure compatible with the driver we want to be compatible with. Here we want to be compatible with theled
driver API, so ourapi
field will be aconst struct led_driver_api * const
.
Most functions will receive a struct device *
parameter which you can use to extract the config
and data
field containing the information you need. For example, to turn on one of the leds controlled by the DM163, you will modify the state of the led in the data
structure and send the new led configuration using pins whose configuration is located in the config
structure.
There exist other fields to store power management operations if the device can be put to sleep, as well as the initialization function to call to initialize the device.