Zephyr 下 nRF9160 DK 开发指南:TrustZone 安全分区、双芯片协同与信号路由配置
2026/9/19 13:48:12 网站建设 项目流程

Zephyr 下 nRF9160 DK 开发指南:TrustZone 安全分区、双芯片协同与信号路由配置

【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr

本文以 Zephyr RTOS 仓库中 nRF9160 DK 板级文档 为核心骨架,系统讲解在 Zephyr 中为 nRF9160 DK(PCA10090)开发固件的完整流程,包括基于 Armv8-M Security Extensions(TrustZone)的 Secure/Non-Secure 双镜像构建方案、nRF9160 与板载 nRF52840 两颗芯片的协同开发,以及通过 devicetree 控制板载模拟开关实现引脚信号路由的具体方法。读完本文,你将能够独立完成 nRF9160 DK 的 Zephyr 应用构建、烧录、调试与板级外设路由配置。

nRF9160 DK(图片来源:Nordic Semiconductor)

板卡概览:一颗 SiP、两颗芯片、三套板级配置

nRF9160 DK(PCA10090)是面向 LTE-M 与 NB-IoT 蜂窝物联网场景的单板开发套件。Zephyr 仓库中boards/nordic/nrf9160dk目录下同时提供三套板级配置,覆盖板上的两颗芯片:

  • nrf9160dk/nrf9160:基于 Nordic nRF9160 SiP,核心为 ARM Cortex-M33F CPU,支持 ARMv8-M Security Extensions(安全扩展),是 LTE-M/NB-IoT 应用的主控。
  • nrf9160dk/nrf9160/ns:同一颗 nRF9160 的 Non-Secure(非安全)变体配置,用于构建运行在 TrustZone 非安全世界中的 Zephyr 固件。
  • nrf9160dk/nrf52840:板载的 nRF52840 SoC(ARM Cortex-M4F),承担低功耗蓝牙(BLE)、802.15.4、USB 等接口 MCU(interface MCU)职责。

板卡型号与 SoC 变体关系定义在 board.yml 中,其中明确声明了 nrf9160 的ns变体,以及板卡硬件版本(revision)体系major.minor.patch,默认版本为0.14.0,同时支持0.7.00.14.0两个版本。

板级硬件要点

  • 板载两颗外部晶振:慢时钟 32.768 kHz,主时钟 32 MHz。
  • 从 v0.14.0 版本开始,DK 新增两块额外硬件:
    • 外部 Flash 存储器 MX25R6435F(64 Mb);
    • I/O 扩展器 PCAL6408A,可用于扩展 LED、拨动开关(slide switch)与按键的接口能力。

这些额外硬件默认未启用。要使用它们,需要在构建时显式指定板卡硬件版本,例如构建 nRF9160 DK v1.0.0 目标:

west build -b nrf9160dk/nrf9160@1.0.0

同时,还需要在 nRF52840 的固件中启用对应信号的路由(详见下文"板控制器固件与模拟开关路由"一节),否则额外硬件不会真正接入 nRF9160 SiP。

连接与 IO 映射

nRF9160 DK 板上 LED、按键与开关的引脚连接关系如下(对应 devicetree 实现见 nrf9160dk_nrf9160_common.dtsi):

外设引脚
LED1(绿色)P0.2
LED2(绿色)P0.3
LED3(绿色)P0.4
LED4(绿色)P0.5
BUTTON1P0.6
BUTTON2P0.7
SWITCH1P0.8
SWITCH2P0.9
BOOT = SW5启动/复位

值得留意的是,nRF9160 DK 与大多数 Nordic DK 不同,它只有 2 个按键和 2 个开关。为了遵循 Zephyr 社区"每个 DK 板 4 个按钮"的惯例,nrf9160dk_nrf9160_common.dtsi 将两个开关也以gpio-keys节点暴露为button2/button3SWITCH1INPUT_KEY_2SWITCH2INPUT_KEY_3),这样依赖标准按钮语义的示例与上层软件可以无缝工作。所有按钮节点均配置为GPIO_PULL_UP | GPIO_ACTIVE_LOW,并提供了sw0~sw3led0~led3等兼容别名。

安全组件:IDAU 与安全启动

nRF9160 DK 在安全方面的两个关键组件:

  • IDAU(Implementation Defined Attribution Unit):nRF9160 使用 System Protection Unit(SPU)实现 IDAU,用于划分安全(Secure)与非安全(Non-Secure)内存映射。默认情况下,全部内存空间(Flash、SRAM 与外设地址空间)均被定义为仅安全访问。
  • 安全启动(Secure boot):板卡支持从安全状态引导系统。

因此,nrf9160dk/nrf9160 配置默认在 Secure 状态下启动,这一点是理解下文所有构建流程的前提。

使用 Arm TrustZone 构建 Secure/Non-Secure 应用

nRF9160 上的应用可能同时包含一个 Secure 固件镜像和一个 Non-Secure 固件镜像:

  • Secure 镜像可以由 Zephyr 构建,也可以使用 Trusted Firmware-M(TF-M)构建;
  • Non-Secure 固件镜像总是由 Zephyr 构建。

默认情况下,nRF9160 的 Secure 镜像使用 TF-M 构建。

方式一:Secure 固件由 Zephyr 构建

整个流程分为三步:

  1. 使用-DBOARD=nrf9160dk/nrf9160构建 Secure Zephyr 应用,并在应用的项目配置文件中启用CONFIG_TRUSTED_EXECUTION_SECURE=y
  2. 使用-DBOARD=nrf9160dk/nrf9160/ns构建 Non-Secure Zephyr 应用;
  3. 将两个二进制镜像合并。

Secure 侧相关的板级配置可以在 nrf9160dk_nrf9160_defconfig 中看到,它启用了CONFIG_ARM_MPUCONFIG_ARM_TRUSTZONE_M、GPIO、UART 驱动与控制台;Non-Secure 侧的默认配置见 nrf9160dk_nrf9160_ns_defconfig,额外启用CONFIG_TRUSTED_EXECUTION_NONSECURE=y表明该配置用于构建非安全固件。

Secure 与 Non-Secure 镜像的内存划分由各自的 devicetree 决定:

  • Secure 配置 nrf9160dk_nrf9160.dts 选择sram0_s作为安全 SRAM 分区、slot0_partition作为代码分区,并同时声明sram-secure-partitionsram-non-secure-partition
  • Non-Secure 配置 nrf9160dk_nrf9160_ns.dts 使用sram0_ns_app作为运行 SRAM、slot0_ns_partition作为代码分区,并默认禁用uart1——因为该串口被 TF-M 占用。

方式二:Secure 固件使用 TF-M 构建

此方式只需构建 Non-Secure Zephyr 应用,构建系统会自动完成其余工作:

  1. 使用-DBOARD=nrf9160dk/nrf9160/ns构建 Non-Secure Zephyr 应用(命令中的板名写为nrf9160dk_nrf9160_ns亦可);
  2. Zephyr 构建系统会因 Kconfig 选项BUILD_WITH_TFM(构建 Non-Secure 应用时默认启用)自动执行:
    • 将 Non-Secure 固件镜像作为常规 Zephyr 应用构建;
    • 构建 TF-M(Secure)固件镜像;
    • 合并输出二进制文件;
    • 可选地构建引导加载程序镜像(MCUboot)。

注意:根据 TF-M 的具体配置,可能需要为应用提供 DTS overlay,以调整 Non-Secure 镜像在 Flash 与 SRAM 中的起始地址及大小。

无论采用哪种方式,构建 Secure/Non-Secure 应用时,Secure 应用都必须提前配置 IDAU(SPU),允许 Non-Secure 访问 Non-Secure 固件所使用的全部 CPU 资源;SPU 配置必须在跳转到 Non-Secure 应用之前完成。

构建纯 Secure 应用

如果不需要 Non-Secure 世界,只需按常规方式构建 Zephyr 应用,使用-DBOARD=nrf9160dk/nrf9160即可。

烧录与调试

烧录前需要按照 Nordic 板卡的 Segger 工具链流程安装并配置必要的软件(J-Link 软件与驱动)。完成环境准备后即可按常规流程构建并烧录应用。

hello_world示例为例,先在终端中监听串口输出:

$ minicom -D <tty_device> -b 115200

<tty_device>替换为 nRF9160 DK 对应的端口,在 Linux 下通常是/dev/ttyACM0。然后构建并烧录:

$ west build -b nrf9160dk/nrf9160 samples/hello_world $ west flash

调试方面,参考 Nordic 板卡的 Segger IC 调试说明(nordic_segger文档)即可,nRF9160 DK 板载调试器支持 J-Link 全功能调试。

验证板载 LED 与按键:blinky 与 button 示例

Zephyr 为验证 nRF9160 DK 的按键(开关)与 LED 是否工作正常提供了两个现成示例:

  • samples/basic/blinky:让 LED 周期性闪烁,验证 GPIO 输出通路;
  • samples/basic/button:读取按键/开关输入,验证 GPIO 输入通路。

构建并烧录这两个示例,可以快速确认 Zephyr 在板卡上运行正常。LED 与按键的完整 devicetree 定义位于 nrf9160dk_nrf9160_common.dtsi。

nRF52840 板级配置

nRF9160 DK 上的 nRF52840 SoC 提供以下外设支持:

  • CLOCK(时钟)
  • FLASH
  • GPIO
  • MPU(内存保护单元)
  • NVIC(嵌套向量中断控制器)
  • PWM
  • RADIO(低功耗蓝牙与 802.15.4)
  • RTC(nRF RTC 系统时钟)
  • Segger RTT(RTT 控制台)
  • UART
  • WDT(看门狗定时器)

需要特别强调的是:nRF52840 SoC 与板上的 LED、按键、开关以及 Arduino 排针没有任何物理连接。不过,nRF52840 的部分引脚可以通过模拟开关路由到 nRF9160 SiP,实现两颗芯片之间的互联(这正是下文"板控制器固件"的用武之地)。

nRF52840 配置的 devicetree 见 nrf9160dk_nrf52840.dts,其中chosen节点将zephyr,bt-mon-uartzephyr,ieee802154指向 nRF52840 的 UART0 与 802.15.4 无线电,ieee802154节点默认启用。

构建、烧录与调试 nRF52840 应用

nrf9160dk/nrf52840配置构建和烧录应用的方式与常规 Zephyr 应用相同,但有一个关键前提:必须将 DK 上的 PROG/DEBUG 开关拨到 nRF52 位置

hello_world为例:

$ minicom -D <tty_device> -b 115200

Linux 下 nRF52840 通常对应/dev/ttyACM1——注意/dev/ttyACM0连接的是板上的 nRF9160 SiP。随后构建并烧录:

$ west build -b nrf9160dk/nrf52840 samples/hello_world $ west flash

调试方式同前(Segger J-Link),并记得再次确认 PROG/DEBUG 开关位于 nRF52 位置。

板控制器固件与模拟开关路由

板控制器固件的作用

板控制器固件是一小段运行在 nRF52840 上的代码,负责将 nRF9160 SiP 的特定引脚路由到 DK 上的不同组件,包括 LED、按键、接口 MCU 的 UART 接口(VCOMx)以及 nRF52840 的特定引脚。

  • 当为nrf9160dk/nrf52840编译工程时,板控制器固件会在内核初始化完成后自动编译并运行;
  • 在早于 v0.14.0 的 DK 版本上,被路由到其他组件的 nRF9160 信号无法同时在 DK 连接器上使用(即信号被独占路由)。

默认路由表

板控制器固件默认执行的路由如下:

nRF9160 引脚路由到
P0.26、P0.27、P0.28、P0.29VCOM0
P0.01、P0.00、P0.15、P0.14VCOM2
P0.02LED1
P0.03LED2
P0.04LED3
P0.05LED4
P0.08Switch 1
P0.09Switch 2
P0.06Button 1
P0.07Button 2
P0.17、P0.18、P0.19Arduino 排针
P0.21、P0.22、P0.23Trace 接口
COEX0、COEX1、COEX2COEX 接口

通过 devicetree 节点控制路由

如果希望改变上述路由或启用其他可用路由,只需启用或禁用代表对应模拟开关的 devicetree 节点即可。板控制器固件的实现见 board.c:它在board_late_init_hook()中遍历所有routing_switches,根据每个节点在 devicetree 中的statusokay/disabled)将对应control-gpios配置为输出有效或无效电平,从而闭合或断开模拟开关;当外部 Flash 路由节点存在时,还会在board_early_init_hook()中尽早闭合对应开关,保证 Flash 的 HOLD 引脚被正确上拉。

模拟开关节点的 devicetree 绑定定义在 nordic,nrf9160dk-optional-routing.yaml,核心属性为control-gpios(控制模拟开关的 GPIO)。

DK 上定义的模拟开关节点与物理开关对应关系如下:

Devicetree 节点标签模拟开关名称
vcom0_pins_routingnRF91_UART1 (nRF91_APP1)
vcom2_pins_routingnRF91_UART2 (nRF91_APP2)
led1_pin_routingnRF91_LED1
led2_pin_routingnRF91_LED2
led3_pin_routingnRF91_LED3
led4_pin_routingnRF91_LED4
switch1_pin_routingnRF91_SWITCH1
switch2_pin_routingnRF91_SWITCH2
button1_pin_routingnRF91_BUTTON1
button2_pin_routingnRF91_BUTTON2
nrf_interface_pins_0_2_routingnRF_IF0-2_CTRL (nRF91_GPIO)
nrf_interface_pins_3_5_routingnRF_IF3-5_CTRL (nRF91_TRACE)
nrf_interface_pins_6_8_routingnRF_IF6-8_CTRL (nRF91_COEX)

当构建 DK 0.14.0 或更新版本时,还可以使用以下额外节点(通过-DBOARD=nrf9160dk/nrf9160@<版本>指定板卡版本):

Devicetree 节点标签模拟开关名称
nrf_interface_pin_9_routingnRF_IF9_CTRL
io_expander_pins_routingIO_EXP_EN
external_flash_pins_routingEXT_MEM_CTRL

路由配置实战示例

示例 1:启用可选路由,将 nRF9160 的 P0.17、P0.18、P0.19 分别路由到 nRF52840 的 P0.17、P0.20、P0.15。在应用的 devicetree overlay 中添加:

&nrf_interface_pins_0_2_routing { status = "okay"; };

示例 2:禁用 VCOM2 引脚的路由:

&vcom2_pins_routing { status = "disabled"; };

从 nrf9160dk_nrf52840.dts 的board-control节点可以看到这些开关的实际control-gpios定义:例如vcom0_pins_routing由 P1.14(低电平有效)控制,vcom2_pins_routing需要同时驱动 P1.12 与 P0.12 两个引脚,而nrf_interface_pins_0_2_routingnrf_interface_pins_3_5_routingnrf_interface_pins_6_8_routing默认均为disabled

双芯片 UART 通信的快捷配置

boards/nordic/nrf9160dk/dts/nrf52840boards/nordic/nrf9160dk/dts/nrf9160两个目录下提供了若干辅助.dtsi文件,它们既可作为配置路由的参考示例,也可以直接从应用 overlay 中 include,快速实现 nRF9160 与 nRF52840 之间的信号路由。例如,要让两颗芯片通过各自的uart1互连通信:

nRF52840 侧的 overlay:

#include <nrf52840/nrf9160dk_uart1_on_if0_3.dtsi>

nRF9160 侧的 overlay:

#include <nrf9160/nrf9160dk_uart1_on_if0_3.dtsi>

以 nrf9160dk_uart1_on_if0_3.dtsi 为例,它定义了uart1_default_alt备用引脚组合(TX=P0.18、RX=P0.17、RTS=P0.21、CTS=P0.19),并将uart1的状态置为okay,同时挂载default/sleep两组 pinctrl 状态。结合nrf_interface_pins_0_2_routing等模拟开关节点,即可在硬件层面打通 nRF9160 与 nRF52840 之间的 UART 通路。

小结

围绕 nRF9160 DK,Zephyr 提供了从安全启动、TrustZone 双镜像构建到双芯片路由控制的完整支撑:nrf9160dk/nrf9160nrf9160dk/nrf9160/ns配置分别对应 Secure/Non-Secure 世界,配合CONFIG_TRUSTED_EXECUTION_*与 TF-M 可灵活组织安全固件;nrf9160dk/nrf52840配置配合板控制器固件,通过 16 个模拟开关节点实现了 nRF9160 SiP 与板载外设、nRF52840 之间的可编程信号路由。开发者只需在 devicetree overlay 中设置对应节点的status,即可按需打通 VCOM、LED、按键、Arduino 排针乃至双芯片 UART 通信链路,为 LTE-M/NB-IoT + BLE 组合场景提供便捷的硬件基础。

【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询