直接放代码
#include "stm32f1xx.h"
typedef void (*pFunction)(void);
/*!
* @brief 跳转到应用程序段
* @param app_addr: 用户代码向量表的起始地址
* @retval: 无
*/
void jump_to_app(uint32_t app_addr)
{
if (((app_addr & 0xFF000000) == 0x08000000) && // 确保在Flash范围内
// 注意:这里不再检查堆栈指针是否在RAM范围内,因为堆栈指针的值本身就是RAM地址
// 但你可以根据实际需求添加其他验证逻辑
true) // 假设其他验证都通过(这里简化为true)
{
// 读取堆栈指针(MSP)的值
uint32_t msp = *(__IO uint32_t*)app_addr;
// 读取复位向量的地址
uint32_t reset_vector = *(__IO uint32_t*)(app_addr + 4);
// 设置MSP
__set_MSP(msp);
// 跳转到复位向量
pFunction jump_to_application = (pFunction)reset_vector;
jump_to_application();
}
else
{
// 错误处理:无效的应用程序地址
// 可以添加一些代码来处理这种情况,比如进入一个错误循环或重置设备
}
}
#define FLASH_JUMP_ADDR (0x08008000) // 假设这是用户应用程序向量表的起始地址
int main(void)
{
/*
初始化程序省略.....
*/
// 检查FLASH_JUMP_ADDR是否在Flash范围内
if ((FLASH_JUMP_ADDR & 0xFF000000) == 0x08000000)
{
jump_to_app(FLASH_JUMP_ADDR); // 跳转到应用程序
}
else
{
// 错误处理:无效的Flash起始地址
// ...
}
while (1)
{
// 如果未跳转到应用程序,则执行这里的循环(但通常不会到达这里)
}
}
该程序本人亲测有效,你是用的时候只需要简单的步骤即可
1、替换头文件#include "stm32f1xx.h" 替换为你自己芯片
2、将jump_to_app(uint32_t app_addr)整个函数全部复制到你的Bootload中
3、在主函数中调用该函数,记得要验证地址是否有效(你可能多输入或者少输入几个0)
注意*烧录bootload方法就不介绍了,不懂得自己去搜。
最后贴一个效果图,我的bootload会通过串口打印“进入BOO”,我的主函数会打印“进入app”
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2024/7/12
更新一下,这个跳转程序在CubeMx生成的MDK中可以直接使用,但是如果使用标准库却不行,本人研究了半天都没有找到错误,感谢大佬指点,标准库要将system_stm32f4xx.c中的VECT_TAB_OFFSET设置为偏移值。
之前SBC->VTOR = FLASH_BASE | VECT_TAB_OFFSET被误导了,实际该值在初始化时就被设置了,后面修改也不会在进入中断向量表(个人理解,如有不对还请大佬指出)。
为什么HAL库可以等我再研究一下,有消息第一时间更新