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‘

1066. Root of AVL Tree (25)

Bighead Fighter - Boarding the Peak of the Beast

*Tree child->parent relationships