IAP升级时跳转不成功,之前的例程重新编译后又不成功,经过三四天的调试发现如下问题:
1.在APP栈顶检测出错,栈顶要求20000000,通过变量输出APP栈顶为10000000,使用HWorks软件打开APP生成的Bin文件,第一行 70 04 00 10即为10000470栈顶(initial_sp=RW_data+ZI_data)位置,IAP跳转的第一个函数位置,APP栈顶地址与IAP设置不一致导致无法正常跳转;
由于我使用的是F4系列,KEIL设置存在两个SRAM区,APP程序较小取消IRAM2的勾选再次编译生成BIN文件,栈顶地址就是2000000开头的,下载跳转正常;
2.下载带FREE操作系统时,注意了以上问题,程序跳转正常,但是无法运行APP程序,经调试查询发现有以下两个重点重点:
一:IAP与APP的SystemClock_Config配置必须一模一样,我使用的是CubeMX创建工程,系统时钟比较直观,看到PLLQ倍频是没有使能的所以就没要求与APP一致,程序调试很久APP程序就是无法运行,由于APP程序参与的人比较多,所以决定还是修改IAP程序中的SystemClock_Config配置与APP一直,修改完后再次运行就正常了;
二:APP程序跳转正常无法运行还有一个重要原因是中断开关,操作系统是通过中断来调配CPU资源,IAP只开了一个串口接收中断,IAP中断在跳转APP程序时无法复位中断状态容易导致操作系统中断混乱无法正常运行(个人理解),所以在跳转APP程序时要手动关闭全局中断,在APP程序主函数main里面开启全局中断;其中一点容易忽略的是系统sys滴答中断,这个需要单独关闭,sys滴答为系统时钟中断,最高级中断;具体如下(IAP程序跳转前关闭SYS滴答时钟和全局中断 __disable_irq ();)
SysTick->CTRL = 0X00;//禁止SysTick
SysTick->LOAD = 0;
SysTick->VAL = 0;
__disable_irq ();
iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
APP在main函数中开启全局中断(sys滴答中断在初始化后会自动开启,无需单独开启中断)
main函数首行设置中断偏移,即APP地址偏移, __enable_irq ();开启全局中断;
int main(void)
{
/* USER CODE BEGIN 1 */
SCB->VTOR = FLASH_BASE | 0x8000;//设置偏移量
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
__enable_irq ();
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
以上经历希望能够帮助到一些人,如有错误或补充,欢迎大家评论表述!