我这边的是这样的:
分区:
1.boot 起始地址 0x8000000 大小 0x2000
2.app1 起始地址 0x8020000 大小 0x2000
3.app2 起始地址 0x8040000 大小 0x2000
逻辑:
boot只做app更新以及跳转,没有业务逻辑。
boot里面判断app1的最后一个uint32_t的值,如果不是更新状态就直接跳转到app1.
如果是更新状态是的话就擦除app1,然后复制app2到app1,再擦除app1,最后再跳转到app1.
app1里面有根据业务判断通过lwip将bin下载到app2。下载完成会在app1的最后位置写入一个uint_32的更新状态值,然后重启。
重启通过下面这个代码
[C] 纯文本查看 复制代码 /**
* @brief 复位重启
* @note
*/
void mcu_restart(void)
{
__disable_irq() ;
__set_FAULTMASK(1); //关闭所有中断
NVIC_SystemReset(); //复位
}
boot和app的RAM都是起始地址0x20000000,大小0x10000,这个共用有没有影响的?我没用那个分享加载。
boot里面只开了一个usart2用来打印调试信息。
app 没用os的,开了一些usart和定时器 搞了lwip,然后用了DWT做延迟。
就是在这个DWT初始化的时候出问题了 进HardFault_Handler。
这是boot里面的跳转函数,App_Addr就是app1的起始地址 0x8020000
[C] 纯文本查看 复制代码 /** @bieaf 程序跳转函数
* @return none 返回值
*/
void IAP_ExecuteApp (uint32_t App_Addr)
{
if (((*(__IO uint32_t *)App_Addr) & 0x2FFE0000) == 0x20000000) //检查栈顶地址是否合法.
{
uint32_t i=0;
void (*SysMemBootJump)(void); /* 声明一个函数指针 */
/* 关闭全局中断 */
DISABLE_INT();
/* 关闭滴答定时器,复位到默认值 */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/* 设置所有时钟到默认状态,使用HSI时钟 */
HAL_RCC_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 *) (App_Addr + 4)));
/* 设置主堆栈指针 */
__set_MSP(*(uint32_t *)App_Addr);
/* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */
__set_CONTROL(0);
/* 跳转到系统APP */
SysMemBootJump();
}
else
{
printf("There is None APP to jump,ERROR!!!\r\n");
}
/* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
}
app1里面就是在main方法开始加了中断向量表地址 偏移
[C] 纯文本查看 复制代码 SCB->VTOR = FLASH_BASE | Application_1_Addr;/* 更改中断向量表地址 偏移到APP1 地址 */
|