本文说明如何将新增的驱动纳入到Zephyr应用的目录下进行管理。
本篇是<<Zephyr应用的代码结构>>系列的终篇和下面两篇文章一起可以构建出一个有app独立管理的zephyr项目
Zephyr个人项目的代码结构–West提货单: zephyr和zephyr外部项目纳入到应用代码目录管理
Zephyr应用的代码结构–自定义开发板: 将自定义board纳入到应用代码目录管理
除了上面两个场景外,我们的硬件可能也有新的驱动需求,而该驱动不被Zephyr支持,如果不想将驱动放入Zephyr中,就需要将驱动纳入到应用代码目录。
Zephyr驱动的添加可以分为3个级别:
- 有驱动API抽象,有设备树绑定: 只用添加驱动代码
- 有驱动API抽象,无设备树绑定:添加设备树绑定文件和驱动代码
- 无驱动API抽象,无设备树绑定: 添加抽象API头文件,添加设备树绑定文件,添加驱动代码
驱动代码目录
驱动代码目录添加
在app/目录下添加drivers目录,如下1
2
3
4
5
6
7
8
9
10
11
12
13app
├── drivers
│ └── zephyr
│ ├── CMakeLists.txt
│ ├── Kconfig
│ └── sensor
│ ├── CMakeLists.txt
│ ├── Kconfig
│ └── rotary_encoder
├── CMakeLists.txt
├── Kconfig
├── rotary_encoder.c
└── rotary_encoder.h
在drivers/zephyr下的将要添加的驱动类型分类,例如我需要添加传感器类型的驱动,就增加一个sensor文件夹
zephyr/CMakeLists.txt中指定该文件夹, 如果有其它驱动类型的文件夹也加入到该文件中1
add_subdirectory(sensor)
zephyr/Kconfig包含各个驱动类型文件夹的Kconfig1
rsource "sensor/Kconfig"
zephyr/sensor/CMakeLists.txt中指定要使用的驱动文件夹,例如这里要指定选择编码器1
add_subdirectory_ifdef(CONFIG_ROTARY_ENCODER rotary_encoder)
zephyr/sensor/Kconfig包含该类型下各个驱动的Kconfig1
rsource "rotary_encoder/Kconfig"
zephyr/sensor/rotary_encoder/CMakeLists.txt指定驱动的源代码1
2
3zephyr_include_directories(.)
zephyr_library()
zephyr_library_sources(rotary_encoder.c)
zephyr/sensor/rotary_encoder/Kconfig则是该驱动代码rotary_encoder.c要使用的配置选项1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19menuconfig ROTARY_ENCODER
bool "Rotary Encoder Sensor"
depends on GPIO
help
Enable driver for Rotary encoder sensors.
if ROTARY_ENCODER
config ROTARY_ENCODER_THREAD_PRIORITY
int "Thread priority"
default 10
help
Priority of thread used by the driver to handle interrupts.
config ROTARY_ENCODER_THREAD_STACK_SIZE
int "Thread stack size"
default 1024
help
Stack size of thread used by the driver to handle interrupts.
驱动代码由rotary_encoder.c和rotary_encoder.h组成,不是本文说明重点,如何实现驱动可以参考Zephyr驱动模型实现方式
指定使用驱动目录
Zephyr建议将外部目录的驱动作为module添加,在app/CMakeLists.txt中添加下面内容,构建时就会编译app/drivers1
2
3list(APPEND ZEPHYR_EXTRA_MODULES
${CMAKE_CURRENT_SOURCE_DIR}/drivers
)
设备树绑定文件目录
为了硬件上的灵活性,Zephyr引入了设备树,通过设备树绑定的方式将设备树转换为C宏来使用。Zephyr的设备树绑定文件可能不包含我们要用的硬件设备,这就需要我们自己添加。同样设备树绑定文件也可以纳入app的目录进行管理,在app目录下添加dts目录,里面放置设备树绑定文件1
2
3
4
5app
├── dts
│ └── bindings
│ └── sensor
│ └── rotary-encoder.yaml
rotary-encoder.yaml的编写和使用方法不是本文重点,详细可以参考Zephyr添加旋转编码器驱动
在app/CMakeLists.txt中添加下面内容,构建时编译设备树会查找到app/dts目录1
list(APPEND DTS_ROOT ${CMAKE_SOURCE_DIR})
设备驱动API头文件目录
对于个人项目开发来说,设备驱动API一般是项目内使用,API抽象的普遍覆盖性并不一定要非常全,此外使用的人员也不需要大范围讨论,根据需求进行自定义就可以, 所形成的头文件放到对应的驱动目录即可,例如zephyr/sensor/rotary_encoder/rotary_encoder.h, 为了方便应用直接使用,可以在app/CMakeLists中添加1
include_directories(drivers/zephyr/sensor/rotary_encoder/)
之后应用代码中就可以直接”#include “rotary_encoder.h”
结束语
到此为止我们通过三篇文章可以将Zephyr代码, Zephyr外部项目,自定义board, 驱动都纳入到一个app的仓库进行管理,通过一个独立的app仓库可以驱动编译所必须的代码,既方便管理,又十分精简。
如果你使用的SOC都还未被Zephyr支持,也可以将soc的移植纳入到应用目录下进行管理,这部分目前我并没有使用过无法做实例解释可以参考https://docs.zephyrproject.org/latest/application/index.html#soc-definitions进行操作。
参考
https://github.com/zephyrproject-rtos/zephyr/tree/main/samples/application_development/out_of_tree_driver
https://docs.zephyrproject.org/latest/samples/application_development/out_of_tree_driver/README.html