【Nordic博文分享系列】理解Zephyr编译与配置系统(下)

Nordic半导体 2025-02-25 17:01




转载自:cnblogs.com |作者:Jayant Tang

Zephyr Project是Linux基金会推出的一个Apache2.0开源项目,版权非常友好,适合用于商业项目开发。包含RTOS、编译系统、各类第三方库。NCS中的例程基本都跑在Zephyr RTOS上。

对于之前只接触过IDE+外设驱动库这种开发方式的开发者来说,Zephyr的配置和编译系统可能比较令人费解,但是一旦你能掌握,就会发现它的方便之处。

本文接上篇内容,将继续介绍NCS中的配置和编译工具,包含Zephyr中特有的Sysbuild、Boards,以及Nordic提供的Partition Manager存储器分区等介绍。

【Nordic博文分享系列】理解Zephyr编译与配置系统(上)




Sysbuild (System build)

前面介绍的CMake, Kconfig, DeviceTree都是其他领域(如Linux内核)已经在广泛使用的配置工具。但是Sysbuild是Zephyr的新引入的构建机制,它是一个High-Level的配置工具,解决的是MCU多镜像编译的问题。

前面介绍的那些工具,都是为了1个镜像编译时用的。当我们要编译一个多镜像的固件时,这些不同的镜像之间可能会有一些配置项的差别。

例如,我希望我的串口用于打印日志,但是在bootloader镜像中,同一个串口用于固件升级。

又比如,我选型了一款QSPI外挂Flash,与Nordic官方开发板上的Flash不同,于时我修改了我的工程中的overlay文件。但是,我也需要在某个地方修改bootloader工程的overlay文件,从而让bootloader也识别我的flash。

以上说的是运行在同一个CPU上,不同镜像之间的差异配置。除此之外,还有运行在不同CPU上,不同镜像之间的相同配置,例如双核MCU上的App Core和Net Core,我希望同时配置为debug模式或release模式,而不是单独去调。


1

Sysbuild的开关

编译时可以决定是否使用Sysbuild

west build --sysbuild
west build --no-sysbuild

在NCS v2.7.0之后,west build命令默认就是开启--sysbuild的。在NCS v2.6.x之前,则默认不开启。


2

命名空间(Namespace)

在多镜像编译的场景下,我们用west build进行命令行编译时,如果要添加一些配置项,则可能需要指定,这个配置项是属于哪个子工程的,或者是属于整体的(Sysbuild)。

# 带有Namespace的Kconfig-D<namespace>_CONFIG_=
# 带有Namespace的CMake选项-D<namespace>_=

例如:

west build -b reel_board --sysbuild samples/hello_world \  -- \    -DSB_CONFIG_BOOTLOADER_MCUBOOT=y \    -DCONFIG_DEBUG_OPTIMIZATIONS=y \    -Dmcuboot_CONFIG_DEBUG_OPTIMIZATIONS=y# 给Sysbuild(全局)传递CONFIG_BOOTLOADER_MCUBOOT=y,表示使用bootloader作为MCUBOOT,命名空间为SB# 给当前默认Application工程传递CONFIG_DEBUG_OPTIMIZATIONS=y,命名空间为空# 给mcuboot工程传递CONFIG_DEBUG_OPTIMIZATIONS=y,命名空间为mcuboot,也就是子工程的名称


3

Sysbuild配置文件

除了上述在编译时传递编译选项的方法,也可以保存Sysbuild级别的配置文件

application/├── ...├── CMakeLists.txt # application的CMake├── prj.conf       # application的配置项├── ...├── Kconfig.sysbuild # Sysbuild全局级别的Kconfig菜单定义。可以不定义,不定义时使用SDK内的默认菜单├── sysbuild.conf    # Sysbuild全局配置项├── ...├── sysbuild.cmake   # Sysbuild全局级别的CMake。可以用来管理有哪些工程镜像参与总镜像的编译├── ...└── sysbuild/         # Sysbuild目录下,可以分别给每个子工程单独进行配置    └── mcuboot                   ├── prj.conf        ├── app.overlay        └── boards            ├── .conf            ├── .overlay            ├── .conf            └── .overlay

关于sysbuild的例程,可以参考zephyr/samples/sysbuild/下的几个例程。

4

Sysbuild配置文件

参考zephyr/samples/sysbuild/hello_world,这个工程是给双核MCU运行使用的。App核运行一个Hello World,然后同时再添加一个Hello World工程给另一个核使用。最后编译出双镜像固件。

要给当前工程添加子工程,其实就是修改sysbuild.cmake。

ExternalZephyrProject_Add(  APPLICATION my_sample                 # 要添加的工程名  SOURCE_DIR /my_sample        # 要添加的工程路径  BOARD mps2_an521_remote               # 如有必要,单独指定要添加的工程使用的board  BUILD_ONLY TRUE                       # 如有必要,可以只编译不烧录)
# 要先编译my_sample,再编译当前默认application工程sysbuild_add_dependencies(CONFIGURE ${DEFAULT_IMAGE} my_sample)# 等价于以下CMake标准函数add_dependencies(${DEFAULT_IMAGE} my_sample)
# 要先烧录my_sample,再烧录当前application工程sysbuild_add_dependencies(FLASH ${DEFAULT_IMAGE} my_sample)# 如果my_sample配置为BUILD_ONLY=TRUE,则会报错

特别地,如果要添加的工程就是MCUBOOT,则只需在sysbuid.conf中添加下列配置即可:

SB_CONFIG_BOOTLOADER_MCUBOOT=y

因为SDK中已经把MCUBOOT相关的sysbuild写好了,这里直接使能即可。





【已抛弃】parent-child image

在NCS v2.6.x及之前的版本中,多镜像的管理靠的是parent-child image。这个工具不是Zephyr的,而是Nordic的。它也能在一个子文件夹里分别管理子镜像的配置。但它和Sysbuild的区别在于:它没有单独的High-Level的全局配置。这导致一些实际上应该属于全局的配置,直接放在了Application层的配置中(例如选择哪个Bootloader),因此偶尔会产生混淆。

如使用老版本的NCS,建议参考老版本NCS关于这方面的文档:https://docs.nordicsemi.com/bundle/ncs-2.7.0/page/nrf/config_and_build/multi_image.html





存储器分区文件
Partition Manager

管理一个MCU的存储器分区是很常见的需求。不仅在多镜像、OTA的场景下要管理,在内部和外部flash上挂载文件系统、用单独的分区存储生产信息等等场景下都要管理。

存储器分区文件,尤其是带有外部flash的,可以参考Matter例程,例如nrf/samples/matter/lock。你可以看到很多pm_static_xxx.yml:


mcuboot:  address: 0x0  size: 0x7000  region: flash_primarymcuboot_pad:  address: 0x7000  size: 0x200app:  address: 0x7200  size: 0xefe00mcuboot_primary:  orig_span: &id001  - mcuboot_pad  - app  span: *id001  address: 0x7000  size: 0xf0000  region: flash_primarymcuboot_primary_app:  orig_span: &id002  - app  span: *id002  address: 0x7200  size: 0xefe00factory_data:  address: 0xf7000  size: 0x1000  region: flash_primarysettings_storage:  address: 0xf8000  size: 0x8000  region: flash_primarymcuboot_secondary:  address: 0x0  size: 0xf0000  device: MX25R64  region: external_flashexternal_flash:  address: 0xf0000  size: 0x710000  device: MX25R64  region: external_flash

详细的语法无需在意,不同工程基本都是大同小异的。

注意:配置Partition Manager时,一定要注意对齐Flash的Page!!!


1

静态分区文件说明

mcuboot相关

mcuboot相关照抄即可,只需修改地址和大小。

  • mcuboot:也就是mcuboot的固件大小。Matter的MCUBOOT配置是SDK中专门优化过的,因此只需要0x7000字节。一般来说自己添加一个需要0xc000的空间

  • mcuboot_pad:DFU期间,存储一些固件升级情况的标志位和校验信息

  • mcuboot_primary:也就是app所在的slot,同时也有mcuboot_pad。

  • mcuboot_secondary:也就是升级时新固件存放的slot。通常app负责接收新固件,然后跳转到mcuboot,mcuboot进行分区固件交换后,升级完成。secondary slot也可以放到外部flash

app相关

app相关照抄即可,只需修改地址和大小。

  • app与mcuboot_primary_app:都是app分区

settings_storage

settings_storage是Zephyr系统中一个存储配置项的分区,是一个简易的文件系统。可以用“字符串”(通常是文件路径,例如id/serial)作为句柄来存取数据(提供首地址、长度)。

Zephyr中许多的Librarys都依赖Settings来存储持久化数据,例如蓝牙的绑定密钥。因此这个分区非常常见。考虑到用到Settings的组件非常多,最好不要把Settings放到外部flash,不然做外部flash低功耗时,如果外部flash休眠了,而某个组件要用到Settings,就会报错,非常麻烦。

由于Settings是文件系统,因此它不是把数据单一的存在一个地址,而是像硬盘一样一直向后写,直到分区flash写满了,才把前面的page全部擦掉做垃圾回收。因此最好给settings_storage准备至少2个page的flash空间(上面的例子是0x8000,为两个4kB的page)。如果在特定极端峰值情况下,flash读写非常快且数量多,则需要3个page或以上。例如HomeKit认证时的循环蓝牙绑定16次测试,需要3个page。

其他分区

其他分区没有什么特别的,就是用一个label定义一个分区名称。

  • factory_data:在Matter工程中,用于存储证书等数据的分区。

  • external_flash:外部flash空余的位置,随意进行了一个命名。

其实Partition Manager只是一套脚本,最终还是要落实到C代码。在代码中,可以通过label来访问这些分区。例如Matter的SDK中就会通过factory_data来访问认证证书等数据。

你也可以充分利用这个未使用的分区。用nrf/include/flash_map_pm.h中定义的宏函数,来吧这些label转化成Zephyr可以使用的Flash Device句柄和分区句柄。例如把这个external_flash分区拿来建立NVS文件系统。

#include 
#define NVS_PARTITION    external_storage#define NVS_PARTITION_DEVICE  FIXED_PARTITION_DEVICE(NVS_PARTITION)#define NVS_PARTITION_OFFSET  FIXED_PARTITION_OFFSET(NVS_PARTITION)
#include
static struct nvs_fs fs;
int app_nvs_entry(void){    int rc = 0;  char buf[16];  uint8_t key[8], longarray[128];  uint32_t reboot_counter = 0U;  struct flash_pages_info info;
 /* define the nvs file system by settings with:   *  sector_size equal to the pagesize,   *  3 sectors   *  starting at NVS_PARTITION_OFFSET   */  fs.flash_device = NVS_PARTITION_DEVICE;  if (!device_is_ready(fs.flash_device)) {    LOG_ERR("Flash device %s is not ready", fs.flash_device->name);    return 0;  }  fs.offset = NVS_PARTITION_OFFSET;  rc = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info);  if (rc) {    LOG_ERR("Unable to get page info");    return 0;  }
 fs.sector_size = info.size;  fs.sector_count = PAGE_COUNT;
   LOG_INF("NVS sector size: %d, sector count: %d", fs.sector_size, fs.sector_count);
 rc = nvs_mount(&fs);  if (rc) {    LOG_ERR("Flash Init failed");    return 0;  }    ...}

值的一提的是,根据nrf/include/flash_map_pm.h中的定义,当使用以下三种文件系统时,最好就使用那个名字作为label

  • settings_storage

  • littlefs_storage

  • nvs_storage


2

外部Flash分区

当某个分区位于外部Flash时,这个分区需要配置:

region: external_flashdevice: MX25R64

其中device是需要在设备树中配置的,要让partition manager知道外部flash是哪个设备,比如这里是mx25r64这个节点:

/ {  chosen {    nordic,pm-ext-flash = &mx25r64;  };};

如果Bootloader也需要访问外部flash,不要忘记在mcuboot中也添加以上配置。

除此之外,还要注意。如果不得已要把文件系统放在外部flash,一定要使能对应的配置,例如:

  • CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL

  • CONFIG_PM_PARTITION_REGION_SETTINGS_STORAGE_EXTERNAL

  • CONFIG_PM_PARTITION_REGION_NVS_STORAGE_EXTERNAL

并且这些配置是,只有当你用Nordic的QSPI Flash驱动时(compatible = "nordic,qspi-nor")才有作用的。

更多使用外部flash的细节,见文档。
https://docs.nordicsemi.com/bundle/ncs-2.9.0/page/nrf/app_dev/bootloaders_dfu/mcuboot_nsib/bootloader_partitioning.html#ug-bootloader-external-flash


3

动态分区

实际上Partition Manager还支持根据不同子工程编译的大小动态分区。但是动态分区对于实际的项目来说没有任何意义,实际项目一定都需要静态分区,才能确保固件升级(DFU)的正确性。

如需了解更多,参考Partition Manager文档。

https://docs.nordicsemi.com/bundle/ncs-2.9.0/page/nrf/scripts/partition_manager/partition_manager.html

4

检查Partition Manager是否开启

要检查自己是否开启了Partition Manager,检查编译后的.config中有无:

CONFIG_PARTITION_MANAGER_ENABLED=y

不要主动去设置它,一般来说开启多镜像编译后,它就会自动使能。


5

用CMake变量指定分区文件

通常来说,编译时会自动选择项目根目录下的pm_static_.yaml文件。

但是如果你的项目比较复杂,希望用CMake变量来指定Partition Manager文件,类似于指定CONF_FILE配置文件那种方式,则需要在Sysbuild级别的配置sysbuild.cmake中进行设置,变量为PM_STATIC_FILE。

sysbuild.cmake

set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_LIST_DIR}/foo/bar/pm_static.yml CACHE INTERNAL "")





Zephyr中的“Boards”

在Zephyr中,Boards是非常重要的一个概念。直观地理解,它指的就是你开发的项目的PCB板子。Zephyr中有很多可选择的Boards,都是各个厂商或提交给Zephyr的。在编译时必须选择一个Boards。

但看完前面的介绍,我们就可以更深入地理解Boards:它其实就是一堆默认的Kconfig,DeviceTree配置文件的集合。


1

Boards默认配置文件

当我们选择nrf52840dk/nrf52840时,就会导入SDK中${NCS}/zephyr/boards/nordic/nrf52840dk/目录下的各种配置文件。这其中,nrf52840dk是板子的名称,nrf52840是SoC的名称。

其中,Kconfig配置文件是nrf52840dk_nrf52840_defconfig;DeviceTree文件是nrf52840dk_nrf52840.dts。其余.dts或.dtsi文件是被它include的。例如,引脚分配文件nrf52840dk_nrf52840-pinctrl.dtsi。

当编译时,选择nrf52840dk/nrf52811时,它是用nrf52840这颗芯片来模拟nrf52811的资源,让你也可以用nRF52840DK这个开发板来进行nRF52811的开发。


2

Board Name

Boards是为了编译固件而服务的。因此board name中一定包含编译目标所需要的信息。

示例:

  • nrf52840dk/nrf52840:为nRF52840DK开发板上的nRF52840这颗SoC芯片编译固件

  • nrf5340dk/nrf5340/cpuapp:为nRF5340DK开发板上的nRF5340这颗双核芯片的App核编译固件

  • nrf54l15/cpuapp/ns:为nRF554L15DK开发板上的nRF54L15这颗双核芯片的App核编译固件,并且选择非安全(non-secure)地址空间进行编译。

完整示例:


nrf54l15dk@1.0.0/nrf54l15/cpuapp/ns:

nrf54l15dk

板子名称

@1.0.0

板子版本

(常见于工程样片版本)

/nrf54l15

Board qualifier 
for SoC

/cpuapp

Board qualifier
for CPU cluster

/ns

Board qualifier 
for variant

老版本板子名称

前面介绍的都是Zephyr的Hardware Model v2。在板子、SoC、CPU之间有层级关系。

在NCS v2.6.x之前,用的是没有层级关系的板子名称。例如:

nrf52840dk_nrf52840和nrf52840dk_nrf52811被认为是两块不同的板子。

当然你也可以简单理解为,Hardware Model v2就是简单把下划线_换成了斜杠/。



3

CMake中使用Boards变量

可能你需要在CMake中根据Board来配置不同的文件。

  • ${BOARDS}:板子名,例如:
    nrf52840dk,`nrf54l15dk``

  • ${BOARD_QUALIFIERS}:后缀,例如:
    /nrf52840,/nrf54l15/cpuapp/ns

比如,在sysbuild.cmake中,根据不同的board来使用不同的Partition Manager配置文件:

# 多镜像分区配置# 在sysbuild.cmake中配置,以下配置会追加到所有子工程的CMakeLists.txt中
## Partition managerif (EXISTS "${CMAKE_CURRENT_LIST_DIR}/configurations/${BOARD}${BOARD_QUALIFIERS}/pm_static.yml")    message(STATUS "Using Partition Manager file: ${CMAKE_CURRENT_LIST_DIR}/configurations/${BOARD}${BOARD_QUALIFIERS}/pm_static.yml")    set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_LIST_DIR}/configurations/${BOARD}${BOARD_QUALIFIERS}/pm_static.yml CACHE INTERNAL "")else()    message(FATAL_ERROR "Can't find Partition Manager configurations (${CMAKE_CURRENT_LIST_DIR}/configurations/${BOARD}${BOARD_QUALIFIERS}/pm_static.yml)")endif()

这里${BOARD}${BOARD_QUALIFIERS}拼接起来,对应的就是配置文件目录层级:



4

自定义板子

如果你的项目比较简单,可以不用自定义板子。直接选择Nordic开发板作为基础的Board。然后用device tree overlay文件和Kconfig配置文件,来增、删、改配置。

但是定义自己的板子会有许多好处,比如:

  • 让一个工程同时支持自己的Borad和开发板。debug时,可以对比开发板和自己的板子的表现。在排查硬件问题,进行功耗优化时非常有用。

  • 用同一块板子开发不同工程时,移植非常方便。

  • 你选择的芯片封装和开发板上的封装并不相同,引脚数量有区别,需要自定义board。

自定义板子的步骤

也可以参考官方文档
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/board_support/defining_custom_board.html

创建Board

可以在VS Code中图形化操作,定义板子:


输入板子名称,是给人阅读的字符串,可以带空格:


输入板子名称,是编译时使用的名称,不能带空格:

选择使用的NCS版本:

选择SoC芯片:

选择自己的boards相关文件存放的位置,通常就是当前project根目录即可。

输入公司名称,作为vendor字段:

创建完毕后,就存放在当前工程的boards目录下:


添加默认Kconfig

默认的config就是你的_defconfig:

可以按需求拷贝开发板的默认配置,参考${NCS-2.8.0}/zephyr/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig

以上是添加默认的配置值。如果你想增加这个板子的菜单可选项,可以在Konfig.中添加你的菜单项。

值得一提的是,如果你的板子上没有32.768kHz晶振,则需要使用内部RC震荡器。可以把内部晶振相关配置写到这个defconfg中

CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=yCONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=nCONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=y

但是,在成本允许的情况下,还是非常推荐使用外部32k晶振的。外部晶体相比于内部RC震荡器具有更高的温度稳定性。此外,内部RC震荡器需要经常用高频时钟进行校准,因此功耗也会更高。


添加默认设备树配置

.dts中增加你的默认设备树配置。你也可以按需求拷贝对应芯片的开发板文件。例如:

/${NCS-v2.8.0}/zephyr/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.dts

这里着重介绍一些要用到的:

特殊引脚配置(in UICR)

当你的GPIO不够用时,可能需要把一些特殊引脚当作GPIO使用。这些需要写芯片的UICR寄存器(类似于Flash的一个区域,存储用户配置)。

&uicr {    // bool类型属性,有则为true,没有则为false        // Reset pin 当作 reset 而不是GPIO使用  gpio-as-nreset;    // 删除属性,就是把bool类型设为false    // NFC引脚不当作GPIO使用  /delete-property/ nfct-pins-as-gpios;};

在较老的NCS版本,v2.4.x及之前,不是在DeviceTree中设置,而是在Kconfig中设置:

CONFIG_GPIO_AS_PINRESET=y
CONFIG_NFCT_PINS_AS_GPIOS=n


电源regulator配置

板子外部通过VDD引脚对芯片进行供电,Nordic芯片内部还有一级电源Regulator给内核供电。这个Regulator可以配置成DC/DC或者LDO。如果是DC/DC的话,板子外部需要添加对应的电感电容。

nRF52832内部供电-DCDC模式

nRF52840内部两级供电-双DC/DC模式

nRF52840有高电压模式,可以用VDDH引脚输入2.5~5.5V电压。

你也可以不使用VDDH。直接把VDDH和VDD短路,这种情况下会跳过Regulator0,供电范围是1.7~3.6V:

nRF52840一级供电 - LDO模式

大多数应用,采用一级供电即可。此外,像是nRF52840-QFAA这种封装(QFN48)内部已经把VDDH和VDD进行了短路操作,这时regulator0已经被屏蔽。直接配置reg1即可

// 使用DC/DC®1 {  regulator-initial-mode = ;};
// 使用LDO®1 {  regulator-initial-mode = ;};

如果你用的是带有VDDH供电的封装,则用以下设备树开启REG0的DC/DC

// reg0 只在nrf52840-qiaa.dtsi中有定义®0 {  status = "okay";};

在较老的NCS版本中,不是在设备树中配置,而是用Kconfig配置DC/DC

CONFIG_SOC_DCDC_NRF52X=yCONFIG_SOC_DCDC_NRF52X_HV=y

gpio reserve

在开发板的设备树中,我们可能会看到gpio port的节点下有一些配置。我们需要知道它的意思。

&gpio0 {  status = "okay";  gpio-reserved-ranges = <0 2>, <6 1>, <8 3>, <17 7>;  gpio-line-names = "XL1", "XL2", "AREF", "A0", "A1", "RTS", "TXD",    "CTS", "RXD", "NFC1", "NFC2", "BUTTON1", "BUTTON2", "LED1",    "LED2", "LED3", "LED4", "QSPI CS", "RESET", "QSPI CLK",    "QSPI DIO0", "QSPI DIO1", "QSPI DIO2", "QSPI DIO3","BUTTON3",    "BUTTON4", "SDA", "SCL", "A2", "A3", "A4", "A5";};

这里gpio-reserved-ranges的意思是:从软件层面上限制gpio0的某些引脚不能当作普通GPIO使用,因为它们在开发板上已经接了一些元器件。这可以防止出一些引脚分配问题。

<0 2>的意思是P0.00及其之后一共2个引脚,也就是P0.00和P0.01,因为它们是32.768kHz低频晶振所使用的引脚;同理,<17 7>的意思是P0.17及其之后一共7个引脚不能当普通GPIO使用,因为它们是板子上外部QSPI flash采用的引脚,还有P0.18是 reset引脚。

这个只是限制引脚不能当作普通GPIO使用,运行时会报错。但是并不限制这些引脚用pinctrl来分配给外设(毕竟QSPI引脚就是这么分配的)。

我们在拷贝开发板的dts到我们自定义的board时,注意不要完全拷贝这部分,要根据需求来。

Zephyr软件依赖的设备树节点

Zephyr中有许多现成的软件模块,它们与硬件有关。比如命令行终端shell,又比如LED和button的驱动。当你使能这些软件模块时,它们会去device tree中寻找自己应该操作哪些硬件。

比如,许多Zephyr Kernel功能用的是/chosen节点下的定义:

/{  chosen {    zephyr,console = &uart0;    zephyr,shell-uart = &uart0;    zephyr,uart-mcumgr = &uart0;    zephyr,bt-mon-uart = &uart0;    zephyr,bt-c2h-uart = &uart0;    zephyr,ieee802154 = &ieee802154;  };};
// 如果用到OpenThread, Zigbee协议,则需要开启802.15.4&ieee802154 {  status = "okay";};

而其他一些library和例程用的是/aliases节点下的定义:

/{  aliases {    led0 = &led0;    led1 = &led1;    led2 = &led2;    led3 = &led3;    pwm-led0 = &pwm_led0;    sw0 = &button0;    sw1 = &button1;    sw2 = &button2;    sw3 = &button3;    bootloader-led0 = &led0;    mcuboot-button0 = &button0;    mcuboot-led0 = &led0;    watchdog0 = &wdt0;  };};

很多例程会用到LED和Button。当你在自己的板子上运行例程,而你的板子上又没有定义led或button时,记得删除例程中LED和Button相关代码。

例程led和button相关的CONFIG是:

# Remove support for LEDs and buttons on Nordic development kitsCONFIG_DK_LIBRARY=n

外部Flash

nRF52840DK开发板上默认的QSPI flash为:

&qspi {  status = "okay";  pinctrl-0 = <&qspi_default>;  pinctrl-1 = <&qspi_sleep>;  pinctrl-names = "default", "sleep";  mx25r64: mx25r6435f@0 {    compatible = "nordic,qspi-nor";    reg = <0>;    /* MX25R64 supports only pp and pp4io */    writeoc = "pp4io";    /* MX25R64 supports all readoc options */    readoc = "read4io";    sck-frequency = <8000000>;    jedec-id = [c2 28 17];    sfdp-bfp = [      e5 20 f1 ff  ff ff ff 03  44 eb 08 6b  08 3b 04 bb      ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52      10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 68 44      30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff    ];    size = <67108864>;    has-dpd;    t-enter-dpd = <10000>;    t-exit-dpd = <35000>;  };};

在nRF7002DK中,也有SPI Flash

&spi4 {  compatible = "nordic,nrf-spim";  status = "okay";  pinctrl-0 = <&spi4_default>;  pinctrl-1 = <&spi4_sleep>;  pinctrl-names = "default", "sleep";  cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;  mx25r64: mx25r6435f@0 {    compatible = "jedec,spi-nor";    reg = <0>;    spi-max-frequency = <33000000>;    jedec-id = [c2 28 17];    sfdp-bfp = [      e5 20 f1 ff ff ff ff 03 44 eb 08 6b 08 3b 04 bb      ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52      10 d8 00 ff 23 72 f5 00 82 ed 04 cc 44 83 68 44      30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff    ];    size = <67108864>;    has-dpd;    t-enter-dpd = <10000>;    t-exit-dpd = <5000>;  };};

QSPI Flash选用的驱动为compatible = "nordic,qspi-nor". SPI Flash选用的驱动为compatible = "jedec,spi-nor。

如果你选的板子上的外挂flash和开发板自带的不同,则可以参考

${NCS}/zephyr/samples/driversamples/drivers/jesd216例程。不论你用的是QSPI还是SPI Flash,都把它先挂到SPI上,然后根据此例程的说明运行。例程会自动读取Flash信息,并把对应的设备树配置打印到日志中,复制出来即可。但是Flash一定是需要支持JEDEC的。

JEDEC (Joint Electron Device Engineering Council) 是一个制定半导体行业标准的组织。对于外挂Flash存储器来说,JEDEC标准定义了Flash存储器的接口、性能和功能特性。JEDEC标准确保了不同厂商生产的Flash存储器具有互操作性和兼容性。

Partition Manager

用MCUBoot进行升级时,如果需要把Second slot放到外部Flash,则需要增加以下配置,让Partition Manager知道外部Flash也要参与存储器分区:

chosen { nordic,pm-ext-flash = &mx25r64; // 赋值为你的外部flash的label};

用自定义板子编译

VS Code Build界面中出现自定义Board可以选择:

也可以在命令行编译时以当前板子为参数

west build -d build -b my_board/nrf52840 --sysbuild




编译流程与输出文件

1

编译流程


2

输出文件

以下均按照开启sysbuild的情况下来看路径:

  • 当前application工程固件:build//zephyr/zephyr.hex

  • 当前多工程编译合并固件:build/merged.hex,如果有多个核,每个核会有自己的merged_.hex

  • DFU升级文件:build/dfu_application.zip,通过蓝牙等方式升级时使用的升级包

更多输出文件请参考官方文档.

https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/config_and_build/output_build_files.html

3

VS Code界面

也可以在nRF Connect for VS Code插件界面中查看自己的所有参与编译的源码、配置文件、输出文件:





【联系我们】

中文官网:www.nordicsemi.cn

英文官网:www.nordicsemi.com

微信公众号:nordicsemi


【Nordic 开发者论坛】

https://devzone.nordicsemi.com


【销售接洽】

北京分公司: +86 010 8438 2767

上海分公司: +86 21 6330 0620

深圳分公司: +86 755 8322 0147

sales.cn@nordicsemi.no

 点击“阅读原文” 探索更多Nordic资讯

Nordic半导体 Nordic 半导体开发支持蓝牙智能、ANT+和2.4GHz应用的超低功耗短距无线通信技术,用于物联网 、可穿戴产品、智能家居、玩具等应用。Nordic 提供现成可用的设计框架、世界级文档资料和支持,以加快专业工程师和业余爱好者的开发速度。
评论 (0)
  • 在 AI 浪潮席卷下,厨电行业正经历着深刻变革。AWE 2025期间,万得厨对外首次发布了wan AiOS 1.0组织体超智能系统——通过AI技术能够帮助全球家庭实现从健康检测、膳食推荐,到食材即时配送,再到一步烹饪、营养总结的个性化健康膳食管理。这一创新之举并非偶然的个案,而是整个厨电行业大步迈向智能化、数字化转型浪潮的一个关键注脚,折射出全行业对 AI 赋能的热切渴求。前有标兵后有追兵,万得厨面临着高昂的研发成本与技术迭代压力,稍有懈怠便可能被后来者赶
    用户1742991715177 2025-05-11 22:44 48浏览
  • 【拆解】+自动喷香机拆解 家里之前买了从PDD买了一个小型自动喷香机放在厕所里。来增加家里的温馨感,这东西看着确实小巧,精致。可是这东西吧,耗电就是快,没过几天就没电了。今个就让我拆开看看什么在捣鬼。如下是产品的实物和宣传图: 由于螺丝孔太小和限位很深。对于我的螺丝刀套装没用。只能使用那种螺丝刀细头,同时又长的小螺丝刀进行拆解 拧下三颗螺丝钉,用一字螺丝刀撬开外壳,内部结构就呈现在眼前。 内部构造相当简单,部件没多少。就是锂电池供电,通过MCU实现按键控制,段码屏控制,LE
    zhusx123 2025-05-10 19:55 40浏览
  • 递交招股书近一年后,曹操出行 IPO 进程终于迎来关键节点。从 2024 年 4 月首次递表,到 2025 年 4 月顺利通过中国证监会境外发行上市备案,并迅速更新招股书。而通过上市备案也标志着其赴港IPO进程进入实质性推进阶段,曹操出行最快有望于2025年内完成港股上市,成为李书福商业版图中又一关键落子。行路至此,曹操出行面临的挑战依然不容忽视。当下的网约车赛道,早已不是当年群雄逐鹿的草莽时代,市场渐趋饱和,竞争近乎白热化。曹操出行此时冲刺上市,既是背水一战,也是谋篇布局。其招股书中披露的资金
    用户1742991715177 2025-05-10 21:18 44浏览
  •   定制软件开发公司推荐清单   在企业数字化转型加速的2025年,定制软件开发需求愈发多元复杂。不同行业、技术偏好与服务模式的企业,对开发公司的要求大相径庭。以下从技术赛道、服务模式及行业场景出发,为您提供适配的定制软件开发公司推荐及选择建议。   华盛恒辉科技有限公司:是一家专注于高端软件定制开发服务和高端建设的服务机构,致力于为企业提供全面、系统的开发制作方案。在部队政企开发、建设到运营推广领域拥有丰富经验,在教育,工业,医疗,APP,管理,商城,人工智能,部队软件、工业软件、数字化转
    华盛恒辉l58ll334744 2025-05-12 15:55 44浏览
  •         信创产业含义的“信息技术应用创新”一词,最早公开信息见于2019年3月26日,在江苏南京召开的信息技术应用创新研讨会。本次大会主办单位为江苏省工业和信息化厅和中国电子工业标准化技术协会安全可靠工作委员会。        2019年5月16日,美国将华为列入实体清单,在未获得美国商务部许可的情况下,美国企业将无法向华为供应产品。       2019年6
    天涯书生 2025-05-11 10:41 106浏览
  • 行车记录仪是长这个样子的,如下图。从前面拆去玻璃挡板,可以清晰的看见里面的部件,5个按键电路板,液晶显示屏,摄像头,喇叭,电池包,还有一块主电路板。液晶显示屏正面,如下图。液晶显示屏背面,如下图。喇叭,如下图。5个按键的电路板,MENU,DOWN,POWER,UP,OK总共5个按键功能,导线连接到主电路板上,如下图。电池包,303040聚合物锂电池,3.7V,300mAH,如下图。如下图。摄像头,如下图。拿去摄像头外壳,如下图。分离广角聚集镜头和PCB板,如下图。广角聚焦镜头,具体结构如下图。P
    liweicheng 2025-05-09 22:50 25浏览
  • 体积大小:14*11*2.6CM,电气参数:输入100V-240V/10A,输出16V24A。PCB 正面如下图。PCB 背面如下图。根据实际功能可以将PCB分成几部分:EMI滤波,PFC电路,LLC电路。EMI滤波区域,两级共模电感,LN各用了保险丝加压敏电阻,继电器(HF32FV-G)用来切除NTC的,为了提高效率点,如下图。PFC电路区域,如下图。LLC电路区域,如下图。详细分析一下该电源用的主要IC还有功率器件。AC侧采用了两颗整流桥进行并联,器件增加电流应力,如下图。共模电感都有放电针
    liweicheng 2025-05-10 20:03 25浏览
  • 【拆解】+CamFi卡菲单反无线传输器拆解 对于单反爱好者,想要通过远程控制自拍怎么办呢。一个远程连接,远程控制相机拍摄的工具再合适不过了。今天给大伙介绍的是CamFi卡菲单反无线传输器。 CamFi 是专为数码单反相机打造的无线传输控制器,自带的 WiFi 功能(无需手机流量),不但可通过手机、平板、电脑等设备远程连接操作单反相机进行拍摄,而且还可实时传输相机拍摄的照片到 iPad 和电视等大屏设备进行查看和分享。 CamFi 支持大部分佳能和尼康单反相机,内置可充电锂离子电池,无需相机供电。
    zhusx123 2025-05-11 14:14 69浏览
  •   基于 2025 年行业权威性与时效性,以下梳理国内知名软件定制开发企业,涵盖综合型、垂直领域及特色技术服务商:   华盛恒辉科技有限公司:是一家专注于高端软件定制开发服务和高端建设的服务机构,致力于为企业提供全面、系统的开发制作方案。在部队政企开发、建设到运营推广领域拥有丰富经验,在教育,工业,医疗,APP,管理,商城,人工智能,部队软件、工业软件、数字化转型、新能源软件、光伏软件、汽车软件,ERP,系统二次开发,CRM等领域有很多成功案例。   五木恒润科技有限公司:是一家专业的部队信
    华盛恒辉l58ll334744 2025-05-12 16:13 31浏览
  • ‌磁光克尔效应(Magneto-Optic Kerr Effect, MOKE)‌ 是指当线偏振光入射到磁性材料表面并反射后,其偏振状态(偏振面旋转角度和椭偏率)因材料的磁化强度或方向发生改变的现象。具体表现为:1、‌偏振面旋转‌:反射光的偏振方向相对于入射光发生偏转(克尔旋转角 θK)。2、‌椭偏率变化‌:反射光由线偏振变为椭圆偏振(克尔椭偏率 εK)。这一效应直接关联材料的磁化状态,是表征磁性材料(如铁磁体、反铁磁体)磁学性质的重要非接触式光学探测手段,广泛用于
    锦正茂科技 2025-05-12 11:02 54浏览
  • 蓝牙耳机是长这个样子,如下图。背部图,如下图。拆开L耳的一侧,有NFC和电池包(501230 3.7V 150mAh)如下图。电池包(501230 3.7V 150mAh)如下图。NFC正面,如下图。NFC背面,如下图。如何理解NFC的工作原理呢,搜集一下相关的资料,如下图。拆开R耳的一侧,PCB正面,如下图。PCB背面,如下图。有两组红黑的线,一组连接到了喇叭,另一组连接到了MIC头上,MIC头参数如下图。蓝牙模块(CSR 8635),有蛇形PCB走线做成天线,节约了天线成本,如下图。该IC介
    liweicheng 2025-05-10 00:45 24浏览
  • 在印度与巴基斯坦的军事对峙情境下,歼10C的出色表现如同一颗投入平静湖面的巨石,激起层层涟漪,深刻印证了“质量大于数量”这一铁律。军事领域,技术优势就是决定胜负的关键钥匙。歼10C凭借先进的航电系统、强大的武器挂载能力以及卓越的机动性能,在战场上大放异彩。它能够精准捕捉目标,迅速发动攻击,以一敌多却毫不逊色。与之形成鲜明对比的是,单纯依靠数量堆砌的军事力量,在面对先进技术装备时,往往显得力不从心。这一现象绝非局限于军事范畴,在当今社会的各个领域,“质量大于数量”都已成为不可逆转的趋势。在科技行业
    curton 2025-05-11 19:09 161浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦