我的 BOOT起始从 0x0800 0000 ~~ 0x08002800
APP 从 0x08002800 ~~ 0x08008C00
updata 从 0x08008C00 ~~ 0x0800F000
当我的 程序从BOOT跳转到APP中运行 ,我在APP中接收更新文件放到updata,使用NVIC_SystemReset()复位,为啥程序没有重新从boot开始运行,而是还是重新从APP区开始运行程序,这是什么原因呢,请大佬答疑解惑
我的 BOOT起始从 0x0800 0000 ~~ 0x08002800
APP 从 0x08002800 ~~ 0x08008C00
updata 从 0x08008C00 ~~ 0x0800F000
当我的 程序从BOOT跳转到APP中运行 ,我在APP中接收更新文件放到updata,使用NVIC_SystemReset()复位,为啥程序没有重新从boot开始运行,而是还是重新从APP区开始运行程序,这是什么原因呢,请大佬答疑解惑
您好,
从您描述的地址上看,应该是自己实现了一个boot,使用软件复位,在系统初始化后,会从用户区的首地址开始执行,也就是您自己实现的boot功能。
您在boot中使用了什么方式判断停留在该区域还是跳转至用户区(或其他功能)呢?排查这个问题最简单的方法是通过串口打印观察软件的运行,在进入不同的区域后,立即输出标志位信息与当前所处的区域。当然,也可以通过仿真的方式进行排查,具体方法可以参考链接中的博客。https://blog.csdn.net/qq_36353650/article/details/127403408?spm=1001.2014.3001.5501
是的,我在APP中更新完程序后,重启在BOOT读取BIN文件的前8个字节,我在STM32中会?
这样判断一下我的更新文件的程序指针和堆栈指针
if ((tmp32 & 0xffff0000) != 0x20000000)? ?//前面4字节为堆栈指针
? ? {
//? ? ? ? printf("堆栈指针不在RAM内");
? ? ? ? USART_SendByte(USART1,0x06);
? ? ? ? return 1;
? ? }
? ? tmp32 = *(uint32_t*)&out[4];
? ? if ((tmp32 & 0xfffc0000) != 0x08000000)
? ? {
//? ? ? ? printf("程序指针不在FLASH内");
? ? ? ? USART_SendByte(USART1,0x07);
? ? ? ? return 1;
? ? }
但是CH32V203我看生成的BIN文件前面8个字节,好像并不是程序指针和堆栈指针,所以我就这样判断,我看启动文件
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00100073
我就判断这些开头
tmp32 = *(uint32_t*)&out[4];? (BIN文件的 4-8位)? ?
? ? if ((tmp32 & 0x000000ff) != 0x00000013)? ? ? ? ?//判断程序指针是否在FLASH中
? ? {
? ? ? ? return 2;
? ? }
再判断
? ? if ((tmp32 & 0x000000ff) != 0x00000013)? ? ? ? ?//判断文件最后两位特征值
? ? {
? ? ? ? return 3;
? ? }
? ? tmp32 = *(uint32_t*)&out[4];
? ? if ((tmp32 & 0x000000ff) != 0x00000073)? ? ??
? ? {
? ? ? ? return 4;
? ? }
程序就从这里跳出了,重新回到APP区开始执行,所以我如果想判断程序指针和堆栈指针应该怎么办
您好,
V203的内核为RISC-V,编译结束后的bin可能与ST的会有些差别,建议您在Flash中存储一个标志位,当标志位变化时再动作,您也可以考虑讲该标志存储在用户选择字中,防止在操作Flash时误擦除。