首先是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、下面是跳转函数
typedef void (*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,不知道那里有错,
|