【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)
  • 在电子设计中,电磁兼容性(EMC)是确保设备既能抵御外部电磁干扰(EMI),又不会对自身或周围环境产生过量电磁辐射的关键。电容器、电感和磁珠作为三大核心元件,通过不同的机制协同作用,有效抑制电磁干扰。以下是其原理和应用场景的详细解析:1. 电容器:高频噪声的“吸尘器”作用原理:电容器通过“通高频、阻低频”的特性,为高频噪声提供低阻抗路径到地,形成滤波效果。例如,在电源和地之间并联电容,可吸收电源中的高频纹波和瞬态干扰。关键应用场景:电源去耦:在IC电源引脚附近放置0.1μF陶瓷电容,滤除数字电路
    时源芯微 2025-03-27 11:19 157浏览
  • 文/陈昊编辑/cc孙聪颖‍2025 年,作为中国实施制造强国战略第一个十年计划的关键里程碑,被赋予了极为重大的意义。两会政府工作报告清晰且坚定地指出,要全力加速新质生产力的发展进程,推动传统产业全方位向高端化、智能化与绿色化转型。基于此,有代表敏锐提议,中国制造应从前沿技术的应用切入,逐步拓展至产业生态的构建,最终延伸到提升用户体验的维度,打出独树一帜、具有鲜明特色的发展牌。正是在这样至关重要的时代背景之下,于 AWE 2025(中国家电及消费电子博览会)这一备受瞩目的舞台上,高端厨房的中国方案
    华尔街科技眼 2025-03-25 16:10 85浏览
  • 家电,在人们的日常生活中扮演着不可或缺的角色,也是提升人们幸福感的重要组成部分,那你了解家电的发展史吗?#70年代结婚流行“四大件”:手表、自行车、缝纫机,收音机,合成“三转一响”。#80年代随着改革开放的深化,中国经济开始飞速发展,黑白电视机、冰箱、洗衣机这“新三件”,成为了人们对生活的新诉求。#90年代彩电、冰箱、全自动洗衣机开始大量进入普通家庭,快速全面普及,90年代末,家电产品实现了从奢侈品到必需品的转变。#00年代至今00年代,随着人们追求高品质生活的愿望,常用的电视机、洗衣机等已经远
    启英AI平台 2025-03-25 14:12 90浏览
  •       知识产权保护对工程师的双向影响      正向的激励,保护了工程师的创新成果与权益,给企业带来了知识产权方面的收益,企业的创新和发明大都是工程师的劳动成果,他们的职务发明应当受到奖励和保护,是企业发展的重要源泉。专利同时也成了工程师职称评定的指标之一,专利体现了工程师的创新能力,在求职、竞聘技术岗位或参与重大项目时,专利证书能显著增强个人竞争力。专利将工程师的创意转化为受法律保护的“无形资产”,避免技术成果被他人抄袭或无偿使
    广州铁金刚 2025-03-25 11:48 181浏览
  • 长期以来,智能家居对于大众家庭而言就像空中楼阁一般,华而不实,更有甚者,还将智能家居认定为资本家的营销游戏。商家们举着“智慧家居、智慧办公”的口号,将原本价格亲民、能用几十年的家电器具包装成为了高档商品,而消费者们最终得到的却是家居设备之间缺乏互操作性、不同品牌生态之间互不兼容的碎片化体验。这种早期的生态割裂现象致使消费者们对智能家居兴趣缺失,也造就了“智能家居无用论”的刻板印象。然而,自Matter协议发布之后,“命运的齿轮”开始转动,智能家居中的生态割裂现象与品牌生态之间的隔阂正被基于IP架
    华普微HOPERF 2025-03-27 09:46 109浏览
  • 在嵌入式语音系统的开发过程中,广州唯创电子推出的WT588系列语音芯片凭借其优异的音质表现和灵活的编程特性,广泛应用于智能终端、工业控制、消费电子等领域。作为该系列芯片的关键状态指示信号,BUSY引脚的设计处理直接影响着系统交互的可靠性和功能拓展性。本文将从电路原理、应用场景、设计策略三个维度,深入解析BUSY引脚的技术特性及其工程实践要点。一、BUSY引脚工作原理与信号特性1.1 电气参数电平标准:输出3.3V TTL电平(与VDD同源)驱动能力:典型值±8mA(可直接驱动LED)响应延迟:语
    广州唯创电子 2025-03-26 09:26 206浏览
  • ​2025年3月27日​,贞光科技授权代理品牌紫光同芯正式发布新一代汽车安全芯片T97-415E。作为T97-315E的迭代升级产品,该芯片以大容量存储、全球化合规认证、双SPI接口协同为核心突破,直击智能网联汽车"多场景安全并行"与"出口合规"两大行业痛点,助力车企抢占智能驾驶与全球化市场双赛道。行业趋势锚定:三大升级回应智能化浪潮1. 大容量存储:破解车联网多任务瓶颈随着​车机功能泛在化​(数字钥匙、OTA、T-BOX等安全服务集成),传统安全芯片面临存储资源挤占难题。T97-415E创新性
    贞光科技 2025-03-27 13:50 148浏览
  • 六西格玛首先是作为一个量度质量水平的指标,它代表了近乎完美的质量的水平。如果你每天都吃一个苹果,有一间水果店的老板跟你说,他们所卖的苹果,质量达到六西格玛水平,换言之,他们每卖一百万个苹果,只会有3.4个是坏的。你算了一下,发现你如果要从这个店里买到一个坏苹果,需要805年。你会还会选择其他店吗?首先发明六西格玛这个词的人——比尔·史密斯(Bill Smith)他是摩托罗拉(Motorloa)的工程师,在追求这个近乎完美的质量水平的时候,发明了一套方法模型,开始时是MAIC,后来慢慢演变成DMA
    优思学院 2025-03-27 11:47 151浏览
  • 汽车导航系统市场及应用环境参照调研机构GII的研究报告中的市场预测,全球汽车导航系统市场预计将于 2030年达到472亿美元的市场规模,而2024年至2030年的年复合成长率则为可观的6.7%。汽车导航系统无疑已成为智能汽车不可或缺的重要功能之一。随着人们在日常生活中对汽车导航功能的日渐依赖,一旦出现定位不准确或地图错误等问题,就可能导致车主开错路线,平白浪费更多行车时间,不仅造成行车不便,甚或可能引发交通事故的发生。有鉴于此,如果想要提供消费者完善的使用者体验,在车辆开发阶段便针对汽车导航功能
    百佳泰测试实验室 2025-03-27 14:51 188浏览
  • 在智能终端设备开发中,语音芯片与功放电路的配合直接影响音质表现。广州唯创电子的WTN6、WT588F等系列芯片虽功能强大,但若硬件设计不当,可能导致输出声音模糊、杂音明显。本文将以WTN6与WT588F系列为例,解析音质劣化的常见原因及解决方法,帮助开发者实现清晰纯净的语音输出。一、声音不清晰的典型表现与核心原因当语音芯片输出的音频信号存在以下问题时,需针对性排查:背景杂音:持续的“沙沙”声或高频啸叫,通常由信号干扰或滤波不足导致。语音失真:声音断断续续或含混不清,可能与信号幅度不匹配或功放参数
    广州唯创电子 2025-03-25 09:32 112浏览
  • 案例概况在丹麦哥本哈根,西门子工程师们成功完成了一项高安全设施的数据集成项目。他们利用宏集Cogent DataHub软件,将高安全设施内的设备和仪器与远程监控位置连接起来,让技术人员能够在不违反安全规定、不引入未经授权人员的情况下,远程操作所需设备。突破OPC 服务器的远程连接难题该项目最初看似是一个常规的 OPC 应用:目标是将高安全性设施中的冷水机(chiller)设备及其 OPC DA 服务器,与远程监控站的两套 SCADA 系统(作为 OPC DA 客户端)连接起来。然而,在实际实施过
    宏集科技 2025-03-27 13:20 109浏览
  • 在当今竞争激烈的工业环境中,效率和响应速度已成为企业制胜的关键。为了满足这一需求,我们隆重推出宏集Panorama COOX,这是Panorama Suite中首款集成的制造执行系统(MES)产品。这一创新产品将Panorama平台升级为全面的工业4.0解决方案,融合了工业SCADA和MES技术的双重优势,帮助企业实现生产效率和运营能力的全面提升。深度融合SCADA与MES,开启工业新纪元宏集Panorama COOX的诞生,源于我们对创新和卓越运营的不懈追求。通过战略性收购法国知名MES领域专
    宏集科技 2025-03-27 13:22 189浏览
  • WT588F02B是广州唯创电子推出的一款高性能语音芯片,广泛应用于智能家电、安防设备、玩具等领域。然而,在实际开发中,用户可能会遇到烧录失败的问题,导致项目进度受阻。本文将从下载连线、文件容量、线路长度三大核心因素出发,深入分析烧录失败的原因并提供系统化的解决方案。一、检查下载器与芯片的物理连接问题表现烧录时提示"连接超时"或"设备未响应",或烧录进度条卡顿后报错。原因解析接口错位:WT588F02B采用SPI/UART双模通信,若下载器引脚定义与芯片引脚未严格对应(如TXD/RXD交叉错误)
    广州唯创电子 2025-03-26 09:05 146浏览
  • 在智能语音产品的开发过程中,麦克风阵列的选型直接决定了用户体验的优劣。广州唯创电子提供的单麦克风与双麦克风解决方案,为不同场景下的语音交互需求提供了灵活选择。本文将深入解析两种方案的性能差异、适用场景及工程实现要点,为开发者提供系统化的设计决策依据。一、基础参数对比分析维度单麦克风方案双麦克风方案BOM成本¥1.2-2.5元¥4.8-6.5元信噪比(1m)58-62dB65-68dB拾音角度全向360°波束成形±30°功耗8mW@3.3V15mW@3.3V典型响应延迟120ms80ms二、技术原
    广州唯创电子 2025-03-27 09:23 162浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦