上一篇文章介绍了一下在NRF52840上运行zephyr application。在zephyr 运行之前,NRF52840会先运行boot loader,同时boot loader也提供了DFU的功能。接下来介绍一下整个boot loader的flow。有兴趣的可以去github下载源码研究。
GitHub - adafruit/Adafruit_nRF52_Bootloader: USB-enabled bootloaders for the nRF52 BLE SoC chips
DFU (Device Firmware Update)
DFU模式是用来对系统的firmware进行更新的模式。以“SuperMini”NFRF52840开发板为例,连续按两次reset可以进入DFU模式。开发板会模拟一个USB 驱动器,直接把zephyr.uf2拷贝到USB驱动器就能开始firmware update。
Boot Loader Flow
首先运行“thumb_crt0.s”汇编代码,thumb_crt0.s的作用是初始化硬件和运行c需要的栈空间,最后跳转到main函数入口。
main
board_init //initialize board hardware
bootloader_init
check_dfu_mode // Check if we need to enable DFU mode
// Read reset pin status. If reset is pressed, reason_reset_pin = 1
reason_reset_pin = (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk) ? true : false;
// If (*dbl_reset_mem) == DFU_DBL_RESET_MAGIC, it means this is the 2nd reset
dfu_start = ((*dbl_reset_mem) == DFU_DBL_RESET_MAGIC) && reason_reset_pin;
if (reason_reset_pin)
// Register our first reset for double reset detection
(*dbl_reset_mem) = DFU_DBL_RESET_MAGIC;
// Wait for 2nd reset
NRFX_DELAY_MS(DFU_DBL_RESET_DELAY);
// if RST is pressed during this delay (double reset), the below code will not be executed.
(*dbl_reset_mem) = 0; // Clear reset info
if (dfu_start)
// Initialize Tiny USB Driver which calls proc_read10_cmd or proc_write10_new_data to read/write DFU USB drive.
// When OS read block, "read_block" returns emulated USB drive info such as label, size.
// When OS write block (copy firmware to USB drive), USB driver will write firmware to flash.
usb_init
usb_desc_init
uf2_init
tusb_init
if (bootloader_app_is_valid() && !bootloader_dfu_sd_in_progress())
bootloader_app_start
bootloader_util_app_start // Run Zephyr OS
NVIC_SystemReset
当按下两次reset,boot loader进入DFU模式。用户拷贝.uf2格式的firmware到USB drive。 USB driver完成firmware的flash write。
如果只有一次reset,进入zephyr。