nRF52840芯片Flash资源调整说明

蓝牙 BLE设备、蓝牙 MESH设备、蓝牙 Beacon设备、Sub-G设备等


Post Reply
User avatar
逻辑的院子
Posts: 219
Contact:

Flash 分区说明

目前 TuyaOS BLE SDK V3.9.0 For nRF52840 的 Flash 分区图如下:

Image

上图中:

  • 0x27000 ~ 0x77000 共 320KB 的区域是应用代码存储区。

  • 0x77000 ~ 0xC7000 共 320KB 的区域是OTA代码存储区。

  • 0xC7000 ~ 0xF4000 共 180KB 的区域是未使用区域,可以用于应用层数据存储

  • 0xF4000 ~ 0xF8000 共 16KB 的区域是涂鸦授权和配网信息存储区,不允许其他程序进行修改和占用。

其他黄色区域是 Nordic 官方 SDK 分配好的区域,其中包含:

  • 4KB 的 MBR(Master Boot Record)程序引导区;

  • 152KB 的 softdevice(蓝牙协议栈)区域;

  • 8KB 的 bootloader 区域;

  • 4KB 的 MBR 信息存储区域;

  • 4KB 的 bootloader 信息存储区域;

Flash 分区调整方法

如果预分配的 application 区域不能满足应用开发需求,可以调整 application 区域的空间,由于 OTA 固件的可能大小跟 application 固件的可能大小是一样的,所以也需要同时调整 OTA 区域的空间。

从分区图中可以看到:unused 区域刚好位于 OTA 区域上方,所以我们只需要将 OTA 区域的起始地址和结束地址向后偏移即可。

具体操作步骤如下(假设将 application 区域由原来的 320KB 扩充到 400 KB):

(1)将 “\software\TuyaOS\vendor\nrf52840_ble\tuyaos\include\board.h” 文件中的

Code: Select all

#ifndef BOARD_FLASH_OTA_START_ADDR
#define BOARD_FLASH_OTA_START_ADDR              (0x77000)
#endif

#ifndef BOARD_FLASH_OTA_END_ADDR
#define BOARD_FLASH_OTA_END_ADDR                (0xC7000)
#endif

修改为:

Code: Select all

#ifndef BOARD_FLASH_OTA_START_ADDR
#define BOARD_FLASH_OTA_START_ADDR              (0x8B000) // (0x77000)
#endif

#ifndef BOARD_FLASH_OTA_END_ADDR
#define BOARD_FLASH_OTA_END_ADDR                (0xEF000) // (0xC7000)
#endif

(2)将 “\software\TuyaOS\vendor\nrf52840_ble\tuyaos\drivers\tkl_flash.c” 文件中的

Code: Select all

NRF_FSTORAGE_DEF(nrf_fstorage_t tkl_flash_fstorage) =
{
    .evt_handler = ty_flash_fstorage_evt_handler,
    .start_addr = (0x77000),
    .end_addr   = 0xF8000,
};

修改为:

Code: Select all

NRF_FSTORAGE_DEF(nrf_fstorage_t tkl_flash_fstorage) =
{
    .evt_handler = ty_flash_fstorage_evt_handler,
    .start_addr = (0x8B000), // 0x77000,
    .end_addr   = 0xF8000,
};

该步骤非必须,但是非常推荐修改,防止 Flash 相关接口修改 application 区域的代码。

(3)修改后的 Flash 分区图为:

Image

(4)基于 TuyaOS BLE SDK V3.9.0 For nRF52840 修改完成后使用以下方式已经测试成功

测试使用的步骤如下:

a. 烧录 3.9.0 版本的固件,固件运行成功;

b. 将固件版本从 3.9.0 OTA 升级到 3.9.1(文件名和固件实际版本 “FIRMWARE_VERSION” 都为 3.9.1),OTA 成功,固件运行成功,检测固件版本号为 3.9.1;

c. 将固件版本从 3.9.1 OTA 升级到 9.9.9(文件名修改为9.9.9,用于触发手机 App 启动 OTA 过程,固件实际版本 “FIRMWARE_VERSION” 为 3.9.0),OTA 成功,固件运行成功,检测固件版本号为 3.9.0,该方法可用于循环 OTA 测试;

其他说明

bootloader 不需要修改的原因:

查看 “\software\TuyaOS\vendor\nrf52840_ble\tuyaos\drivers\tkl_ota.c” 文件中的:

Code: Select all

OPERATE_RET tkl_ota_end_notify(BOOL_T reset)
{
    OPERATE_RET ret = OPRT_OK;

    if (sg_firmware_len > BOARD_FLASH_OTA_SIZE) {
        return 1;
    }

    if ((sg_data_crc32 != tkl_ota_get_crc32_in_flash(sg_firmware_len))
        || (sg_data_crc32 != *(tkl_ota_pri_param->p_firmware_crc32))) {
        return 2;
    }

    if (reset == TRUE) {
        memset(&s_dfu_settings, 0, SIZEOF(nrf_dfu_settings_t));
        s_dfu_settings.bank_1.image_crc = sg_data_crc32;
        s_dfu_settings.bank_1.image_size = sg_firmware_len;
        s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP;

        memset(&s_dfu_settings.progress, 0, SIZEOF(dfu_progress_t));
        s_dfu_settings.write_offset = 0;
        s_dfu_settings.progress.update_start_address = BOARD_FLASH_OTA_START_ADDR; // Here

        nrf_dfu_settings_write_and_backup((nrf_dfu_flash_callback_t)tkl_ota_setting_write_complete_cb);
    } else {
        s_dfu_settings.bank_1.image_crc = 0;
        s_dfu_settings.bank_1.image_size = 0;
        s_dfu_settings.bank_1.bank_code = 0;

        memset(&s_dfu_settings.progress, 0, SIZEOF(dfu_progress_t));
        s_dfu_settings.write_offset = 0;
        s_dfu_settings.progress.update_start_address = 0;
//        memset(&s_dfu_settings, 0, SIZEOF(nrf_dfu_settings_t));
        nrf_dfu_settings_write_and_backup(NULL);
    }

    return ret;
}

可知:

修改后的 “BOARD_FLASH_OTA_START_ADDR” 的值通过 nrf_dfu_settings_write_and_backup 接口存储到 “bootloader settings” 区域,当下一次 bootloader 运行时会获取到该值,就可以找到 OTA 固件的位置;

Post Reply