NDK Bootloader 开发指南¶
1. 背景介绍¶
BootLoader是一个系统的引导程序,用于引导 App 软件初始化、支持 DFU/OTA 升级等。由于实际产品中 BootLoader 是不可以或者很难更新的,所以确保BootLoader的稳定性和鲁棒性是对一个系统最基本的保证。本文是 PAN10xx NDK 中提供的 Bootloader 例程程序的开发指南。
Bootloader 例程代码位于:
<PAN10XX-NDK>\01_SDK\nimble\mcu_boot\
目录下。
2. Bootloader Config 配置¶
与 App 工程类似,Bootloader 工程中也提供了一个名为 sdk_config.h
的配置文件,但其配置项与 App 中的有所差异:

Bootloader Config File¶
2.1 Bootloader Config¶
Bootloader Config 是与当前 Bootloader 工程相关的配置,包括 Bootloader 支持功能的选择、Flash 分区配置等项目:
Enable UART DFU:使能 Bootloader UART DFU 功能
此功能基于 xmodem 协议实现
Enable USB DFU:使能 Bootloader USB DFU 功能
此功能使用芯片 ROM 中固化的 USB DFU 升级流程
Enable Private 2.4G OTA:使能 Bootloader 私有 2.4G OTA 功能
此功能基于 Panchip 私有 2.4G OTA 升级协议实现
Flash Partition Config:配置与 Bootloader 相关的 Flash 分区起始地址和大小(注意此处 Flash 分区配置需与 App 工程中的 sdk config 配置保持一致!)
Bootloader Flash Partition Address:设置 Bootloader Flash 分区起始地址
此项为固定值 0x0,无需修改
Bootloader Flash Partition Size:设置 Bootloader Flash 分区大小(字节)
根据当前项目需要,将此项修改为非 0 值,表示为 Bootloader Image 预留的 Flash 空间大小
App Flash Partition Address:设置当前 App Flash 分区起始地址
根据当前项目需要,将此项修改为非 0 值(并确保 App 分区起始地址紧接着 Bootloader 分区,中间不可有空隙,否则会弹出预编译报错提醒)
App Flash Partition Size:设置当前 App Flash 分区大小(字节)
根据当前项目需要,将此项修改为非 0 值,表示为 App Image 预留的 Flash 空间大小
App Backup Flash Partition Address:设置 App Backup Flash 分区起始地址
根据当前项目需要,若需使用 App 备份区(如蓝牙 OTA 场景),则将此项修改为非 0 值(并确保 App 备份区起始地址紧接着 App 分区,中间不可有空隙,否则会弹出预编译报错提醒)
App Backup Flash Partition Size:设置 App Backup Flash 分区大小(字节)
根据当前项目需要,若需使用 App 备份区(如蓝牙 OTA 场景),则将此项修改为非 0 值(并确保 App 备份区起始地址紧接着 App 分区,中间不可有空隙,且 App 备份区大小应与 App 分区相同,否则会弹出预编译报错提醒)
App Use Image Header:使能 App Image Header 功能
当前 SDK 框架下,若使用 Bootloader,则必须同时使能 App Image Header,所以此选项必须勾上(且应与 App Config 中的对应选项保持一致)
2.2 SoC Platform¶
SoC Platform 是与芯片平台相关的配置,包括时钟、电源、平台相关的特殊 Feature 等项目。
Bootloader 中的此项菜单实际上是 App Config 中对应项菜单的子集,详情参考 NDK Configuration 指南。
2.3 Log & Debug Config¶
Log & Debug Config 是与芯片 Log 功能和调试相关的配置。
Bootloader 中的此项菜单实际上是 App Config 中对应项菜单的子集,详情参考 NDK Configuration 指南。
3 BootLoader 升级流程和策略¶
BootLoader 启动的时候,会等待很多个信号,然后依次 trigger 信号的操作。
// signals:
bool sig_key_push_down(void);
bool sig_special_ram_value_detected(void);
bool sig_ota_start_received(void);
bool sig_back_up_is_completed_image(void);
// slots:
void on_usb_dfu_enter(void);
void on_prf_ota_enter(void);
void on_uart_dfu_enter(void);
void on_image_load_enter(void);
连接信号和槽
typedef void (slot_handler_t)(void);
typedef void (signal_handler_t)(void);
void connect(uint8_t priority, signal_handler_t signal, slot_handler_t slot);
事件检测流程
/* when checking backup image is valid, the on_image_load_enter function will be handled */
ss_connect(0, sig_back_up_is_completed_image, on_image_load_enter);
#if BOOT_ENABLE_UART_DFU
/* when detecting key1 down, the on_uart_dfu_enter function will be handled */
ss_connect(1, sig_key1_push_down, on_uart_dfu_enter);
#endif
#if BOOT_ENABLE_USB_DFU
/* when dectecting key2 down, the on_usb_dfu_enter function will be handled */
ss_connect(2, sig_key2_push_down, on_usb_dfu_enter);
#endif
#if BOOT_ENABLE_PRF_OTA
/* when receive a ota start packet, the on_prf_ota_enter function will be handled */
ss_connect(3, sig_ota_start_received, on_prf_ota_enter);
#endif
/* handle all of events related signal fuction*/
ss_events_handle();
3.4 Backup dfu 模式¶
尝试校验 Flash App Backup 分区中的固件, 以决定是否要将其搬移至 Flash App 分区。
4. uart 升级详解¶
升级的固件需要签名校验,默认 keil 编译的时候,在工程的同级目录Images下会自动生成 ndk_app.signed.bin
的签名 Image:
4.1 检测并进入uart 升级模式¶
在 Bootloader Config 配置中使能 UART DFU 功能
编写 uart dfu 进入的 signal 函数,并将信号和槽连接,槽属于升级流程BootLoader已经支持,用户不需要修改。用户可以修改 signal 函数。默认如下:
#if BOOT_ENABLE_UART_DFU /* when detecting key1 down, the on_uart_dfu_enter function will be handled */ ss_connect(1, sig_key1_push_down, on_uart_dfu_enter); #endif /* user can implement a custom signal fucntion */ bool sig_key1_push_down(void) { GPIO_SetMode(P0, BIT6, GPIO_MODE_INPUT); GPIO_EnablePullupPath(P0, BIT6); SYS_delay_10nop(10000); for (uint16_t i = 0; i < 1000; i++) { if (P06 == 1) { return false; } } return true; }
下载 BootLoader 和 App 程序,App 程序配置为带 Bootloader 的方式
4.2 操作流程¶
准备好 Bootloader Image
准备好待升级的 App Image(例如 ble_central)
使用工具SecureCRT进行升级
打开工具SecureCRT连接设备串口,串口波特率921600
按住 EVB 底板的 KEY1 按键不松开,然后再按一下 EVB 底板或核心板的 Reset 按钮复位芯片,查看工具SecureCRT上log打印,一直输出CCCCCCCCCC
PAN107x UART DFU进入升级模式¶
在工具SecureCRT的”传输”界面选择”发送Xmodem(N)”,选择待升级工程的文件,位于image路径下: ndk_app.signed.bin,文件开始传输
PAN107x UART DFU传输文件¶
再次复位芯片,观察串口log,确认已经打印升级后的程序log
5 USB dfu 升级详解¶
升级的固件需要签名校验,默认 keil 编译的时候,在工程的同级目录Images下会自动生成 ndk_app.signed.bin
的签名 Image:
5.1 检测并进入usb 升级模式¶
在 Bootloader Config 配置中使能 USB DFU 功能
编写 uart dfu 进入的 signal 函数,并将信号和槽连接,槽属于升级流程BootLoader已经支持,用户不需要修改。用户可以修改signal 函数。默认如下
#if BOOT_ENABLE_USB_DFU /* when dectecting key2 down, the on_usb_dfu_enter function will be handled */ ss_connect(2, sig_key2_push_down, on_usb_dfu_enter); #endif /* user can implement a custom signal fucntion */ bool sig_key2_push_down(void) { GPIO_SetMode(P1, BIT2, GPIO_MODE_INPUT); GPIO_EnablePullupPath(P1, BIT2); SYS_delay_10nop(10000); for (uint16_t i = 0; i < 1000; i++) { if (P12 == 1) { return false; } } return true; }
下载 BootLoader 和 App 程序,App 程序配置为带 Bootloader 的方式
5.2 操作流程¶
准备好 Bootloader Image
准备好待升级的 App Image(例如 ble_central)
使用 SDK 的 05_TOOLS 里面的工具箱工具 pan107xToolBox 进行升级
打开工具 pan107xToolBox,选择”显示”>”DFU”,连接设备USB口
按住 EVB 底板的 KEY1 按键不松开,然后再按一下 EVB 底板或核心板的 Reset 按钮复位芯片,确认工具 pan107xToolBox 成功识别到USB
PAN107x USB DFU识别usb口¶
在工具程序设置那里选择”添加程序”>”加载程序”,选择待升级工程的文件,位于image路径下:
ndk_app.signed.bin
,注意工具中的地址配置需要与 App 工程编译配置一致程序加载好之后,点击”开始下载”即可
PAN107x USB DFU升级成功¶
再次复位芯片,观察串口log,确认已经打印升级后的程序log