Zephyr RTOS -- West 命令及编译过程简介

Posted 搬砖-工人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Zephyr RTOS -- West 命令及编译过程简介相关的知识,希望对你有一定的参考价值。

前言

本人正在学习 Zephyr,一个可移植性较强,可以兼容多种开发板及物联网设备的操作系统,如果你感兴趣,可以点此查看我的 学习笔记总述 进行了解!

 

摘要

前文 源树结构及软硬件配置过程简介 简单介绍了下关于一个新项目工程的配置过程,本文简单介绍一下 Zephyr 如何使用 West 命令来根据项目工程链接其他的 cmake 文件及脚本,最后编译生成 hex 文件。

 

West init & update

在获取及更新 Zephyr 代码时,west 可以看做是一个简单的 git 工具。

west init 命令就是获取远程仓库的代码,该命令提供了一个参数 -m,用来指定远程仓库的地址。例如之前我们获取的 ncs 仓库的命令,--mr 是指定版本号(分支):

west init -m https://github.com/nrfconnect/sdk-nrf --mr v1.5.0

如果不指定仓库地址,就默认获取 Zephyr 源码的仓库,像之前我们使用的 west init zephyrproject 命令会将该仓库下代码获取到 zephyrproject 的文件夹下,该命令等同于:

west init -m https://github.com/zephyrproject-rtos/zephyr

完整的 Zephyr 项目实际包含了 30 多个子仓库,并且每个子仓库都要求版本号(分支)。west init 只获取了关于 Zephyr 部分的代码,而 west update 命令就是获取这些相关联的子仓库代码并放到指定的目录下。

即:west update 命令用于获取和更新 Zephyr 仓库源代码及其相关联的 30 多个子仓库代码。

 

那么 west update 到底是怎么来获取这些子仓库的呢?

Zephyr 团队写了个脚本用来关联这些子仓库,这个脚本叫 west.yml,放在 zephyr 的源代码仓库下。

west update 会读取 zephyr\\west.yml 文件,将其中列举的仓库依次下载下来,放到指定目录下,若找不到 west.yml 文件就会报错。

west.yml 的部分内容如下所示:
west.yml
基本上是可以看出来这个脚本的含义:
https://github.com/zephyrproject-rtos 获取仓库代码,将 cmsis 仓库的 421dcf358fa420e9721a8452c647f0d42af8d68c 分支下载放至 modules/hal/cmsis 的目录下;依次执行,直至所有子仓库代码获取完毕,west update 的工作就完成了。

根据这个,我们也可以创建属于自己本地的 west.yml 文件,用来获取自己的仓库代码。

 
所以每次有新版本发布之后,我们需要使用 git checkout 来切换分支,获取新的 west.yml 脚本,以此更新整个仓库。

 

West build

west build 是最常用到的指令,用来进行编译,使用方法很简单,但是其处理机制比较复杂。以下是简单的编译命令:

初次编译:

west build -b <boards> …

再次编译:

west build -p …

-p 为清除老的生成文件。

重新编译:

west build -c

west build 的核心工作是执行:

mkdir build & cd build
cmake -GNinja -DBOARD=<boards> …
ninja

 
west 命令是怎么转换成 cmake 命令的呢?

west 在运行的时候会根据路径去寻找 .west 文件夹,该文件夹下的 config 文件记录了 zephyr 文件夹的路径,然后去读取 zephyr 目录下的 west.yml 文件。

west.yml后两行
关注 west.yml 的最后几行,又指向了 west 的扩展命令的路径:scripts/west-commands.yml

west-commands.yml
上面的脚本意味着:当执行 west build 命令时,会执行 scripts/west_commands/build.py;当执行 west flash 命令时,会执行 scripts/west_commands/flash.py;这些指令将执行的命令引导到了 Python 脚本上,最后经过 build.py 脚本处理之后生成执行命令:

cmake -B build_dir -S source_dir -G Ninja -DBOARD = board

 

West flash

west flash 命令被用来烧录 hex 文件。它会调用 nrfjprog 进行烧录,我们不需要指定 hex 文件路径,并且如果工程有变动,它会自动编译,生成新的 hex 文件。

与前面的 west build 一样,执行 west flash 命令最后会调用 flash.py,而 flash.py 会调用 run_common.py 这个脚本,该脚本会读取 runners.yaml 文件。

runners.yaml 文件格式如下所示:

runners.yaml

runners.yaml 文件是用来记录下载与调试的工具信息的,它不是固定的,是根据不同的芯片进行配置的,其中记录了使用什么工具进行下载,以及 hex 文件的路径。

runners.yaml 文件的生成过程:

以上面的 nrf52dk_nrf52832 为例,该硬件的 runner 配置信息是通过目录 zephyr\\boards\\arm\\nrf52dk_nrf52832 下的 board.cmake (与硬件的 dts 文件同路径) 进行设置的,在编译的时候依次执行下列文件:

zephyr\\cmake\\app\\boilerplate.cmake
zephyr\\CMakeLists.txt
zephyr\\cmake\\flash\\CMakeLists.txt

在最后一步中根据 runner 的配置信息 (board.cmake) 生成 runners.yaml 文件。

 

上面编译的这三个文件又是哪来的?怎么关联的呢?

 

CMakeLists.txt 文件编译过程

在前面的 West build 部分讲了执行 west build 命令最后会执行 build.py 的脚本,最终执行 cmake 的命令。而 cmake 命令是根据 CMakeLists.txt 文件来进行操作的。

打开我们的工程文件下的 CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(zephyr_prj)

target_sources(app PRIVATE src/main.c)
zephyr_include_directories(src)

第一行是设置要求的 cmake 的最小版本,一般与 Zephyr 下的工程项目保持一致,先不管它。

第三行是设置工程,也先不管。

第五、六行是将你的源代码 (.c) 及相关的 .h 文件添加工程文件中。

重要的是第二行,它就是那个关键点。find_packagecmake 的系统函数,该行是表示在 ZEPHYR_BASE 目录中寻找命名为 Zephyr 的模块。

$ENV{ZEPHYR_BASE} 设计了 zephyr 的根目录路径,比如前面我搭建环境时设置的 F:\\ncs\\zephyr

 
编译时执行的 build.py 脚本中引用了 zephyr\\scripts\\west_commands\\zephyr_ext_common.py,在这个脚本中设置了 ZEPHYR_BASE 的宏。

cmake 的文档中找到关键注释:

于是,根据这个提示我们找到名为 Zephyr 的模块文件:zephyr\\share\\zephyr-package\\cmake\\ZephyrConfig.cmake

ZephyrConfig.cmake 调用 zephyr\\cmake\\app\\boilerplate.cmake,它将处理 Device treeKconfig 等配置信息,最终生成必要的头文件,它还会关联其他的相关文件及 Zephyr 下的 CMakeLists.txt 文件,这个 CMakeLists.txt 又会关联其他的配置文件以及 zephyr\\cmake\\flash\\CMakeLists.txt,最终完成整个编译的过程。

 
编译完成后,会在生成的 <build> 文件夹下生成一个名为 CMakeCache.txt 的文件,这个文件记录了编译过程中保存的一些变量值和文件,还有相关的文件路径,这些信息用来烧录与调试。

CMakeCache.txt 文件包含 West 在烧录时使用的默认值,例如开发板目录 (.dts) 在文件系统上的位置、以多种格式烧录的内核二进制文件的路径等等。 你可以在运行时使用其他选项覆盖此配置。

 

West 一些常用命令

编译:

west build -b <board> -d <build-dir> -p …

参数:

  • -b :等同于 --board,编译的开发板类型
  • -d :等同于 --build-dir,编译生成的存放文件的目录
  • -p :等同于 --pristine,清除老的生成文件
  • -c :等同于 --cmake,重新编译
  • -t :等同于 --target,其他功能

命令行界面:

west build -t menuconfig

GUI 界面:

west build -t guiconfig

注意:使用界面工具时,需保证已经有生成的 <build> 文件夹 (编译指定生成的文件夹),因为界面工具是通过修改 <build>/zephyr/.config 文件来进行工作的。

查看 RAM/ROM 占用:

west build -t ram_report       查看 RAM 占用
west build -t rom_report       查看 ROM 占用

打印详细调试信息:

以下命令依次打印更低级别的调试信息:

west -v build
west -vv build
west -vvv build

下载:

west flash

 

参考链接

https://docs.zephyrproject.org/latest/guides/west/build-flash-debug.html

以上是关于Zephyr RTOS -- West 命令及编译过程简介的主要内容,如果未能解决你的问题,请参考以下文章

Zephyr RTOS -- West 命令及编译过程简介

Zephyr RTOS -- West 命令及编译过程简介

Zephyr RTOS -- 开发环境的搭建 (基于 Windows)

Zephyr RTOS -- 开发环境的搭建 (基于 Windows)

Zephyr RTOS -- 开发环境的搭建 (基于 Windows)

Zephyr RTOS -- 创建并编译一个新的工程