Zephyr out of tree board
Posted 咕咚.萌西
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Zephyr out of tree board相关的知识,希望对你有一定的参考价值。
文章目录
前言
- 在Zephyr中使用west工具进行编译时,会从zephyr/boards目录下寻找用户输入的board,查找成功后再继续进行后续工作,但是在一些情况下,现存的board中存在的配置并不能满足需求,或是使能了一些不需要的功能,这种情况下我们通常需要根据硬件新建board。
- 通常可以在zephyr/boards目录下新建board并添加设备树和kconfig文件,west运行后会根据board名称查找对应的文件夹,将其中的文件添加到编译系统中。
- 这种方式虽然可以满足我们的需求,但是增加的文件位于内核源码树下,会引起内核源码变动,但是该变动通常不会进行提交,在多人协同开发时,所使用的内核源码与官方的保持一致,一般不会修改内核源码,如果想要所有人都能编译通过,就需要对内核源码添加补丁,后期如果更换内核版本,还需要添加新的补丁上去,因此该方法存在一定局限性。
- 理想的方式是在app目录下可以添加board,然后通过提供的api将board到构建系统中,使其可以在不更改内核源码的情况下添加board。
自定义 board 目录
- Zephyr 支持源码树外添加 board,可以参考 zephyr/doc/develop/application/index.rst 文件的 Custom Board, Devicetree and SOC Definitions 章节。
目录结构
boards/
soc/
CMakeLists.txt
prj.conf
README.rst
src/
- soc 目录下保存了soc相关的代码,此处可以省略,我们所使用的soc是Zephyr中已经存在的SOC。
- boards 目录下保存了自定义的开发板配置,目录结构如下:
.
├── boards
│ └── x86
│ └── my_custom_board
│ ├── doc
│ │ └── img
│ └── support
└── src
- my_custom_board 为自定义开发板的名称,doc和support可以省略,但是提交到Zephyr时必须要有。
- boards 目录下首先需要有一个架构文件夹,可用的架构与内核源码树下 boards 文件夹下一致,需根据芯片所属架构进行添加,如果没有将自定义的板子放在对应的架构文件夹下会提示查找失败。
- 下面是 my_custom_board 中的文件:
my_custom_board_defconfig
my_custom_board.dts
my_custom_board.yaml
board.cmake
board.h
CMakeLists.txt
doc/
Kconfig.board
Kconfig.defconfig
pinmux.c
support/
添加目录至构建系统
- 文件添加好之后需要将board的路径添加到编译系统中,在CMake中通过 BOARD_ROOT 变量来识别外部的board目录,该变量可以通过命令行传递参数,也可以通过在app中定义 BOARD_ROOT 进行设置,但是两种方式有所区别,通过命令行定义的变量可以是绝对路径和相对路径,而在app中的CMakeLists.txt中 定义的 BOARD_ROOT 变量必须是绝对路径。
- 下面是 boards.cmake 从 BOARD_ROOT 查找板级目录的代码:
foreach(root $BOARD_ROOT)
# Check that the board root looks reasonable.
if(NOT IS_DIRECTORY "$root/boards")
message(WARNING "BOARD_ROOT element without a 'boards' subdirectory:
$root
Hints:
- if your board directory is '/foo/bar/boards/<ARCH>/my_board' then add '/foo/bar' to BOARD_ROOT, not the entire board directory
- if in doubt, use absolute paths")
endif()
# NB: find_path will return immediately if the output variable is
# already set
if (BOARD_ALIAS)
find_path(BOARD_HIDDEN_DIR
NAMES $BOARD_ALIAS_defconfig
PATHS $root/boards/*/*
NO_DEFAULT_PATH
)
if(BOARD_HIDDEN_DIR)
message("Board alias $BOARD_ALIAS is hiding the real board of same name")
endif()
endif()
if(BOARD_DIR AND NOT EXISTS $BOARD_DIR/$BOARD_defconfig)
message(WARNING "BOARD_DIR: $BOARD_DIR has been moved or deleted. "
"Trying to find new location."
)
set(BOARD_DIR BOARD_DIR-NOTFOUND CACHE PATH "Path to a file." FORCE)
endif()
find_path(BOARD_DIR
NAMES $BOARD_defconfig
PATHS $root/boards/*/*
NO_DEFAULT_PATH
)
if(BOARD_DIR AND NOT ($root STREQUAL $ZEPHYR_BASE))
set(USING_OUT_OF_TREE_BOARD 1)
endif()
endforeach()
- 上面的代码会在 BOARD_ROOT 变量存在时从对应的目录下查找是否存在 boards 子目录,然后查找对应自定义板子的 defconfig 文件确定板级目录。
- 查找到板级目录后会根据板级目录的路径确认板子所属架构,如果查找不到对应的架构,终止编译并报错:
/* BOARD_DIR 的上一级目录作为 arch 目录 */
cmake_path(GET BOARD_DIR PARENT_PATH board_arch_dir)
/* board_arch_dir 去掉前缀仅保留文件名作为芯片的架构 */
cmake_path(GET board_arch_dir FILENAME ARCH)
/* 查找该架构是否在支持的列表中 */
foreach(root $ARCH_ROOT)
if(EXISTS $root/arch/$ARCH/CMakeLists.txt)
set(ARCH_DIR $root/arch)
break()
endif()
endforeach()
/* 终止编译并报错 */
if(NOT ARCH_DIR)
message(FATAL_ERROR "Could not find ARCH=$ARCH for BOARD=$BOARD, \\
please check your installation. ARCH roots searched: \\n\\
$ARCH_ROOT")
endif()
Zephyr_overlay文件讲解
在Zephyr下针对不同的boards可能会出现定制板的情况,或你的板子使用的串口或sdram内存空间与原生板不同,所以我们需要进行修改,但是,如果去修改zephyr目录下boards里的dts文件,很明显这会破坏文件体系,并且后面如果有人要编译同类型的板子就会出现问题。
同时这个板子可能只针对当前的项目,所以我们可以在当前项目的根目录下生成一个目录:boards
mkdir boards
然后进入这个目录,并创建一个与MCU型号一样名字以.overlay结尾
如我们的MCU是:mimxrt1061_evk,生成如下文件
cd boards
touch mimxrt1061_evk.overlay
然后在这个文件里以dts的方式来编写就可以了,这样Zephyr在编译时会读取boards目录下与MCU对应名字的overlay文件里的dts信息,来定制你的MCU。
如果想所有MCU都被修改可以声明一个统一的overlay文件:
touch app.overlay
那么无论你的MCU是什么样,都会读取app.overlay文件来定制MCU。
以上是关于Zephyr out of tree board的主要内容,如果未能解决你的问题,请参考以下文章
cJSON的使用教程(树外构建 out of tree build 概念)(组包概念)
Zephyr:compatible ‘micro,wm89xx‘ has unknown vendor prefix ‘micro‘
Zephyr:compatible ‘micro,wm89xx‘ has unknown vendor prefix ‘micro‘