首先是IAP STM32F103C8T6的flash是64k,每次擦除是1k 1、用串口接收APP的bin文件数据,然后写入内部的FLASH //appxaddr是要跳转的地址 设置是0x0800500 //appbuf是串口接收到的app的bin文件数据 //appsize是bin的大小 void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize) { u8 page = 0; u32 i =0; u16 *p = (u16 *)appbuf; page = FLASH_PagesMask(appsize); //得到要擦除的页数 printf("\r\n要擦除的数据页数:%d\r\n",page); FLASH_Unlock(); //解锁 for(i = 0; i < page; i++) { CPU_IntDis(); //关中断 FLASH_ErasePage(appxaddr+i*Page_Size); //一次擦除1024字节 CPU_IntEn(); //开中断 if(Flash_ReadHalfWord(appxaddr+i*Page_Size)!=0xffff) { printf("\r\n擦除出错.................\r\n"); } } for(i = 0; i < appsize; i=i+2) { FLASH_ProgramHalfWord(appxaddr + i,*p); //半字写入 if((Flash_ReadHalfWord(appxaddr +i) & 0xff)!=appbuf[i])//判断写入的是否正确 { FLASH_Lock(); printf("\r\n写入错误\r\n"); return ; } p++; } FLASH_Lock(); } 上面是把接收到串口的数据写入flash,写入的数据是没有错误的,通过读flash和app的bin文件做了比较 2、下面是跳转函数 typedefvoid (*iapfun)(void); //定义一个函数类型的参数. iapfun jump2app; void iap_load_app(u32 appxaddr)//appxaddr是0x08005000 { if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)//检查栈顶地址是否合法. { jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址) MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) jump2app(); //跳转到APP. } } 串口接收发送都是采用中断 每次在跳转的时候就会进入HardFault_Handler,不知道错在什么地方 app的设置如下 1、在魔法棒中设置app的起始地址为0x08005000 2、设置中断向量表SCB->VTOR = FLASH_BASE | 0x5000; 然后程序里面就是一个很简单的LED的闪烁, 每次在接收完成,把数据写入到flash之后再进行跳转就会进入HardFault_Handler,不知道那里有错, 这是之前我发的帖子 错误的原因是:我虽然设置了起始地址,但是没选择如下图,所以map里面的地址一直没改变,use memory哪里默认的不是勾选,应该把哪里勾选 文章图片 这样我的问题就解决了 ,有空再把bootloader的整体给写出来,,,这里个错误找了我3天时间 ,,好浪费啊希望可以帮助到其他人 文章图片 这样map就可以看到起始地址的改变了 |
- 【用STM32F103C8T6的做IAP时,在跳转时一直进入HardFault_Handler 解决方法】
推荐阅读
- stm32|基于STM32和freeRTOS智能门锁设计方案
- 日常分享|共享充电宝方案原理,具体部件组成以及主控MUC参数
- #|ARM裸机开发(汇编LED灯实验(I.MX6UL芯片))
- STM32|STM32的四种IO输出模式
- STM32 远程升级(ISP / IAP)
- stm32|stm32f103can总线过滤器配置
- STM32CubeMX配置SDIO模式(非DMA方式)
- STM32|如何建一个STM32F030标准库工程模板
- STM32 时钟RCC相关配置参考stm32f10x_rcc.h
- STM32 NVIC