RT1060 OTA 引导加载程序的 ISP 及交换回滚用法
1 简介
RT1060 MCUXpresso SDK 提供 ota_bootloader 项目,下载链接:
https://mcuxpresso.nxp.com/en/welcome
ota_bootloader路径:
SDK_2_10_0_EVK-MIMXRT1060\boards\evkmimxrt1060\bootloader_examples\ota_bootloader
该 ota_bootloader 可让用户实现板载应用程序更新,RT1060 OTA 引导加载程序主要有两大功能:
ISP方法更新APP
提供 API 供用户实现不同应用程序的交换、回滚功能
ISP 方式基于 flashloader 实现,flashloader 会将代码加载到内部 RAM 中。使用时,RT 芯片通常需要进入串行下载模式,并通过 sdphost 将 flashloader 下载到内部 RAM,然后运行 flashloader 以实现 ISP 功能。而 OTA_bootloader 直接将代码存储在闪存中,RT 芯片可在内部引导模式下直接运行该引导程序。芯片每次复位后,代码会先运行 ota_bootloader,此时用户可通过 blhost 直接与 RT 芯片进行 UART/USB HID 通信来下载应用程序代码。因此,对于 OTA_bootloader 中的 ISP 功能,用户也可将其用作 ISP 二级引导加载程序来直接更新应用程序。在 5 秒超时后复位,如果应用程序区域有效,代码会跳转到应用程序并运行。
对于 ota_bootloader 的交换和回滚功能,用户可在应用程序中直接使用提供的 API 来实现应用程序更新、运行不同应用程序、交换应用程序以及回滚到旧应用程序等操作。
本文档将详细介绍如何使用 ota_bootloader 的 ISP 功能更新应用程序、如何修改用户应用程序以适配 ota_bootloader、如何解决用户应用程序与 ota_bootloader 配合使用 SDRAM 时出现的问题、如何使用 ota_bootloader 的 API 实现交换和回滚功能以及相关的应用程序准备工作。
2 OTA 引导加载程序的 ISP 用法
部分用户需要 ISP 二级引导加载程序功能,由于 flashloader 需要加载到内部 RAM 中,因此用户可利用 ota_bootloader 的 ISP 功能来满足二级引导加载程序的需求。采用这种方式,用户主要需要注意两点:
1)APP需要添加ota_header以满足ota_bootloader的需求。
2)APP使用SDRAM,ota_bootloader需要添加DCD内存
2.1 应用程序修改
OTA_bootloader 位于闪存的 0x60000000 地址处,应用程序位于 0x60040000 地址处。这一点可在 ota_bootloader 的 bootloader_config.h 文件中找到:
#define BL_APP_VECTOR_TABLE_ADDRESS (0x60040000u)
从 0x60040000 地址开始,前 0X400 字节应存放 ota_header,实际的应用程序代码从 0x60040400 地址开始存放。
现在以SDK中的evkmimxrt1060_iled_blinky项目为例,进行修改,使其与ota_bootloader相匹配。
应用程序代码需要添加以下文件:
ota_bootloader_hdr.c,
ota_bootloader_board.h,
ota_bootloader_supp.c,
ota_bootloader_supp.h
这些文件可从 evkmimxrt1060_lwip_httpssrv_ota 项目中获取,将上述文件放入 led_blinky 的源文件夹中。
2.1.1 内存修改
应用程序内存起始地址从 0x60000000 修改为 0x60040000,这是 ota_bootloader 定义的地址。
1.jpg
图1
2.1.2 添加 ota_hdr 相关文件
在 led_blinky 项目的源文件夹中,添加上述提到的与 ota_bootloader 相关的文件。
2.jpg
图2
2.1.3 linker file modification
在 evkmimxrt1060_iled_blinky_debug.ld 中,添加 boot_hdr,长度为 0X400。
我们可以使用 MCUXpresso IDE 的 linkscripts 文件夹,添加 .ldt 文件来修改链接文件。
在项目中,添加一个 linkscripts 文件夹,添加 boot_hdr_MIMXRT1060.ldt 文件,然后进行构建。
3.jpg
图3
构建完成后,可以发现 ld 文件已在开头的 0x400 范围内添加了 ota_header。
4.jpg
图4
以上是生成的 evkmimxrt1060_iled_blinky_ota_0x60040000.bin 文件,可以发现其中已包含 boot_hdr。
从偏移地址 0x400 开始,将放置实际的 APP 代码。
2.2 ISP 测试相关命令
测试板是MIMXRT1060-EVK,首先下载evkmimxrt1060_ota_bootloader项目,可以使用MCUXpresso IDE直接下载,然后按下重置按钮,将blhost和evkmimxrt1060_iled_blinky_ota_0x60040000.bin放在同一文件夹中,使用以下命令:
blhost.exe -t 50000 -u 0x15a2,0x0073 -j -- get-property 1 0
blhost.exe -t 2048000 -u 0x15a2,0x0073 -j -- flash-erase-region 0x60040000 0x6000 9
blhost.exe -t 5242000 -u 0x15a2,0x0073 -j -- write-memory 0x60040000 evkmimxrt1060_iled_blinky_ota_0x60040000.bin
blhost.exe -t 5242000 -u 0x15a2,0x0073 -j -- read-memory 0x60040000 0x6000 flexspiNorCfg.dat 9 5.jpg
图5
下载完成后,按下复位键,等待 5 秒,会跳转到应用程序,此时可以发现 MIMXRT1060-EVK 板上的 LED 在闪烁。这种方法实现了闪存 ISP 引导加载程序的下载和应用程序的运行。
上述命令使用 USB HID 进行下载,若需要使用 UART,也可使用如下命令:
blhost.exe -t 50000 -p COM45,19200 -j -- get-property 1 0
blhost.exe -t 50000 -p COM45,19200 -j -- flash-erase-region 0x60040000 0x6000 9
blhost.exe -t 50000 -p COM45,19200 -j -- write-memory 0x60040000 evkmimxrt1060_iled_blinky_ota_0x60040000.bin
blhost.exe -t 50000 -p COM45,19200 -j -- read-memory 0x60040000 0x6000 flexspiNorCfg.dat 9
对于UART通信,由于ota_bootloader存在自动波特率检测问题,建议使用波特率不超过19200bps,或者在ota_bootloader代码中定义固定波特率,例如115200。
2.3 引导加载程序 DCD 注意事项
一些用户将 ota_bootloader 与其自己的应用程序配合使用,该应用程序使用外部 SDRAM,他们发现虽然下载成功,但引导后应用程序无法正常运行。在应用程序代码中,虽然添加了 DCD 配置,但由于 ota_bootloader 已经位于 QSPI 的前面,应用程序会使用 ota_hdr,这会删除 dcd 部分,因此,在这种情况下,用户可以在 ota_bootloader 中添加 dcd。SDK 的 ota_bootloader 在默认情况下没有添加 dcd 部分。
现在,首先修改 ota_bootloader,然后准备 sdram 应用程序并进行测试。
2.3.1 Ota_bootloader add dcd
2.3.1.1 添加 dcd 文件
ota_bootloader 添加 dcd.c 和 dcd.h 这两个文件,可从 SDK 的 hello_world 项目中找到。将这两个文件复制到 ota_bootloader 的 board 文件夹中。从 dcd.c 代码中可以看到,dcd_data [] 数组存放在 “.boot_hdr.dcd_data” 区域,并且需要定义预处理器:
XIP_BOOT_HEADER_DCD_ENABLE=1
2.3.1.2 添加 dcd 链接器代码
修改 MCUXpresso IDE 的 ld 文件,并添加 dcd 范围。
.ivt : AT(ivt_begin)
{
. = 0x0000 ;
KEEP(* (.boot_hdr.ivt)) /* ivt section */
. = 0x0020 ;
KEEP(* (.boot_hdr.boot_data)) /* boot section */
. = 0x0030 ;
KEEP(*(.boot_hdr.dcd_data))
__boot_hdr_end__ = ABSOLUTE(.) ;
. = 0x1000 ;
} > m_ivt
6.jpg
图6
0x60001000 : IVT
0x6000100c:DCD入口点
0x60001020:引导数据
0x60001030:DCD详细数据
2.3.1.3 添加 IVT dcd 入口点
ota_bootloader->MIMXRT1062 文件夹 ->hardware_init_MIMXRT1062.c,修改 image_vector_table,将 DCD 地址填充到 dcdc_data 数组地址作为 dcd 入口点。
7.jpg
图7
至此,完成了 ota_bootloader 的 dcd 添加,构建项目,生成镜像,可以发现 DCD 已添加到 ota_bootloader 镜像中。
8.jpg
图8
DCD 入口点在 IVT 中正确,且 DCD 数据正确,我们可以将修改后的 ota_bootloader 烧录到 MIMXRT1060-EVK 开发板上。
2.3.2 准备 SDRAM 应用程序
仍以 evkmimxrt1060_iled_blinky 项目为基础,只需将一些函数放入 SDRAM 中。从内存中可以发现,SRAM 在 RAM4 中:
9.jpg
图9
在 led_blinky.c 中,添加以下头文件:
#include
然后,将 systick 延迟代码放入 RAM4,也就是 SDRAM 区域。
__RAMFUNC(RAM4) void SysTick_DelayTicks(uint32_t n)
{
g_systickCounter = n;
while (g_systickCounter != 0U)
{
}
}
现在,我们已经完成了简单的 SDRAM 应用程序,也可以对其进行测试,并在 SysTick_DelayTicks 中设置断点,可以发现地址也是与 SDRAM 相关的地址,生成 evkmimxrt1060_iled_blinky1_SDRAM_0x60040000.bin。
如果使用旧的 ota_bootloader 下载此 .bin 文件,可以发现 LED 没有闪烁。
2.3.3 测试结果
参考 2.2 节 ISP 测试相关命令,使用新修改的 ota_bootloader 项目下载 evkmimxrt1060_iled_blinky1_SDRAM_0x60040000.bin,可以发现复位后 LED 会闪烁。因此,SDRAM 应用程序与修改后的 ota_bootloader 能够正常工作。
3 OTA 引导加载程序的交换和回滚
OTA 引导加载程序可以实现交换和回滚功能,本部分将测试 ota_bootloader 的交换和回滚,准备两个应用程序并下载到不同的分区区域,然后使用 UART 输入字符来选择交换或回滚功能,以查看当前运行的是哪个应用程序。
3.1 内存映射
ota 引导加载程序的内存信息。
10.jpg
图10
以上映射基于外部 8Mbyte QSPI 闪存。
OTA引导加载程序:RT SDK ota引导加载程序代码
Boot meta 0:包含 3 个分区的起始地址、大小等信息,ISP 外设信息。
Boot meta 1:包含3个分区的起始地址、大小等信息,以及ISP外设信息。
Swap meta 0:引导加载程序将使用元数据执行交换操作
Swap meta 1:引导加载程序将使用元数据执行交换操作
分区 1:APP1 位置
Partition 2:APP2 所在位置
Scratch part:APP1 的备份位置,起始点在 0x60441000 之前,足以存放 APP1 和多个扇区大小,例如,APP1 为 0X5410,扇区大小为 0x1000,APP1 需要 6 个扇区,因此临时区域的起始地址为 0x60441000-0x6000=0x43b000。
用户数据:用户使用的数据区域
3.2 交换和回滚基础
11.jpg
图11
位于 partition1 和 partition2 中的 APP1 和 APP2 需要包含满足引导加载程序要求的 ota_header,引导加载程序会检查应用程序的 CRC,如果检查通过,则会引导该应用程序,否则,会进入 ISP 模式。Partition2 镜像需要有有效的头部,否则,交换将会失败。
交换功能会擦除 partition2 的临时区域,然后将 partition1 的代码放入临时区域,擦除 partition1 的位置,并将 partition2 的镜像写入 partition1 的位置。
回滚功能会运行之前的 APP1,擦除 partition2 的位置,将 partition1 的镜像复制回 partition2,擦除 partition1 的位置,将 partition2 临时区域的镜像复制回 partition1。
3.2.1 启动元数据
boot_meta 0: 0x0x6003c000 size: 0x20c
boot_meta 1: 0x0x6003d000 size: 0x20c
OTA 引导加载程序可以从两个不同的地址读取引导元数据,当两个地址的元数据都有效(标签为 'B'、'L'、'M'、'T')时,引导加载程序会选择版本号较大的元数据。如果两个元数据都无效,引导加载程序会将默认的引导元数据复制到 boot meta 0 地址。
引导元数据包含 3 个分区的起始地址、大小等信息,以及 ISP 外设信息。SDK 演示程序可以调用引导加载程序 API 来获取分区信息,然后进行镜像编程。
Boot meta 还包含 ISP 外设信息、超时(5秒)信息,结构为:
//!@brief Partition information table definitions
typedef struct
{
uint32_t start; //!< Start address of the partition
uint32_t size; //!< Size of the partition
uint32_t image_state; //!< Active/ReadyForTest/UnderTest
uint32_t attribute; //!< Partition Attribute - Defined for futher use
uint32_t reserved[12]; //!< Reserved for future use
} partition_t;
//!@brief Bootloader meta data structure
typedef struct
{
struct
{
uint32_t wdTimeout;
uint32_t periphDetectTimeout;
uint32_t enabledPeripherals;
uint32_t reserved[12];
} features;
partition_t partition[kPartition_Max];//16*4*7 bytes
uint32_t meta_version;
uint32_t patition_entries;
uint32_t reserved0;
uint32_t tag;
} bootloader_meta_t;
3.2.2 swap meta
交换元数据 0:0x6003e000,大小 0x50
交换元数据 1:0x6003f000,大小 0x50
OTA 引导加载程序会从两个不同的位置读取交换元数据,如果无效,引导加载程序会将默认数据设置到 swap meta 0(0x6003e000)。如果两个镜像都有效,引导加载程序会选择版本号较大的元数据。
引导加载程序会参考元数据执行交换操作,有时复位后,元数据会自动修改。这主要取决于 swap_type:
kSwapType_ReadyForTest:复位后,执行交换操作。
将 meta swap_type 修改为 kSwapType_Test。
复位后,由于元数据为 kSwapType_Test,引导加载程序可执行回滚操作。
kSwapType_Test:重置后,执行回滚
操作完成后,swap_type 更改为 kSwapType_None。
kSwapType_Rollback
引导加载程序会将 kSwapType_Test 写入元数据,复位后,引导加载程序会参考 kSwapType_Test 执行操作。
kSwapType_Permanent
重置后,将元数据修改为kSwapType_Permanent,然后APP将从分区1启动。
交换结构:
//!@brief Swap progress definitions
typedef struct
{
uint32_t swap_offset; //!< Current swap offset
uint32_t scratch_size; //!< The scratch area size during current swapping
uint32_t swap_status; // 1 : A -> B scratch, 2 : B -> A
uint32_t remaining_size; //!< Remaining size to be swapped
} swap_progress_t;
typedef struct
{
uint32_t size;
uint32_t active_flag;
} image_info_t;
//!@brief Swap meta information, used for the swapping operation
typedef struct
{
image_info_t image_info[2]; //!< Image info table
#if !defined(BL_FEATURE_HARDWARE_SWAP_SUPPORTED) || (BL_FEATURE_HARDWARE_SWAP_SUPPORTED == 0)
swap_progress_t swap_progress; //!< Swap progress
#endif
uint32_t swap_type; //!< Swap type
uint32_t copy_status; //!< Copy status
uint32_t confirm_info; //!< Confirm Information
uint32_t meta_version; //!< Meta version
uint32_t reserved[7]; //!< Reserved for future use
uint32_t tag;
} swap_meta_t;
3.3 常用的API
Bootloader提供了API供客户使用,常用的API有:
3.3.1 update_image_state
更新交换元数据,更新前会检查 partition1 的镜像是否有效,若镜像无效,则不更新交换元数据,并返回失败。
3.3.2 get_update_partition_info
获取分区信息,然后定义映像程序地址。
3.3.3 get_image_state
获取当前启动映像状态。
无/永久/UnderTest
3.4 Swap回滚APP准备
准备两个应用程序:APP1 和 APP2 的 bin 文件,并通过 USB HID 下载到分区 1 和分区 2。复位后,默认运行 APP1,然后通过 COM 输入选择交换和回滚功能。
代码是:
int main(void)
{
char ch;
status_t status;
/* Board pin init */
BOARD_InitPins();
BOARD_InitBootClocks();
/* Update the core clock */
SystemCoreClockUpdate();
BOARD_InitDebugConsole();
PRINTF("\r\n------------------hello world + led blinky demo 2.------------------\r\n");
PRINTF("\r\nOTA bootloader test...\r\n"
"1 - ReadyForTest\r\n"
"3 - kSwapType_Permanent\r\n"
"4 - kSwapType_Rollback\r\n"
"5 - show image state\r\n"
"6 - led blinking for 5times\r\n"
"r - NVIC reset\r\n");
// show swap state in swap meta
get_image_swap_state();
/* Set systick reload value to generate 1ms interrupt */
if (SysTick_Config(SystemCoreClock / 1000U))
{
while (1)
{
}
}
while(1)
{
ch = GETCHAR();
switch(ch)
{
case '1':
status = bl_update_image_state(kSwapType_ReadyForTest);
PRINTF("update_image_state to kSwapType_ReadyForTest status: %i\n", status);
if (status != 0)
PRINTF("update_image_state(kSwapType_ReadyForTest): failed\n");
else
NVIC_SystemReset();
break;
case '3':
status = bl_update_image_state(kSwapType_Permanent);
PRINTF("update_image_state to kSwapType_Permanent status: %i\n", status);
if (status != 0)
PRINTF("update_image_state(kSwapType_Permanent): failed\n");
else
NVIC_SystemReset();
break;
case '4':
status = bl_update_image_state(4); //
PRINTF("update_image_state to kSwapType_Rollback status: %i\n", status);
if (status != 0)
PRINTF("update_image_state(kSwapType_Rollback): failed\n");
else
NVIC_SystemReset();
break;
case '5':
// show swap state in swap meta
get_image_swap_state();
break;
case '6':
Led_blink10times();
break;
case 'r':
NVIC_SystemReset();
break;
}
}
}
下载APP时,您需要在前0x400区域使用正确的ota_header,否则swap将会失败。
const boot_image_header_t ota_header = {
.tag = IMG_HDR_TAG,
.load_addr = ((uint32_t)&ota_header) + BL_IMG_HEADER_SIZE,
.image_type = IMG_TYPE_XIP,
.image_size = 0,
.algorithm = IMG_CHK_ALG_CRC32,
.header_size = BL_IMG_HEADER_SIZE,
.image_version = 0,
.checksum = {0xFFFFFFFF},
};
这是一个正确的示例:
12.jpg
图12
镜像大小和校验和需使用应用程序镜像的实际信息,附件中提供了一个 image_header_padding.exe,它可以输入无 ota 头部的镜像,然后输出在前 0x400 范围内添加了包含镜像大小和镜像 CRC 数据的 ota 头部的完整镜像。
3.5 测试步骤和结果
准备无头部的 APP1 镜像 evkmimxrt1060_APP1_0X60040400.bin、APP2 镜像 evkmimxrt1060_APP2_0X60240400.bin,并将 blhost.exe、image_header_padding.exe 放在同一文件夹中。APP1 和 APP2 仅 printf 版本不同,一个为版本 1,另一个为版本 2。
printf 结果:
你好,世界 + LED 闪烁演示 1
你好,世界 + LED 闪烁演示 2
附带的 OTAtest 文件夹用于测试,但需从以下链接下载 blhost.exe,并将 blhost.exe 复制到 OTAtest 文件夹中。
https://www.nxp.com/webapp/sps/download/license.jsp?colCode=blhost_2.6.6&appType=file1&DOWNLOAD_ID=null
然后运行以下 bat 命令:
image_header_padding.exe evkmimxrt1060_APP1_0X60040400.bin 0x60040400
sleep 20
blhost.exe -t 50000 -u 0x15a2,0x0073 -j -- get-property 1 0
sleep 20
blhost.exe -u -t 1000000 -- flash-erase-region 0x6003c000 0x4000
sleep 50
blhost -u -t 5000 -- flash-erase-region 0x60040000 0x10000
sleep 50
blhost -u -t 5000 -- write-memory 0x60040000 boot_img_crc32.bin
sleep 100
image_header_padding.exe evkmimxrt1060_APP2_0X60240400.bin 0x60040400
sleep 20
blhost -u -t 5000 -- flash-erase-region 0x60240000 0x10000
sleep 50
blhost -u -t 5000 -- flash-erase-region 0x6043b000 0x10000
sleep 50
blhost -u -t 5000 -- write-memory 0x60240000 boot_img_crc32.bin
sleep 100
pause
其功能是生成带有正确 ota 头部的 APP1,擦除分区 1,将 APP1 编程到分区 1,生成带有正确 ota 头部的 APP2,擦除分区 2 和临时区域,将 APP2 编程到分区 2。
运行 .bat 文件需在复位后 5 秒内进行,然后使用 ISP 连接:
blhost.exe -t 50000 -u 0x15a2,0x0073 -j -- get-property 1 0
ota_bootloader 可通过 ota_bootloader 项目直接下载到 0X60000000 区域。
下载后,重置芯片,等待 5 秒钟,APP 将会运行。
这是测试结果:
13.jpg
图13
从测试结果可以看出,首次启动时,运行 APP1,镜像状态为:无
输入 1,执行交换,会发现运行 APP2,镜像状态为:测试中
输入3,选择永久,重置后仍能找到,APP2仍在运行,图像状态:永久
输入 4,选择回滚,复位后会发现运行 APP1,镜像状态为:无
到目前为止,请完成 swap 和 rollback 功能。
输入 6,您会发现 APP 包含 SDRAM 指示灯闪烁功能正在运行。
i.MXRT 106x 回复:RT1060 OTA 引导加载程序的 ISP 及交换回滚用法 一些客户还需要 IAR 版本,因此在此附上 IAR 应用程序版本。
基于 led_blinky IAR 项目,修改如下:
1. 将 ota_bootlaoder_board.h、ota_bootloader_hrd.c、ota_bootloader_supp.c、ota_bootloader_supp.h 复制到源文件夹
2. 删除 XIP 文件夹。
3. 在 led_blinky.c 中添加:
#include "ota_bootloader_supp.h"
4. MIMXRT1062xxxxx_flexspi_nor.icf 修改如下:
1.jpg
/*
** ###################################################################
** Processors: MIMXRT1062CVJ5A
** MIMXRT1062CVL5A
** MIMXRT1062DVJ6A
** MIMXRT1062DVL6A
**
** Compiler: IAR ANSI C/C++ Compiler for ARM
** Reference manual: IMXRT1060RM Rev.1, 12/2018 | IMXRT1060SRM Rev.3
** Version: rev. 0.1, 2017-01-10
** Build: b210227
**
** Abstract:
** Linker file for the IAR ANSI C/C++ Compiler for ARM
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2021 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail:
[email protected]
**
** ###################################################################
*/
define symbol m_ota_boot_hdr_start = 0x60040000;
define symbol __ram_vector_table_size__ = isdefinedsymbol(__ram_vector_table__) ? 0x00000400 : 0;
define symbol __ram_vector_table_offset__ = isdefinedsymbol(__ram_vector_table__) ? 0x000003FF : 0;
define symbol m_interrupts_start = 0x60040400;
define symbol m_interrupts_end = 0x600407FF;
define symbol m_text_start = 0x60040800;
define symbol m_text_end = 0x6023FFFF;
define symbol m_interrupts_ram_start = 0x20000000;
define symbol m_interrupts_ram_end = 0x20000000 + __ram_vector_table_offset__;
define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__;
define symbol m_data_end = 0x2001FFFF;
define symbol m_data2_start = 0x20200000;
define symbol m_data2_end = 0x202BFFFF;
define symbol m_qacode_start = 0x00000000;
define symbol m_qacode_end = 0x0001FFFF;
/* Sizes */
if (isdefinedsymbol(__stack_size__)) {
define symbol __size_cstack__ = __stack_size__;
} else {
define symbol __size_cstack__ = 0x0400;
}
if (isdefinedsymbol(__heap_size__)) {
define symbol __size_heap__ = __heap_size__;
} else {
define symbol __size_heap__ = 0x0400;
}
define exported symbol __NCACHE_REGION_START = m_data2_start;
define exported symbol __NCACHE_REGION_SIZE = 0x0;
define exported symbol __VECTOR_TABLE = m_interrupts_start;
define exported symbol __VECTOR_RAM = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start;
define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__;
define memory mem with size = 4G;
define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end]
| mem:[from m_text_start to m_text_end];
define region QACODE_region = mem:[from m_qacode_start to m_qacode_end];
define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__];
define region DATA2_region = mem:[from m_data2_start to m_data2_end];
define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end];
define block CSTACK with alignment = 8, size = __size_cstack__ { };
define block HEAP with alignment = 8, size = __size_heap__ { };
define block RW { readwrite };
define block ZI { zi };
define block NCACHE_VAR { section NonCacheable , section NonCacheable.init };
define block QACCESS_CODE { section CodeQuickAccess };
initialize by copy { readwrite, section .textrw, section CodeQuickAccess };
do not initialize { section .noinit };
place at address mem: m_interrupts_start { readonly section .intvec };
place at address mem:m_ota_boot_hdr_start { object ota_bootloader_hdr.o };
keep { object ota_bootloader_hdr.o };
place in TEXT_region { readonly };
place in DATA_region { block RW };
place in DATA_region { block ZI };
place in DATA_region { last block HEAP };
place in DATA_region { block NCACHE_VAR };
place in CSTACK_region { block CSTACK };
place in QACODE_region { section .textrw};
place in QACODE_region { block QACCESS_CODE };
然后构建项目,以获取 evkmixrt1060_iled_blinky_ota_0x60040000_iar.bin 文件。
下载 ota_bootloader 后,在板子复位后使用 blhost 进行连接:
C:\KerryPC\IMXRTCode\Question\RT1060\bootloader\AN12604\kerry\OTAtest>blhost.exe -t 50000 -u 0x15a2,0x0073 -j -- get-property 1 0
{
"command" : "get-property",
"response" : [ 1258424320 ],
"status" : {
"description" : "0 (0x0) Success.",
"value" : 0
}
}
C:\KerryPC\IMXRTCode\Question\RT1060\bootloader\AN12604\kerry\OTAtest>blhost.exe -t 2048000 -u 0x15a2,0x0073 -j -- flash-erase-region 0x60040000 0x6000 9
{
"command" : "flash-erase-region",
"response" : [],
"status" : {
"description" : "0 (0x0) Success.",
"value" : 0
}
}
C:\KerryPC\IMXRTCode\Question\RT1060\bootloader\AN12604\kerry\OTAtest>blhost.exe -t 5242000 -u 0x15a2,0x0073 -j -- write-memory 0x60040000 evkmixrt1060_iled_blinky_ota_0x60040000_iar.bin
{
"command" : "write-memory",
"response" : [],
"status" : {
"description" : "0 (0x0) Success.",
"value" : 0
}
}
在原始帖子中找到 iar 应用程序。