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
的部分内容如下所示:
基本上是可以看出来这个脚本的含义:
从 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
的扩展命令的路径:scripts/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
文件是用来记录下载与调试的工具信息的,它不是固定的,是根据不同的芯片进行配置的,其中记录了使用什么工具进行下载,以及 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 $ENVZEPHYR_BASE)
project(zephyr_prj)
target_sources(app PRIVATE src/main.c)
zephyr_include_directories(src)
第一行是设置要求的 cmake 的最小版本,一般与 Zephyr 下的工程项目保持一致,先不管它。
第三行是设置工程,也先不管。
第五、六行是将你的源代码 (.c
) 及相关的 .h
文件添加工程文件中。
重要的是第二行,它就是那个关键点。find_package
是 cmake 的系统函数,该行是表示在 ZEPHYR_BASE 目录中寻找命名为 Zephyr 的模块。
$ENVZEPHYR_BASE 设计了 zephyr 的根目录路径,比如前面我搭建环境时设置的 F:\\ncs\\zephyr
。
编译时执行的 build.py
脚本中引用了 zephyr\\scripts\\west_commands\\zephyr_ext_common.py
,在这个脚本中设置了 ZEPHYR_BASE 的宏。
在 cmake 的文档中找到关键注释:
- cmake 模块的 Module Mode 和 Config Mode 为:<PackageName>Config.cmake 或 Find<PackageName>.cmake
- cmake 模块的 Search Procedure 为:<prefix>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/
于是,根据这个提示我们找到名为 Zephyr 的模块文件:zephyr\\share\\zephyr-package\\cmake\\ZephyrConfig.cmake
。
ZephyrConfig.cmake
调用 zephyr\\cmake\\app\\boilerplate.cmake
,它将处理 Device tree 和 Kconfig 等配置信息,最终生成必要的头文件,它还会关联其他的相关文件及 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 -- 开发环境的搭建 (基于 Windows)
Zephyr RTOS -- 开发环境的搭建 (基于 Windows)