我正在 S32K148 上开发一个引导加载程序和应用程序设置。
当引导程序执行闪存擦除和应用程序复制时,跳转到应用程序不起作用。
然而
堆栈指针和RESET处理程序值看起来有效
应用程序矢量表正确
应用程序在没有引导程序的情况下也能正常运行
我没有在应用程序代码中明确启用看门狗
闪存擦除 + 复制后,在跳转到 S32K148 上的应用程序之前还需要哪些步骤?
谁能帮帮我?
我将链接文件脚本和跳转程序代码附在下面。
谢谢!
引导程序链接器文件
内存
{
int_flash_interrupts:ORIGIN = 0x00000000,长度 = 0x00000400 /* 1K */ /* 不要更改此部分 */ int_flash_config:ORIGIN = 0x00000400,长度 = 0x00000010 /* 16 字节 */ /* 不要更改此部分 */
int_flas
h:ORIGIN = 0x00000410,长度 = 0x00001101 bf0 /* 总计 128KB-0x410 = 引导加载程序代码为 0x1FBF0 字节 */ int_sram_results:ORIGIN = 0x1FF0000,长度 = 0x00000100 /* 256 字节 */ int_sram:ORIGIN = 0x1FF0100,长度 = 0x0003df00 /* ~248K */ int_sram_stack_stack_c0: ORIGIN = 0x2001E000,长度 = 0x
00001000 /* 4K */ r
am_rsvd2:ORIGIN = 0x2001F000,长度 = 0 /* SRAM 结束 */}
应用程序链接文件
内存
{
int_flash_intrupts:ORIGIN = 0x00022000,长度 = 0x00000400 /* 1K-0x00022000 处的应用程序中断向量 */ int_flash_config:ORIGIN = 0x00022400,长度 = 0x00022400,长度 = 0x00000010 /* 16 字节-应用程序
闪存配置 */ int_flash:ORIGIN = 0x00022410,长度 = 0x00063bf0 /* 400KB 应用程序区域(0x64000-0x410 = 0x63bf0 字节)*/ int_sram_results:ORIGIN = 0x1FF0000,长度 = 0x00000100 /* 256 字节 */
int_sram:ORIGIN = 0x1FF0100,长度 = 0x0003df00 /* ~248K */ int_sram_stack_c_c0: ORIGIN = 0x2001E000,长度 =
0x00001000 /* 4K */ r
am_rsvd2:ORIGIN = 0x2001F000,长度 = 0 /* SRAM 结束 */}
main.c
EraseApplication();
CopyApplication(DOWNLOADED_APP_START_ADDRESS,APPLICATION_START_ADDRESS,APPLICATION_SIZE);
jump_to_application();
跳转到应用程序()函数
void jump_too_application(void)
{
uint32 app_msp;
application_entry_t app_reset_handler;
/* 跳转前打印信息 */
// printf("跳转到 application\r\n");
/*
// volatile uint32 delay = 100000U;
// while(delay--);
/* 禁用所有中断 */
__asm volatile ("cpsid i");
/* 将向量表偏移量设置为应用程序的向量表 */
S32_SCB->VTOR = APPLICATION_START_ADDRESS;
/* 从向量表的第一个字加载应用程序的 MSP */
app_msp = *((volatile uint32*)APPLICATION_START_ADDRESS);
/* 从向量表的第二个字加载应用程序的 Reset_Handler 地址 */
app_reset_handler = (application_entry_t)(*((volatile uint32*)(APPLICATION_START_ADDRESS + 4U));
/* 设置指向应用程序 MSP 的堆栈指针 */
__asm volatile ("msr msp,%0": :"r" (app_msp));
// /* Memory barrier */
//__asm volatile ("dsb");
// __asm volatile ("isb");
/* 跳转到应用程序的 Reset_Handler */
app_reset_handler();
/* 不应到达此处 */
while(1)
{
/* 无限循环 */
}
}
请注意,在圣诞假期期间,我们的支持响应时间可能会比平时长。在某些情况下,您的请求可能会在新年后得到处理。感谢您的理解。
嗨,@kavyakoney、
可能存在闪存访问碰撞,因为引导加载程序和应用程序目前都放在 S32K148 的闪存块 0 中。
S32K148 设备包含三个 512 KB 闪存块(方块 0、块 1、块 2)。闪存编程操作(擦除/编程)只能在 CPU 不执行代码的块上进行。
如果引导加载程序从 0 块运行,并试图擦除或编程也在 0 块内的内存,内核可能会执行无效数据,从而无法正确跳转到应用程序。
为避免出现这种情况,应将应用程序放入闪存块 1 或闪存块 2,而将引导加载程序完全放在闪存块 0 中。
谢谢!
BR,丹尼尔