当前方案
硬件
- i.MX RT1052CVL5B
- IS42S16160J 32MB SDRAM
- W25Q256JV 32MB QSPI NOR Flash (用于XIP)
操作系统:RT-Thread (bootloader和app都是)
固件
镜像结构:
通过修改编译链接文件,使bootloader和app镜像按照如上分部。目前已完成了从bootloader 跳转到app,app目前运行正常,不过app目前功能比较单一,就运行了个串口命令行系统: ```bash\ | /
- RT - Thread Operating System / | \ 4.1.0 build May 27 2022 18:12:44 2006 - 2022 Copyright by RT-Thread team Here is boot.[I/main] Firmware Download Complete,Jump App.
\ | /
- RT - Thread Operating System / | \ 4.1.0 build May 29 2022 20:51:39 2006 - 2022 Copyright by RT-Thread team msh >This’s app This’s app This’s app This’s app
<a name="YWFnG"></a>
## 问题
- 问题1:FDCB 、IVT 、BD 、DCD 四个区域的数据如果后续norflash,sdram 配置不变,bootloader入口地址不变更的情况下, 是不是只需烧录一次即可,后续无需重复烧写?(目前我就是初始的时候烧写一次,后面调试bootloader以及app就没再管这些XIP HEADER)
- 问题2:在做bootloader和app时,查阅了NXP官方仓库的bootloader及firmware项目: [sbl(点击查看)](https://github.com/NXPmicro/sbl) 、[sfw(点击查看)](https://github.com/NXPmicro/sfw) ,跳转相关的代码 :
```c
/* The bootloader of MCUboot */
void do_boot(struct boot_rsp *rsp)
{
uintptr_t flash_base;
int rc;
/* The beginning of the image is the ARM vector table, containing
* the initial stack pointer address and the reset vector
* consecutively. Manually set the stack pointer and jump into the
* reset vector
*/
rc = flash_device_base(rsp->br_flash_dev_id, &flash_base);
assert(rc == 0);
vt = (struct arm_vector_table *)(flash_base +
rsp->br_image_off +
#ifdef MCUBOOT_SIGN_ROM
HAB_IVT_OFFSET +
#endif
rsp->br_hdr->ih_hdr_size);
cleanup();
__set_MSP(vt->msp);
__set_CONTROL(0);
((void (*)(void))vt->reset)();
}
针对此代码片段有几个问题:
- 问题2.1: L22 中
cleanup();
在上面定义为了弱函数(详见此处),应该是需要用户自行实现的,那么此处一般将什么样的操作放在cleanup中呢? - 问题2.2: 在跳转之前系统只做了两件事:一是找到向量表并将MSP设置过去
__set_MSP(vt->msp);
,第二就是__set_CONTROL(0);
特权模式+MSP。跳转之前不需要做一些其他操作?比如,关闭中断、清理中断标志位、复位systick、外设进行复位等等。
问题3:通常进入app后需要重新对于中断向量表进行设置,但是在sfw(点击查看)并未发现偏移中断向量表的操作,是不是启动文件通过下述汇编代码操作了?(我追踪了一下,应该是)
.equ VTOR, 0xE000ED08
ldr r0, =VTOR
ldr r1, =__Vectors
str r1, [r0]
问题4:在bootloader中刷app区域固件时,配置FlexSPI的话,必须配置的跟FDCB区域一样吗?比如更新了LUT,且更新后的LUT与FDCB中不兼容,是不是会导致XIP无法正常运行?
我看到sbl项目中:
status_t sbl_flash_init(void)
{
/* Update LUT table. */
FLEXSPI_UpdateLUT(EXAMPLE_FLEXSPI, 0, &customLUT[0], CUSTOM_LUT_LENGTH);
/* Do software reset. */
FLEXSPI_SoftwareReset(EXAMPLE_FLEXSPI);
return kStatus_Success;
}
修改了LUT之后也没有重新配置FlexSPI的 SeqNumbe以及seqIndex,只是FLEXSPI_SoftwareReset操作了以下,内核依然能从外部NORFLASH中读出固件并执行?其中原理希望能描述一下。感谢