本帖最后由 SJUMP 于 2024-8-23 11:02 编辑
首先生成了一个 .bin 文件,然后使用上位机C语言,在.bin 前面加了 4K 的头部字节,参考:BSP视频教程第19期:单片机BootLoader的AES加密实战,含上位机和下位机代码全开源_哔哩哔哩_bilibili。然后下载进去,发现程序能正常跳转到 app 运行,但是在详细测试的时候,发现某些函数指针的返回不正常,本来指针返回出来应该是 2 ,结果编程了0。
做了以下几种尝试(下面都是使用的同一个 bin 文件):
1. 放弃头部,直接下载 bin 固件到指定地址,所有函数能正常返回。
2. 先下载头部进去,不擦出 flash ,再把 .bin 文件下载到指定地址,所有函数能正常返回。
3.将 bin 文件和 头部先组合到一起再下载进去,能运行,但是某些函数返回值不正常。
在 3 的情况下 使用 二进制对比软件看了,除了 头部 4k 不一样,后面的字节全部都是一样的。
异常情况下寄存器值:
异常情况下,进入函数前寄存器值
异常情况下,退出函数后寄存器值
正常情况下寄存器的值:
正常情况下,进入函数前寄存器值
正常情况下,退出函数后寄存器值
在 map 文件里面找到 R3 的地址:
[C] 纯文本查看 复制代码 #define SET_VECTOR_TABLE (1)
#define ENABLE_INT() __set_PRIMASK(0)
#define DISABLE_INT() __set_PRIMASK(1)
void jump_to_app(uint32_t app_boot_address)
{
uint32_t i=0;
static void (*SysMemBootJump)(void);
static __IO uint32_t BootAddr;
BootAddr = app_boot_address+CODE_BEGIN_OFFSET;
DISABLE_INT();
/* 关闭滴答定时器,复位到默认值 */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/* 设置所有时钟到默认状态,使用 HSI 时钟 */
HAL_RCC_DeInit();
HAL_DeInit();
/* 关闭所有中断,清除所有中断挂起标志 */
for (i = 0; i < 8; i++)
{
NVIC->ICER[i]=0xFFFFFFFF;
NVIC->ICPR[i]=0xFFFFFFFF;
}
/* 使能全局中断 */
ENABLE_INT();
/* 跳转到系统 BootLoader,首地址是 MSP,地址+4 是复位中断服务程序地址 */
SysMemBootJump = (void (*)(void)) (*((uint32_t *) (BootAddr + 4)));
#if(SET_VECTOR_TABLE)
SCB->VTOR = BootAddr;
#endif
/* 设置主堆栈指针 */
__set_MSP(*(uint32_t *)BootAddr);
/* 在 RTOS 工程,这条语句很重要,设置为特权级模式,使用 MSP 指针 */
__set_CONTROL(0);
/* 跳转到系统 BootLoader */
SysMemBootJump();
/* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
while (1)
{
}
}
|