0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何开发你的第一个NCS(Zephyr)应用程序

Nordic半导体 来源:Nordic半导体 作者:Nordic半导体 2020-12-29 09:47 次阅读

Nordic有2套并存的SDK

1、老的nRF5 SDK

2、新的NCS SDK

两套SDK相互独立,

大家选择其中一套进行开发即可。

一般而言,如果你选择的芯片是nRF51或者nRF52系列,那么推荐使用nRF5 SDK

如果你选择的是Nordic最新产品系列,比如nRF53或者nRF9160,那么请选择NCS SDK

还有一种特殊情况,虽然你选择的是nRF52芯片,但需要使用最新的一些射频技术,比如蓝牙测向,蓝牙Mesh v1.1,低功耗蓝牙音频,那么也需要使用NCS SDK。

换句话说,最新的射频技术,Nordic都只会在NCS上进行开发,而nRF5 SDK将进入维护阶段不再增加新的特性(如发现bug,会对其进行修复的)。

目录

1、NCS SDK介绍

2、NCS SDK 安装

2.1 - 百度网盘下载 (仅适用于Windows)

2.2 - 通过nRF connect桌面版直接下载GitHub下载(Windows/ Linux/ macOS)

2.3 - nRF command line tools安装

3、NCS SDK开发环境说明

3.1 - SES 开发环境搭建

3.1.1. nRF52项目示例

3.1.2.nRF53项目示例

3.1.3.nRF9160项目示例

3.1.4. 自定义项目装载示例

3.2 - 命令行方式开发环境搭建

3.2.1.nRF52项目示例

3.2.2. nRF53项目示例

3.2.3. nRF9160项目示例

3.3 - 命令行方式开发环境搭建

4、NCS SDK项目的配置或选项

4.1 - NSC项目配置介绍(autoconf.h和devicetree_unfixed.h)

4.1.1.Kconfig (Kconfig, prj.conf及autoconf.h)

4.1.2.Device Tree (*.dts, *.overlay及devicetree_unfixed.h)

4.1.3. 配置程序起始地址和大小

4.2 - 图形化查看Kconfig选项

4.2.1.SES查看

4.2.2.命令行方式查看

5、NCS SDK中几个比较重要的目录

5.1- 例子目录

5.2 - API目录

5.3 板子定义目录

6、开发你的第一个NCS程序

6.1- 修改hello_world main.c文件

6.2 - 在项目中添加一个新的文件blinky.c

6.3 修改blinky.c文件

6.4 编译和运行你的第一个hello_world程序

6.5 使用prj.conf和.overlay配置项目

7、开发你的第一个multi-image(多image)应用

7.1 - 分区管理 (Partition Manager)

7.2 多image的hello_world程序开发

8、NCS编译系统几个要注意的点

8.1 - NCS几个重要的编译系统变量

8.2 - conf文件命名规则及编译顺序

8.3 - overlay 文件命名规则及编译顺序

nRF5 SDK的介紹

关于nRF5 SDK的介绍,请参考这篇博文之前的博文,基本上都是基于nRF5 SDK进行阐述的,尤其是这篇:

Nordic nRF51/nRF52开发环境搭建

详细讲解了nRF5 SDK开发环境的搭建,这里不再赘述。下面将只对NCS SDK进行阐述,以期让大家快速了解这个Nordic最新SDK,并尽快熟悉和上手。

1、NCS SDK介紹

NCS全称nRF Connect SDK,是Nordic最新的SDK平台,该平台将支持Nordic所有产品线,包括低功耗蓝牙,蜂窝网,2.4G,蓝牙Mesh,Zigbee,Thread,CHIP等。

换句话说,由于短距离无线网络和长距离无线网络共用同一个SDK,将使得你同时具备两种网络的开发经验,因为他们的框架是一样的,驱动是一样的,网络协议栈的编写风格也是相仿的。

只要你熟悉了其中一种网络的开发,那么相关的经验可以迅速复制到新网络平台上。


NCS SDK内嵌Zephyr RTOS,并沿用了Zephyr project的编译系统。Zephyr Project是Linux基金会推出的一个Apache2.0开源项目,版权非常友好,适合用于商业项目开发。

°Zephyr Project

Zephyr Project是一个合作社区,其产品就是Zephyr,具体包括Zephyr RTOS,Zephyr组件以及Zephyr编译系统等

Zephyr很多地方都模拟了Linux,比如使用了DeviceTree和Kconfig,对Linux很熟的同学,阅读Zephyr代码会感到很亲切的

经常有人问:为什么NCS要使用Zephyr RTOS?

其实答案就蕴含在Zephyr Project的愿景中:The Zephyr Project strives to deliver thebest-in-class RTOS for connected resource-constrained devices, built be secureand safe

Zephyr的愿景跟Nordic的产品策略高度吻合,这也是为什么Nordic要选Zephyr的主要原因

NCS SDK和Zephyr Project两者最大的区别有3个:

owner不同,NCS SDK由Nordic负责,Zephyr SDK由Linux基金会负责。NCS开发中碰到的所有问题,Nordic都将负责解决

产品管理不一样,NCS SDK将由Nordic完成所有相关测试和考核,并符合Nordic产品开发,测试,发布和质量控制流程,因此NCS有自己的版本,并跟Zephyr版本控制解耦

NCS具有很多增强特性,比如Nordic特有的蓝牙链路层等

所以,从产品角度看,NCS SDK和Zephyr SDK是两套完全不同的SDK。但是,如果从代码角度看,那么NCS SDK和Zephyr SDK又基本上是一样的。

在本文章的下面部分,在不引起混淆的情况下,经常会把NCS和Zephyr两个概念换着使用,因为本质上他们是一个东西。

°NCS使用了CMake编译系统

并使用了大量Python脚本以辅助生成一些头文件,代码和hex,这些都大大增加开发的可移植性和便利性。

°NCS SDK放在GitHub上

里面包含多个代码库,其主代码库(Manifest)是nrf,同时还包含Zephyr,MCUBoot,mbedtls,nrfxlib等其他代码库。NCS SDK可以同时在Windows,macOS和Linux上运行。

°于Zephyr和NCS的build系统是一样的

于Zephyr和NCS的build系统是一样的,如果你正在学习Zephyr RTOS,那么也可以参考本篇文章,从NCS SDK开始学习Zephyr。由于NCS SDK新增了很多特性,比如图形化的DEBUG,丰富的例程,你会发现从NCS SDK学习Zephyr是一条便捷通道。

2、NCS SDK安裝

NCS SDK开发包比较大,目前大概4G(后续有可能会更大),由于GitHub网络带宽的问题,很多人下载的时候会出现超时错误,为此我们提供如下两种安装方案。

如果你能在早上6点左右起床,请参考2.2方案(GitHub直接下载);如果你不想早点起来,请参考2.1方案(百度网盘下载)。

°2.1 百度网盘下载(仅适用于Windows)

代码链接

地址如下所示:

下载链接:https://pan.baidu.com/s/1FKTfY3Q_zBVvviO7KC7Gyg#list/path=%2Fblog

提取码:y8fb

进入目录“开发你的第一个NCS(Zephyr)应用程序”,选择相应的版本,推荐使用最新版本。本篇博文完成之时最新量产tag为:

ncs_v1.4.1

后续还会有ncs_v1.5.0,ncs_v1.6.0等。

直接把相应的压缩包下载下来并解压到本地目录,SDK即算安装完成。

注意,这个压缩包只能在Windows系统上运行,不能在Linux和macOS上运行。

*注:ncs_v1.4.99-dev1是专为nRF53准备的一个临时开发版本,量产版本需要等到v1.5.0或者更新。

°2.2 通过nRF connect桌面版直接GitHub下载(同时支持Windows, Linux和macOS)

采用这个方案,你必须早上6:00左右起床,切记!

首先,下载桌面版nRF connect (同时支持Windows/macOS/Linux平台)。下载链接为:

https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Connect-for-desktop/Download#infotabs,选择你的平台和版本。

3793133e-48c7-11eb-8b86-12bb97331649.png

桌面版nRF connect安装成功后,将如下所示:

37c77cdc-48c7-11eb-8b86-12bb97331649.png

在nRF connect桌面版中有2个app都可以完成NCS SDK安装:

一个是Toolchain Manager

一个是Getting Started Assistant

如果你是GitHub老手,可以按照Getting Started Assistant的步骤一步一步来安装。如果你嫌一步一步安装麻烦,那么建议你使用Toolchain Manager一键安装。

下面将会以Toolchain Manager的方式(支持Windows和macOS)来讲解安装过程(Getting Started Assistant的方式自己有兴趣可以自己去摸索,而且Linux系统目前只能采用这种方式)。

首先install Toolchain Manager,然后open,进入settings界面,选择安装目录,如下:

37efcc1e-48c7-11eb-8b86-12bb97331649.png

然后重新选择SDK ENVIRONMENTS页面,并选择SDK相应版本进行安装,如下所示:

382dd4dc-48c7-11eb-8b86-12bb97331649.png

根据网速不同,这个过程持续时间变化很大,我这边网络大概需要20分钟完成所有下载和安装,安装成功后你将得到如下目录内容:

386ba816-48c7-11eb-8b86-12bb97331649.png

38a4545e-48c7-11eb-8b86-12bb97331649.png

°2.3nRF command line tools安装

下载完SDK压缩包,再下载 “nRF-Command-Line-Tools_10_11_1_Installer.exe”, 即nRF command line tools,nRFcommand line tools包括Jlink驱动以及Nordic自己开发的一些命令行工具,如nrfjprog,nrfutil以及mergehex等,这些工具对开发非常有帮助。nRF command line tools下载链接为: https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools/Download#infotabs

391cc6aa-48c7-11eb-8b86-12bb97331649.png

3、NCS SDK开发环境说明

NCS支持的工具链有2套:

一套是SEGGER Embedded Studio,简称SES,图形化的IDE

一套是命令行方式(沿用了Zephyr工具链),其实就是GCC工具链

两套工具链选其一即可,推荐大家使用SES,因为它的debug功能非常好使。(GCC工具链的debug功能使用起来就比较复杂了)。

下面将分别对SES和命令行方式两种开发环境进行介绍,大家可以参考其中一种或者两种结合一起使用。

°3.1SES开发环境搭建

通过百度网盘或者Toolchain Manager安装的SDK,必须进入如下目录:install folder oolchain并双击SEGGER Embedded Studio.cmd以打开SES,而不能在其他地方直接打开SES,如下所示:

398058e6-48c7-11eb-8b86-12bb97331649.png

SES启动成功后,进入Tools->Options,我们需要先对IDE进行配置。

39a91ff6-48c7-11eb-8b86-12bb97331649.png

如下两种方式的配置有可能都能工作起来,选择一种适合你的(一般来说,推荐配置二,这个配置方式可以适用任何电脑环境)。

°配置一:

3a5e9b92-48c7-11eb-8b86-12bb97331649.png

°配置二:

3dc5910a-48c7-11eb-8b86-12bb97331649.png

配置好了之后,我们就可以打开一个工程进行编译了。进入File->Open nRF Connect SDK Project。

4183ff48-48c7-11eb-8b86-12bb97331649.png

41b3bd8c-48c7-11eb-8b86-12bb97331649.png

在NCS中,项目是通过CMakeLists.txt表示的,如下:

42273898-48c7-11eb-8b86-12bb97331649.png

而开发板一般是在如下目录的:

428df164-48c7-11eb-8b86-12bb97331649.png

选择开发板,就是选择芯片,除此之外,开发板还规定了芯片的一些外设使能情况,以及一些基本外围电路连接情况,这个跟Keil如下选择Device的操作是异曲同工的,而且NCS这种做法更灵活,功能也更多,扩展性也更好。

42ced292-48c7-11eb-8b86-12bb97331649.png

如下为hello_world项目的装载图:

4302596e-48c7-11eb-8b86-12bb97331649.png

下面将对nRF52/nRF9160/nRF53项目,以及客户自定义项目,分别进行阐述,以详细说明如何装载一个项目,编译一个项目,下载一个项目和debug一个项目。 °3.1.1nRF52项目示例 以nrfapplications rf_desktop项目为例,开发板选择支持LLPM的gaming mouse:nrf52840gmouse_nrf52840

4343ed20-48c7-11eb-8b86-12bb97331649.png

装载成功后,编译,如下所示:

4373397c-48c7-11eb-8b86-12bb97331649.png

然后下载,如下所示:

439d6a62-48c7-11eb-8b86-12bb97331649.png

如果要Debug,按如下界面进入:

43fe4b34-48c7-11eb-8b86-12bb97331649.png

°3.1.2nRF53项目示例 Nordic第一个支持nRF53的tag是v1.4.99-dev1,v1.5.0将正式支持nRF53的量产开发,如果你需要开发nRF53,请使用v1.4.99以上版本。 由于nRF53包括两个核:

app核:用来运行应用程序

network核:network核用来运行射频协议栈

所以每次下载的时候需要同时把两个核的hex都下载进去,但是SES只支持一次下载一个核(west可以同时下载两个核,具体请参考第3.2节)。 在使用SES开发nRF53的时候,项目装载/编译/下载/debug跟其他芯片是一样的,但这些操作只是针对一个核(一般来说都是app核),此时如果还需要network核配合的话,那么需要你手动先把network核的image下载进去,这个可以通过nrfjprog或者west来完成。

这里要强调一点的是,当你选择一个蓝牙项目,这个项目默认会同时把app核和network核对应的工程都进行编译,然后生成各自的hex文件,然后你通过nrfjprog或者west把network核的image下载进去,通过SES本身的Target->Download菜单把app核的image下载进去。 以nrfsamplesluetoothperipheral_uart蓝牙透传项目为例:

4437e98e-48c7-11eb-8b86-12bb97331649.png

编译如下所示:

44693eb2-48c7-11eb-8b86-12bb97331649.png

编译成功后,先下载network核里面的image,我们以west flash来下载。进入目录: nrfsamplesluetoothperipheral_uartuild_nrf5340dk_nrf5340_cpuapphci_rpmsg,然后在cmd输入: west flash 即可将image下载到network核里面,如下所示:

44a70148-48c7-11eb-8b86-12bb97331649.png

如果west flash在你的环境跑不通,那么你可以直接使用nrfjprog来下载network核的image,进入目录: nrfsamplesluetoothperipheral_uartuild_nrf5340dk_nrf5340_cpuapphci_rpmsg,然后在cmd输入如下命令: nrfjprog -f NRF53 --coprocessor CP_NETWORK --sectorerase--program merged_CPUNET.hex --verify

然后下载app核image,app核image可以直接通过SES下载,如下:

44eac5a4-48c7-11eb-8b86-12bb97331649.png

如需debug,按如下界面进入:

4521678a-48c7-11eb-8b86-12bb97331649.png

°3.1.3 nRF9160项目示例 以nrfsamples rf9160mqtt_simple项目为例:

4556a710-48c7-11eb-8b86-12bb97331649.png

编译如下所示:

459c592c-48c7-11eb-8b86-12bb97331649.png

下载如下所示:

45e65612-48c7-11eb-8b86-12bb97331649.png

如需debug,按如下界面进行:

461ae044-48c7-11eb-8b86-12bb97331649.png

°3.1.4 自定义项目装载示例 如果是你的自定义项目或者Zephyr项目或者不使用toolchain自带的SES,此时就不能使用SES自带的快捷方式来装载项目,而需要自己去相应的目录找到项目工程和开发板,比如我们装载Zephyr的blinky例子。先选择项目工程CMakeLists.txt所在的目录,如下:

4668d5ce-48c7-11eb-8b86-12bb97331649.png

再选择相应的开发板,如下:

4699b8f6-48c7-11eb-8b86-12bb97331649.png

然后项目就装载成功了,如下:

46ccadd8-48c7-11eb-8b86-12bb97331649.png

后面编译,下载和调试,和之前一样,就不再赘述。 °3.2 命令行方式开发环境搭建 NCS或者Zephyr项目命令行编译的时候,一般使用west命令,west语法可以通过west –help获得,如下:

470072ee-48c7-11eb-8b86-12bb97331649.png

如果你能看到上面的界面,那么你的环境基本上就没问题了。 一个典型的west命令如下所示: west build -bnrf52840dk_nrf52840 *注:-b指定开发板,这里使用nRF52840开发板 通过百度网盘或者Toolchain Manager安装的SDK,必须进入如下目录:install folder oolchain并双击git-cmd.cmd以打开命令行,而不能直接打开CMD,如下所示:

473dd2d8-48c7-11eb-8b86-12bb97331649.png

git-cmd.cmd会自动把环境变量设好,否则后续编译会有问题。 下面分别以nRF52/nRF53/nRF9160开发为例,展示相应的编译和下载命令。 °3.2.1 nRF52项目示例

下面以编译nrfapplications rf_desktop项目为例来讲解。首先进入项目所在的目录

cd nrfapplications rf_desktop 界面将如下所示:

47654c32-48c7-11eb-8b86-12bb97331649.png

由于已经进入了项目所在的目录,编译的时候就无需再指定项目目录了,由于nrf_desktop支持多个开发板,我们还需要指定用哪一个开发板,如下所示: west build -bnrf52840gmouse_nrf52840 或者 west build -bnrf52840gmouse_nrf52840 -p *注:-p用来清除build目录缓存

478d8508-48c7-11eb-8b86-12bb97331649.png

由于上面没有指定build目录,上面的命令会自动生成一个build目录(名字就是build),然后所有的编译文件会自动放在该build目录下: build目录如下所示:

47cd080e-48c7-11eb-8b86-12bb97331649.png

4809aa16-48c7-11eb-8b86-12bb97331649.png

编译成功后,就可以烧写了,使用如下命令进行烧写: west flash 或者 west flash –erase

4831e88c-48c7-11eb-8b86-12bb97331649.png

°3.2.2nRF53项目示例 以nrfsamplesluetoothperipheral_uart为例来讲解。首先进入目录:nrfsamplesluetoothperipheral_uart,然后输入如下编译命令: west build -bnrf5340dk_nrf5340_cpuapp--build-dir build_nrf5340dk_nrf5340_cpuapp -p *注:-b指定开发板,--build-dir指定编译目录,-p清除老的编译目录内容

48be8350-48c7-11eb-8b86-12bb97331649.png

编译成功后,就可以烧写了,使用如下命令进行烧写:

west flash--build-dir build_nrf5340dk_nrf5340_cpuapp

491c44d6-48c7-11eb-8b86-12bb97331649.png

°3.2.3nRF9160项目示例

以nrfsamples rf9160mqtt_simple为例来讲解。首先进入目录: nrfsamples rf9160mqtt_simple 然后输入如下编译命令: west build -bnrf9160dk_nrf9160ns --build-dir build_nrf9160dk_nrf9160ns -p *注:-b指定开发板,--build-dir指定编译目录,-p清除老的编译目录内容

4956f45a-48c7-11eb-8b86-12bb97331649.png

编译成功后,就可以烧写了,使用如下命令进行烧写: west flash--build-dir build_nrf9160dk_nrf9160ns

499e4f62-48c7-11eb-8b86-12bb97331649.png

°3.3 NCS SDK版本说明 NCS SDK开发包目录如下所示:

38a4545e-48c7-11eb-8b86-12bb97331649.png

可以看出,NCS SDK包含nrf,zephyr,bootloader,nrfxlib,modules等多个代码库,其中nrf代码库就是NCS SDK的主代码库(manifest),nrf代码库的版本就是NCS SDK的版本,所以要查看NCS SDK当前版本号,进入nrf目录,输入git branch,如下:

4a5c0ff2-48c7-11eb-8b86-12bb97331649.png

熟悉git的同学都知道,一个SDK如果包含多个代码库,那么每个代码库都有自己的版本,而且代码库版本之间是相互关联的。 以NCS SDK为例,当nrf版本切换为v1.4.0时,其他代码库的版本也需要做相应切换。 那么对应nrf v1.4.0的Zephyr代码库版本是多少呢?mcuboot代码库版本是多少呢?

如果直接使用git工具,那么你需要一个一个记,然后一个一个checkout。在NCS或者Zephyr中,引入了west工具,这样通过管理nrf代码库版本就可以间接管理其他代码库的版本,比如我们现在把NCS SDK版本切换到v1.4.0,指令如下所示: git checkout v1.4.0 然后通过west update命令,就可以让其他代码库版本自动跟v1.4.0 nrf代码库同步,这样你不需要记住或者管理其他代码库版本,只需管理nrf代码库版本即可。 west update

4a7ee05e-48c7-11eb-8b86-12bb97331649.png

4、NCS 项目的配置或选项

°4.1 NCS项目配置介绍(autoconf.h和devicetree_unfixed.h)

每一个NCS或者Zephyr项目都包含了非常多的配置项或选项,总数有可能达几千项之多,然而绝大多数配置项我们都不需要去管他们,只需要使用默认值即可,所以开发一个简单的NCS应用程序,有可能我们不需做任何配置,就可以跑起来。

当你开发复杂的应用程序的时候,你又会体会到NCS配置的灵活性和方便性了,这其实也是NCS一个很大的优势。

本章我们先讲如何查看配置项,后面一章我们再以例子来说明如何更改配置项。

NCS或者Zephyr里面主要包含两种配置项:

Kconfig:主要负责软件的配置

DeviceTree:主要负责板子硬件的配置

两者最终都会生成一个.h文件,其Kconfig生成的头文件为:autoconf.h,而DeviceTree生成的头文件为devicetree_unfixed.h,他们都在如下目录:

4b083700-48c7-11eb-8b86-12bb97331649.png


autoconf.h文件示例如下:

4b3e8120-48c7-11eb-8b86-12bb97331649.png

devicetree_unfixed.h文件示例如下:

4b8437ba-48c7-11eb-8b86-12bb97331649.png

如果大家开发过nRF5 SDK的话,一定记得里面有个:sdk_config.h,从机理上,sdk_config.h和上面的autoconf.h/devicetree_unfixed.h并没有本质区别,他们都是完成同样的功能。 但是很多人都觉得Kconfig和DeviceTree很复杂,其实他们复杂之处在于如何生成这两个头文件,但是头文件本身并不复杂。 在nRF5 SDK中,用户可以直接修改sdk_config.h文件,由于sdk_config.h文件太大,所以Nordic使用了CMSIS_Configuration_Wizard来格式化这个头文件,以形成如下的图形化界面方便大家去修改它:

4bdb3858-48c7-11eb-8b86-12bb97331649.png

在NCS或者Zephyr里面,由于autoconf.h/devicetree_unfixed.h是由Python脚本自动生成的,所以用户不能直接修改autoconf.h/devicetree_unfixed.h这两个头文件。 用户只能去修改生成这两个头文件的输入,以达到间接修改他们的目的。这样做的好处是:更灵活,而且不容易出错(Python会自动帮你找出配置不合理的地方或者语法错误)。 可以说,一旦你熟悉了这套配置机制,你就会爱上它。 下面分别对autoconf.h和devicetree_unfixed.h两者的生成过程进行阐述。 °4.1.1 Kconfig(Kconfig, prj.conf及autoconf.h) 我们先把生成autoconf.h文件的整体流程图贴出来,后面再对这个图进行解释:

4c221c32-48c7-11eb-8b86-12bb97331649.png

autoconf.h文件是由许许多多的Kconfig文件生成的(注:其实Kconfig来源于Linux系统,NCS或者Zephyr对其进行了继承和定制),基本上每个模块都有自己的Kconfig文件,比如蓝牙controller模块:

4c60d562-48c7-11eb-8b86-12bb97331649.png

使用文本编辑器打开Kconfig,你将会看到它的内容大概如下所示:

4c85c520-48c7-11eb-8b86-12bb97331649.png

除了系统模块可以定义Kconfig文件,你自己的项目模块也可以定义自己的Kconfig文件。 如何定义? 依葫芦画瓢,仿照例子来即可。 记住,在NCS或者Zephyr里面,只要可以用文本编辑器打开的文件,他们的语法都是直接可读的,不需要你另外去学习他们,直接仿照例子,你就可以定制自己的内容。 除了Kconfig,autoconf.h还有一个输入来源: 本项目的配置文件。 前面说过,Kconfig文件都是模块自带的,模块为每一个选项都设了一个默认值。 如果你想修改这个默认值,怎么办? 你不需要跑到模块下面直接把Kconfig文件改了(这样不方便,而且也会影响到其他项目工程的运行)。为此NCS或者Zephyr引入了prj.conf文件,prj.conf文件内容大概如下所示:

4caf796a-48c7-11eb-8b86-12bb97331649.png

通过prj.conf,大家就可以更改默认的Kconfig选项了,而且这个更改是永久的,并只适用于本项目。 所有的Kconfig和prj.conf结合,先生成一个.conf文件,最后再生成autoconfig.h。.conf文件在如下目录:

4d101e32-48c7-11eb-8b86-12bb97331649.png

其内容大概如下所示:

4d60ca26-48c7-11eb-8b86-12bb97331649.png

可以看出,.config文件格式更接近Kconfig和prj.conf,起到了一个中间桥梁作用。 .config和autoconfig.h两者内容是可以一一对应的,因此大部分图形配置系统都是直接调用.config文件来完成图形化配置Kconfig的,后面我们会讲解如何使用SES和menuconfig来图形化配置.config文件。 .config是一个临时文件,编译系统默认会以它为基准来生成autoconfig.h,所以一旦你的Kconfig或者prj.conf更新了,记得一定要重新装载项目,以更新.config文件,从而生成新的autoconfig.h文件。 °4.1.2Device Tree (*.dts, *.overlay及devicetree_unfixed.h) 同样我们先把生成devicetree_unfixed.h的整体流程图列出来,后面再对其进行解释:

4dc14248-48c7-11eb-8b86-12bb97331649.png

DeviceTree也是Linux里面的概念,NCS或者Zephyr对其进行了继承和定制。在DeviceTree里面,每一种硬件比如芯片或者板子,都可以使用DeviceTree语言进行描述。 DeviceTree使用了树形结构,按照层级关系把板子包含的组件一一描述清楚,每块板子都会定义一个dts文件,比如nrf52840dk_nrf52840开发板,它对应的dts文件是nrf52840dk_nrf52840.dts,其内容如下所示:

4dff3170-48c7-11eb-8b86-12bb97331649.png

可以看到板子dts文件包含了一个nrf52840_qiaa.dtsi,nrf52840_qiaa.dtsi对应的就是nRF52840这颗芯片本身的dts文件。nrf52840 dtsi里面定义的内容,nRF52840dk开发板直接包含进来,然后在此基础上进行定制。 比如dtsi里面将UART0配置为关闭,nRF52840dk可以将其改配为使能;另一种需要修改的情况,nRF52840dk增加了一些其他组件 比如LED/Button/外部Flash等,这些设备都可以成为nrf52840dk_nrf52840.dts里面的一个节点。

nrf52840dk_nrf52840.dts是一种比较简单的板子,因此一个dts文件就可以将其表达清楚。我们还会碰到一种情况,几块板子大部分特性都是相同的,只有少数组件不一样,这个时候,我们会把相同的地方拎出来组成一个common.dts,然后这几块板子再引用这个common.dts文件,比如目录: zephyroardsarm rf9160dk_nrf9160,里面包含两块开发板:

nrf9160dk_nrf9160ns

nrf9160dk_nrf9160

两块开发板内容基本上是一样的,所以在这里把相同的内容拎出来组成了一个:

nrf9160dk_nrf9160_common.dts

然后nrf9160dk_nrf9160ns.dts和nrf9160dk_nrf9160.dts

再引用nrf9160dk_nrf9160_common.dts

这样拆分一下,逻辑关系更清晰,将使系统变得更灵活,扩展性更好。

4e49d7a2-48c7-11eb-8b86-12bb97331649.png

除了.dts,devicetree_unfixed.h还有一个输入来源: 本项目的硬件配置文件,即overlay文件。 刚才说了,每块板子都有自己的dts文件,里面描述了各个节点的状态,有时候我们会有多个项目共用同一块板子的情况,比如我们的开发板支持很多例子工程,每个例子工程的配置都不一样,有的例子需要打开uart,有的例子需要关闭uart。 这种情况怎么办? 你不需要跑到开发板定义目录下去更改.dts或者_common.dts,你只需要在本项目下定义一个.overlay文件就可以实现你的目标,.overlay文件内容示例如下所示:

4ea9527c-48c7-11eb-8b86-12bb97331649.png

通过.overlay,大家就可以更改板子的默认配置,而且这个更改是永久的,并只适用于本项目。 .dts和.overlay结合先生成一个zephyr.dts文件,最后再生成devicetree_unfixed.h。zephyr.dts文件在如下目录:

4ee764a4-48c7-11eb-8b86-12bb97331649.png

其内容大概如下所示:

4f11a41c-48c7-11eb-8b86-12bb97331649.png

可以看出zephyr.dts就是.dts和.overlay两个文件最终合并的结果,而且zephyr.dts和devicetree_unfixed.h是可以一一对应的,因此大家可以通过查看zephyr.dts来获知自己的硬件配置到底对不对,符不符合预期。 °4.1.3 配置程序起始地址和大小 每个应用都需指定其image的ROM起始地址和大小,以及运行时所占RAM的起始地址和大小,这些都需要在工具链中进行配置的,比如Keil,是在如下界面完成相关配置:

4f972f92-48c7-11eb-8b86-12bb97331649.png

在NCS或者Zephyr中,如果是一个单image应用,程序的起始地址和大小是在DeviceTree中配置的,如下:

4fca032c-48c7-11eb-8b86-12bb97331649.png

4ff07764-48c7-11eb-8b86-12bb97331649.png

4fca032c-48c7-11eb-8b86-12bb97331649.png

对于单image应用,最有用的就是上面三个红框标出来的地方,其他配置选项你可以忽略不管,一般来说能改的就一项: storage_partition的起始地址和大小, storage_partition就是分配给用户用来存储数据的区域。 一般来说,无线IoT应用都是要求具有固件升级功能,为了升级固件,BootLoader就必不可少,此时一个应用至少有两个image:BootLoader对应的image,以及app对应的image,对于这种多image应用,程序起始地址和大小配置一般不通过DeviceTree直接来修改,而是交由partition manager(PM)模块来管理,具体请参考第7章:开发你的第一个multi-image(多image)应用。

°4.2图形化查看Kconfig选项 上面说了,大家可以通过.config文件去查看最终的Kconfig配置,然后通过zephyr.dts文件去查看最终的DeviceTree配置。 zephyr.dts文件不是很大,因此推荐使用这种方法去查看。但是.config文件有点长,直接查看它有点累,而且容易搞错,为此NCS推出了两个图形化查看工具:SES配置和基于命令行方式的menuconfig或者guiconfig °4.2.1SES查看项 进入Project->Configure nRF Connect SDK Project,如下所示:

5089ff2e-48c7-11eb-8b86-12bb97331649.png

50c697d6-48c7-11eb-8b86-12bb97331649.png

由于一个项目的配置项太多,我们一般在右上角搜索配置项名字,找到它,然后查看它的说明。同时我们可以去尝试修改它,修改成功后,点击“Configure”,配置才能生效。 通过图形化界面进行修改,我们可以很快找到合适的配置选项,当大家对系统还不是很熟的时候,推荐使用这种方式去试错。这里强调一下,通过这种方式所做的修改是临时的,一旦项目重启或者缓存刷新了,这里的更改就会失效,所以我们一般推荐使用上面的prj.conf去永久修改配置项。

对于multi-image(多image)应用,点击Project->Configure nRF Connect SDK Project,会同时出现所有image的配置菜单,其中“menuconfig”对应的是主应用的配置项(其他menuconfig对应的是子image的配置项,具体请参考第7章:开发你的第一个multi-image(多image)应用),如下:

50c697d6-48c7-11eb-8b86-12bb97331649.png

°4.2.2命令行方式查看项 命令行方式使用如下命令查看项目配置: west build -tmenuconfig 执行上述命令后,将显示如下界面:

518dfb5a-48c7-11eb-8b86-12bb97331649.png

注:上述命令需要先安装windows-curses ,即在cmd中执行如下命令:pip install windows-curses –user,此命令的执行需要联网。如果你的电脑无法联网,建议使用guiconfig查看工程配置,其对应的命令为: west build -tguiconfig 执行上述命令后显示的界面如下所示:

51ba72e8-48c7-11eb-8b86-12bb97331649.png

由于一个项目的配置项太多,我们一般使用Jump to进行搜索,找到它,然后查看它的说明。同时我们可以去尝试修改它,修改成功后,选择“Save”,配置才能生效。 通过图形化界面进行修改,我们可以很快找到合适的配置选项,当大家对系统还不是很熟的时候,推荐使用这种方式去试错。这里强调一下,通过这种方式所做的修改是临时的,一旦项目重启或者缓存刷新了,这里的更改就会失效,所以我们一般推荐使用上面的prj.conf去永久修改配置项。 5、NCS SDK中几个比较重要的目录

如前所述,NCS SDK中包括了多个代码库,每个代码库都是相互独立的,而且每个代码库包含的代码都很多,如果一行一行代码读下去,那将是一个无底洞。所以实际开发中,我们都是参考例子,按照例子去做,碰到不懂的API,再去看API说明,循环往复,最终完成自己的开发。 °5.1例子目录 我们先说说例子所在的目录。NCS中商业级的应用程序是放在如下目录: nrfapplications

5200b7b2-48c7-11eb-8b86-12bb97331649.png

如果你的应用跟上面的应用相似,那么推荐使用上面的例子,因为他们基本上属于turn-key级的方案,跟成熟的商业应用差不多,你需要的开发工作量最少。 其次是如下例子目录nrfsamples,这个都是Nordic自己开发的一些例程:

52255ad6-48c7-11eb-8b86-12bb97331649.png

然后就是Zephyr自带的例子zephyrsamples:

大家有时候会觉得NCS或者Zephyr例子还是不够多,比如很多驱动API怎么用,好像没有例子。其实Zephyr所有API的的使用,都可以在zephyr ests下面找到示例,所以当你找不到例子的时候,不妨在这里找一找:

°5.2API目录 NCS里面这么多API,到底该使用哪些API?API说明又在哪里? 一般而言,我们只使用代码库里面的include目录下的API,API说明也在那里。 比如nrf代码库的include目录: nrfinclude

Zephyr标准API的include目录zephyrinclude:

其他代码库也是遵守这个规范的,比如Nordic开发的底层驱动API(与RTOS无关): moduleshal ordic rfxdriversinclude

*注:有些人会问:

moduleshal ordic rfxdriversinclude

zephyrincludedrivers

两个目录里面的驱动API,我到底该使用哪个呢?

zephyrincludedrivers这个是Zephyr标准的驱动API,按照Zephyr标准来定义的,它调用了底层API:

moduleshal ordic rfxdriversinclude

moduleshal ordic rfxdriversinclude这里面的API都是Nordic自己实现的,跟平台无关。

所以说,一般推荐使用zephyrincludedrivers这里面的API,只有这里面没有或者实现不了的功能(比如将同一个引脚动态分配给UART和SPI,Zephyr标准API就无能为力),这个时候才使用moduleshal ordic rfxdriversinclude这里面的API。 °5.3 板子定义目录 通过在cmd输入: west boards 就可以查看目前Zephyr支持哪些标准板子:

上面这些板子都是在如下目录定义的:
zephyroardsarm。 由于Cortex-M33内核支持secure和non-secure(ns)两种应用,所以每一个Cortex-M33内核都包含两种硬件定义:安全和非安全。 比如nrf9160dk,虽然物理上只有一块板子,逻辑上我们把它划分成两块板子:

nrf9160dk_nrf9160是跑安全应用

而nrf9160dk_nrf9160ns是跑非安全应用

同样nRF5340dk,虽然物理上只有一块板子,但是它有两个核都可以供用户使用,其中app核既可以跑安全应用又可以跑非安全应用,而网络核只能跑一种应用类型,所以nrf5340dk在逻辑上就划分成三块板子:

nrf5340dk_nrf5340_cpuapp(app核,跑安全应用)

nrf5340dk_nrf5340_cpuappns(app核,跑非安全应用)

以及nrf5340dk_nrf5340_cpunet(network核,跑非安全应用)

除了这些标准Zephyr板子,NCS还有一些自定义板子,他们在如下目录: nrfoardsarm

如果你要自定义自己的板子,可以参考上面例子来。 6、开发你的第一个NCS 程序

现在我们开始我们第一个NCS程序或者Zephyr程序的开发,在NCS中,有如下两个现成的例子:

zephyrsampleshello_world:hello_world例子就是在串口中打印一串字符串

zephyrsamplesasiclinky:而blinky例子就是让开发板的LED1一闪一闪

这两个程序直接就可以编译和运行,而且应该所有的Zephyr开发板都可以跑这两个程序。现在我们把这两个程序合成一个程序,即既打印字符串给串口助手,又让开发板LED1一闪一闪,同时我们把字符串打印变成循环打印,并将字符串同时输出到串口助手和RTT viewer。 下面我们一步一步给大家演示这个开发过程。

开发NCS程序

本章所有代码可以到如下百度网盘链接获取,进入“开发你的第一个NCS(Zephyr)应用程序”->“hello_world”,下载hello_world_ncsv140.rar:

下载链接:

https://pan.baidu.com/s/1FKTfY3Q_zBVvviO7KC7Gyg#list/path=%2Fblog

提取码:y8fbz

°6.1 修改hello_world main.c文件 首先,我们以hello_world例子为基础,将这个例子拷到一个其他目录下(任何目录都可(不要有中文和空格等),只要你的环境变量都设好了,所有NCS例子的目录可以随意更改,这个真是非常方便!),这里让大家拷贝到其他目录,只是为了演示NCS编译路径的依赖性做得非常好,没有别的意思。 如果你不想拷贝,也没关系,咱们可以直接在原始目录上进行修改,NCS自带git管理系统,非常方便你进行版本管理。我们做如下修改,以循环打印同一条日志:

°6.2 在项目中添加一个新文件blinky.c 然后把blinky代码加到hello_world,这里面就会用到添加一个新文件的技能。我们先把zephyrsamplesasiclinkysrc里面的main.c改名为blinky.c,然后拷贝到hello_worldsrc目录下。 如何把blinky.c添加到项目中来呢? 推荐的方法是修改CMakelists.txt文件,通过它加入新的编译文件或者库,或者包含新的目录。我们做如下修改,就可以把blinky.c加进来了:

这种方式不管是NCS项目还是Zephyr项目,都能工作成功,而且是我们首推的方式。 至于CMakeLists的语法怎么理解和使用? 还是那句话: 参考例子,不要专门去学习。除了修改CMakeLists方法外,NCS还引入了一种图形化方法,使用SES来添加文件,如下所示:

这种方式只有nrfsamples这个目录下的例子才支持,zephyrsamples这个目录下的例子默认不支持这种方式。 其实通过SES添加文件,本质上跟修改CMakeLists方法一样,它只不过在CMakeLists文件里面预先放入如下两行标识,这样SES就可以把新添加的文件塞到这两行标识之间:

我们把这两行标识放在我们的hello_world例子里面,这样我们也可以通过SES添加文件了。blinky.c文件添加成功后,相应的CMakelists文件也更新了,如下所示:

°6.3 修改blinky.c文件 好了,现在blinky.c文件已经添加成功了,我们再对其进行修改,修改代码如下所示:

如上,我们直接把blinky代码变成另外一个线程以达到我们的目的(当然你也可以把blinky代码变成一个模块,以供hello_world的main调用,这里就不演示这种方式了)。 °6.4编译和运行你的第一个hello_world程序 上述修改结束后,我们可以使用任何Zephyr标准板运行这个例子,以nrf52840dk为例,SES工程装载如下所示,然后编译和下载。

或者使用west命令进行编译和下载,命令如下所示: west build -b nrf52840dk_nrf52840 -dbuild_nrf52840dk_nrf52840 -p west flash --build-dirbuild_nrf52840dk_nrf52840 不管是SES下载完程序还是west下载完程序,可以看到程序正常执行,串口助手在循环打印“Hello World! nrf52840dk_nrf52840”,然后开发板上LED1在一闪一闪。串口截图如下:

我们第一个hello_world程序算是 正式大功告成了。 °6.5 使用prj.conf和.overlay配置项目 我们现在对hello_world再做一个修改:把log输出到RTT viewer而不是串口助手。传统的nRF5 SDK需要做两件事来达到这个目的:

一是修改sdk_config.h文件

二是添加相应文件

但是在NCS SDK里面,你只需在prj.conf里面做如下修改即可达到同样的目的:

运行后结果如下所示:

按道理说,上面的例子已经把日志输出改为RTT Viewer了,这时去测量nrf52840dk电流,应该很低才对,但实际上此时电流大概为500多微安。 这是什么原因呢? 我们看一下zephyr.dts文件,如下:

56a526c2-48c7-11eb-8b86-12bb97331649.png

可以看出,uart0和uart1都处于使能状态,从而导致功耗偏高。我们通过nrf52840dk_nrf52840.overlay文件,将uart0和uart1关闭,修改如下所示:

56d6e5fe-48c7-11eb-8b86-12bb97331649.png

同时在prj.conf把serial模块关掉(注:serial模块在所有项目默认是打开的),如下: CONFIG_SERIAL=n 实际上,serial模块只使用了uart0模块,所以只需把uart0关掉即可,如下:

重新编译和下载,这时我们再去测量nrf52840dk电流,此时电流只有几微安,符合预期。 7、开发multi-image应用

°第一个multi-image(多image)应用

有时一个应用会包含多个image,最典型的情况有两种:

一是BootLoader+app,BootLoader一个image,app一个image

二是spm+app,spm一个image,app一个image

*注:spm是Nordic为Cortex-M33非安全应用设计的一个引导程序,像nRF9160/nRF5340这种M33内核,所有非安全应用都会默认使能spm。 在NCS SDK中,编译一个项目,会同时生成多个不同image,这种应用就称为multi-image应用。单image应用其生成的hex名为:zephy.hex,multi-image应用其生成的hex名为:merged.hex merged.hex意味着这个项目会生成多个image,然后将他们合并(merge)成一个hex: merged.hex 因此multi-image应用对用户来说,最终也只有一个image,用户只需下载这个image即可。 nrfsamples rf9160http_application_update为例,这是一个典型的多image应用,它包含3个image:

BootLoader image

spm image

以及app image

这三个image都是在nrfsamples rf9160http_application_update编译目录下生成的,编译成功后,我们将同时看到三个image的编译目录,如下所示:

°7.1 分区管理(Partition Manager) 传统的SDK,如果一个产品包含多个image,那么每个image都会对应一个项目,用户需要同时维护多个项目,而且需要同时维护这几个项目的版本关联关系。 NCS中引入了partition manager(PM)模块(注:PM和前面的SPM是两个完全不同的模块,二者之间没有任何联系),由PM完成对多个image的管理,以及存储划分。 在PM中,主应用称为parent应用,其他应用称为child应用,通过使能parent应用的某些Kconfig,可以自动装载child应用,然后自动编译child应用,然后生成child应用的hex,并将child应用的hex和parent应用的hex合并在一起生成前文所述的merged.hex,这一切都发生在parent应用的build目录中。

PM是如何工作的呢? PM首先假定有一个app image,也就是我们的parent应用,这个应用对应的hex就是前文所述的zephyr.hex。 那么app image放在Flash什么地方呢? 这个是由PM动态决定的,PM将根据各个image的相对位置,来决定最终的image排列。 一般来说,parent应用是默认应用,它不需要特别去指定自己的位置,而child应用则需要告诉PM自己的位置在哪里,这个是通过child应用目录下面的pm.yml文件来实现的,pm.yml会告诉PM本child应用会放在那里,pm.yml文件内容大概如下所示:

pm.yml是按照相对位置来决定本child应用的位置的,而且里面会用到Kconfig或者DeviceTree的宏定义,所以前面的.dts文件会定义很多image slot,其实也是为了给PM引用的。 pm.yml看起来又是一种新格式文件,让人觉得有点不适应,其实还是那句话,你不需要专门去学习这个文件的原理,它的语法和格式都是你直接可以读懂的,多看看例子,自然就明白了。

而且一般开发过程中,大家也不需要关心child应用目录下的文件,大家只需关心parent应用目录下的相关PM文件即可。 那么parent应用目录下有哪些PM文件呢? 首先就是build根目录下多image最终布局的partitions.yml文件,以nrfsamples rf9160http_application_update为例,其partitions.yml文件如下所示:

partitions.yml文件是由PM模块自动生成的,用户不能直接修改。 然后就是pm.config 和pm_config.h文件,这两个文件一一对应,pm.config和partitions.yml放在同一个目录下,其内容大概如下所示:

而pm_config.h是C语言代码直接引用的文件,它在buildzephyrincludegenerated目录下。 nrfsamples rf9160http_application_update为例,其pm_config.h文件如下所示:

一般来说,使用PM自动生成的存储layout就可以了,只有一个配置有可能需要改: settings_storage的大小。 这个可以通过Kconfig选项CONFIG_PM_PARTITION_SIZE_SETTINGS_STORAGE直接修改就可以了。 如果需要人为指定某个image的位置,也就是说需要对自动生成的partitions.yml进行修改, 怎么办呢?

其实很简单,把partitions.yml这个文件拷出来,放在项目的根目录下,然后将其重新命名为: pm_static.yml 然后大家就可以按照自己的需求将里面的值进行修改。这里补充一下PM的另一个工作机理,当PM检测到parent应用目录下面有pm_static.yml文件,它就不会再自动去分配存储空间,而是直接使用这个静态的存储空间layout。 °7.2 多image的hello_world程序开发

多image的hello_world程序开发

本节所有代码可以到如下百度网盘链接获取,进入“开发你的第一个NCS(Zephyr)应用程序”->“hello_world”,下载hello_world_ncsv140.rar:

下载链接: https://pan.baidu.com/s/1FKTfY3Q_zBVvviO7KC7Gyg#list/path=%2Fblog

提取码:y8fb

我们现在将第6章的hello_world程序跑在多image环境下。 现在我们以nrf9160dk_nrf9160ns为例,重新编译一下前述的hello_world程序,由于nrf9160dk_nrf9160ns为非安全应用,前面也说过,所有Cortex-M33非安全应用都会默认使能spm模块,所以spm image将会自动加载进来并进行编译。

装载成功后,你可以看到build和download的target都变成: merged.hex,而不是以前的zephyr.hex,如下:

59799252-48c7-11eb-8b86-12bb97331649.png

而且build目录也会多一个spm的build目录,如下所示:

59d66270-48c7-11eb-8b86-12bb97331649.png

程序跑起来后,log如下所示:

5a33c2d0-48c7-11eb-8b86-12bb97331649.png

跟第6章一样,我们再定义一个overlay文件,以将uart0关掉,此时我们去测9160dk的电流,应该只有几微安,但实际上我们测下来还是500多微安。 这是为什么呢? 因为spm还使能了serial和uart0,这个可以从spm的.config和zephyr.dts文件得到验证,如下:

所以uart0在spm中打开了,然后程序跳到app,uart0还是处于打开状态,从而导致功耗偏高。 那么我们怎么可以便捷的关闭spm里面的serial模块和uart0?

方法一,大家跑到spm例子里面,然后定义前述的prj.conf和.overlay以关闭serial模块和uart0,但这种方法会影响其他例子

方法二,我们在parent应用中定义spm的prj.conf和.overlay文件,这样spm只在这个parent应用中关闭了serial模块和uart0,对其他应用不产生任何影响。

为了将parent应用中的conf和overlay文件传给spm,需要用到NCS编译系统的编译变量,给相应的变量赋值,从而可以将相关文件传递给spm,具体请参考第8章。 我们对CMakelists文件做如下修改:

通过设置spm_CONF_FILE和spm_DTC_OVERLAY_FILE两个变量,我们将spm.conf和spm.overlay两个文件传给了spm image编译过程,从而达到控制spm image编译配置目的。 spm.conf我们定义如下选项:

spm.overlay我们定义如下节点:

我们再重新装载hello_world程序,可以看到在spm中,serial和uart0都关闭了,如下:

5b6885e6-48c7-11eb-8b86-12bb97331649.png

此时再去测量9160dk电流,就降到几微安了。 上面日志要不打印到串口助手,要不打印到RTT viewer,而且都是堵塞式打印。 我们现在将打印改成异步的,而且同时打印到串口助手和RTT viewer。为此我们将logging模块打开,同时设置如下Kconfig:

5be9973a-48c7-11eb-8b86-12bb97331649.png

只需做上述修改,就可以达到我们前述的目的,非常方便(无需添加文件,无需修改include目录,这就是NCS!)。这次大家可以使用nrf5340dk_nrf5340_cpuapp跑一下试试。 *注:上述日志配置直接从nrf_desktop拷贝过来,大家以后也可以参考它来使能自己的log模块。 8、NCS 编译系统几个要注意的点

°8.1 NCS几个重要的编译系统变量 在NCS或者Zephyr编译系统中,有几个变量非常重要,每个人最好掌握他们,把他们使用好,会让你的编译变得得心应手,这几个变量是:

ZEPHYR_BASE:用来指示你的Zephyr代码库的绝对目录,比如取值:C:NordicNCSSDK agv1.4.0zephyr

BOARD:用来指定编译用的板子,比如取值:nrf52840dk_nrf52840

CONF_FILE:用来指定项目的conf文件,如果没有指定,默认用prj.conf,详细说明见8.1节

DTC_OVERLAY_FILE:用来指定项目的overlay文件,如果没有指定,默认用.overlay,详细说明见8.2节

PM_STATIC_YML_FILE:用来指定parent应用,即app的pm_static文件,如果没有指定,默认用pm_static.yml,详细说明见7.1节

CMAKE_BUILD_TYPE:命令行可以通过这个变量传递一个参数给CMakelists.txt文件或者其他build过程

°上述变量量不分大小写

所以CONF_FILE和conf_file是一样的,其他类同。因为这些变量是针对每一个image的,所以每一个image都有自己的board,conf_file,dtc_overlay_file等。

对于单image应用,这个好理解也好区分。 那如果是多image应用,该如何区分每个image的conf_file和dtc_overlay_file呢? 这可以通过使用image专用变量来实现。如前所述,conf_file这个变量本身是作用于app image的,实际上你可以把这个变量看成:app_conf_file,只不过默认都是app image,所以就把app_省略了。

当你需要在parent应用中去设置child应用的conf_file,你就不能直接使用conf_file这个变量了(因为它是用来设置parent应用本身的conf文件),而需使用childImageName_conf_file。 比如上面的hello_world程序,我们使用了spm_conf_file这个变量,用来设置子image spm的conf_file。跟conf_file变量一样,dtc_overlay_file变量使用了同样的规则。NCS中目前主要有如下4个child image:

mcuboot。可升级的BootLoader

b0。不可升级的BootLoader

spm。Cortex-M33非安全应用的引导程序,Nordic自己开发的

tfm。trusted-firmware-m,作用跟spm相似,但是符合PSA标准,由第三方开发

除了上述child image,在编译nRF5340 app核的时候,我们也可以自动包含如下network核的child image:

b0n。nRF5340 network核的b0程序

hci_rpmsg。nRF5340 network核的蓝牙controller

802154_rpmsg。nRF5340 network核的802.15.4 controller

通过上面的childImage名字加上前面的编译系统变量,就可以通过parent应用去控制child应用的编译过程,大大方便了多image的开发流程。 关于上述编译系统变量的使用,大家可以参考:

nrfapplications rf_desktop

和nrfapplicationsasset_tracker

nrf_desktop虽然只有一个CMakeLists.txt,但实际上这个CMakeLists.txt包含了20多个项目。 它是怎么做到的呢? 它就是通过board和cmake_build_type这两个变量来实现的。比如要设置某一块板子对应的某一个项目的conf文件,它使用了如下语句:

5c4206e0-48c7-11eb-8b86-12bb97331649.png

比如说: $BOARD=nrf52840dk_nrf52840,$CMAKE_BUILD_TYPE=ZDebug_keyboard,那么它对应的conf文件就是如下这个:

5cbd7104-48c7-11eb-8b86-12bb97331649.png

asset_tracker的CMakeLists.txt文件定义了子image spm的conf文件,以及定义了一个静态的pm文件,如下所示:

5ce55958-48c7-11eb-8b86-12bb97331649.png

大家在写自己的multi image应用的时候,可以多借鉴上面的例子,尤其是nrf_desktop,这是一个非常全面的例子,基本上你要的功能,它都可能有参考。 °8.2 conf文件命名规则及编译顺序 如前所述,可以通过多种方法指定用户自定义Kconfig文件,除了上面讲的prj.conf,符合如下命名标准的conf文件也可以被系统自动加载进来。

首先读取CONF_FILE变量,我们可以将多个conf文件都赋给这个变量(每个conf文件之间以分号或者空格隔开),这些配置文件最终会合并成一个。我们可以通过三种方式设置CONF_FILE变量

通过命令行方式传递:-DCONF_FILE=

在CMakeLists.txt中并且必须在调用find_package(Zephyr)之前(也就是包含boilerplate.cmake之前)

通过CMake变量cache

否则,系统将使用应用目录下的prj_.conf和boards/_.conf两者的合并结果

否则,系统将使用应用目录下的prj_.conf

否则,系统将使用应用目录下的boards/.conf和prj.conf的合并结果

否则,系统将使用应用目录下的prj.conf

记住:如果同一个Kconfig选项或者符号被配置多次,以最后一次配置为准。 °8.3 overlay文件命名规则及编译顺序 系统也可以有多个overlay文件,overlay文件装载的顺序是:

首先读取DTC_OVERLAY_FILE变量,我们可以同时将多个overlay文件赋给这个变量(每个overlay文件之间以分号或者空格隔开),这些overlay文件最终合并为一个文件。我们可以通过如下方式设置DTC_OVERLAY_FILE变量

通过命令行方式传递:-DDTC_OVERLAY_FILE="file1.overlay;file2.overlay"

在CMakeLists.txt中并且必须在调用find_package(Zephyr)之前(也就是包含boilerplate.cmake之前)

否则,系统将使用应用目录下的boards/.overlay

否则,系统将使用应用目录下的.overlay

责任编辑:xj

原文标题:【Nordic博文分享系列】开发你的第一个NCS(Zephyr)应用程序

文章出处:【微信公众号:Nordic半导体】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • NCS
    NCS
    +关注

    关注

    1

    文章

    8

    浏览量

    9057
  • Nordic
    +关注

    关注

    9

    文章

    162

    浏览量

    47286

原文标题:【Nordic博文分享系列】开发你的第一个NCS(Zephyr)应用程序

文章出处:【微信号:nordicsemi,微信公众号:Nordic半导体】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    深入解析Zephyr RTOS的技术细节

    Zephyr针对资源受限设备优化的小型、可缩放、多体系架构实时操作系统(RTOS)。Zephyr由Linux基金会维护[1],是
    的头像 发表于 10-22 16:47 291次阅读
    深入解析<b class='flag-5'>Zephyr</b> RTOS的技术细节

    可以在单个esp8266上安装两NON OS SDK应用程序吗?

    ,因为整个解决方案可能很复杂。 我可以想象我会在闪光灯中出现两 iroms。此外,我相信第一个应用程序的 iram 部分位于 FLASH 的开头,并在启动后被复制。 我不确定的是,我怎样才能设法将第二
    发表于 07-19 07:28

    请问FW OTA二进制文件是否包含应用程序和BT栈/程序库?

    你好,先生: 因为英飞凌仍在不断更新 BT 栈和库。 那么 如果客户在第一个版本中有 OTA 功能。 FW OTA 二进制文件是否包含应用程序和 BT 栈/程序库?
    发表于 05-20 07:28

    鸿蒙OpenHarmony【小型系统 编写“Hello World”程序】 (基于Hi3516开发板)

    展示如何在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello World!”。
    的头像 发表于 05-10 16:26 666次阅读
    鸿蒙OpenHarmony【小型系统 编写“Hello World”<b class='flag-5'>程序</b>】 (基于Hi3516<b class='flag-5'>开发</b>板)

    鸿蒙OpenHarmony【标准系统 编写“Hello World”程序】(基于RK3568开发板)

    下方将展示如何在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello World!”。
    的头像 发表于 05-09 17:58 834次阅读
    鸿蒙OpenHarmony【标准系统 编写“Hello World”<b class='flag-5'>程序</b>】(基于RK3568<b class='flag-5'>开发</b>板)

    鸿蒙OpenHarmony【小型系统编写“Hello World”程序】 (基于Hi3516开发板)

    下方将展示如何在单板上运行第一个应用程序,其中包括新建应用程序、编译、烧写、运行等步骤,最终输出“Hello World!”。
    的头像 发表于 04-22 21:55 334次阅读
    鸿蒙OpenHarmony【小型系统编写“Hello World”<b class='flag-5'>程序</b>】 (基于Hi3516<b class='flag-5'>开发</b>板)

    求助,用CubeMX配置占空比30%的PWM输出第一个波形不准确是为什么?

    我用的是G0的芯片配置,通过抓波发现第一个波形永远与我配置的占空比不准确,但是除了第一个周期不准确外,后面的都没问题。
    发表于 03-18 07:55

    瑞萨正式加入Zephyr项目

    开发人员进行部署和管理。   Zephyr RTOS拥有套不断扩展的软件库,可用于各种应用和产业领域,例如工业物联网、可穿戴设备、机器学习等。它侧重于广泛的芯片组支持、安全性、可靠性、长期支持版本和不断扩展的开源生态系统。瑞
    的头像 发表于 03-09 17:43 1800次阅读

    全志D1s裸机开发之体验第一个程序

    体验第一个程序 2.1 编译烧录运行 2.1.1编译 先进入源码目录,打开 Git Bash,如下图操作: 然后在 Git Bash 中执行 make 命令,可以生成
    发表于 03-08 11:43

    如何在Zephyr OS中使用cyhal?

    直在使用Zephyr和 CY8CPROTO-063-BLE 模块,我需要实现高速SPI驱动器。 不幸的是,Zephyr 驱动
    发表于 01-29 07:12

    Harvard FairSeg:第一个用于医学分割的公平性数据集

    为了解决这些挑战,我们提出了第一个大规模医学分割领域的公平性数据集, Harvard-FairSeg。该数据集旨在用于研究公平性的cup-disc segmentation,从SLO眼底图像中诊断青光眼,如图1所示。
    的头像 发表于 01-25 16:52 513次阅读
    Harvard FairSeg:<b class='flag-5'>第一个</b>用于医学分割的公平性数据集

    世界上第一个石墨烯半导体的“石墨烯”究竟是什么?

    有媒体报道称有研究团队创造了世界上第一个由石墨烯制成的功能半导体(Functional Graphene Semiconductor)。
    的头像 发表于 01-23 11:26 1147次阅读

    如何构建linux开发环境和编译软件工程、应用程序

    前文介绍了如何使用官方提供的镜像文件启动开发板,本文将说明如何构建linux开发环境和编译软件工程、应用程序
    的头像 发表于 01-03 12:31 1937次阅读
    如何构建linux<b class='flag-5'>开发</b>环境和编译软件工程、<b class='flag-5'>应用程序</b>

    【从0开始创建AWTK应用程序】创建应用程序并在模拟器运行

    。创建工程本篇文章我们来创建第一个AWTK程序,也就是HelloWorld程序,它总共包含两页面,先来看下最终效果图:图1Hello工程两
    的头像 发表于 12-01 08:24 465次阅读
    【从0开始创建AWTK<b class='flag-5'>应用程序</b>】创建<b class='flag-5'>应用程序</b>并在模拟器运行

    开发java应用程序的基本步骤是

    ava是种面向对象的编程语言,广泛用于开发各种类型的应用程序。在开发Java应用程序时,有
    的头像 发表于 11-28 16:52 1523次阅读