准备两个工程,1个BOOT,1个APP
1、FLASH刷写,boot将片内FLASH后面一半保存的新程序刷到前面一半,APP则是将通过通讯接口获取升级包,将升级包刷写到后一半的FLASH
//IAP写入
uint8_t IAP_Write(void)
{
uint16_t j;
uint32_t left_len,addr=0;
static uint16_t check_sum = 0;
static uint16_t flash_read_checknum;
uint8_t retry_time = 0;
left_len = System_Para.Filesize-4;
while(left_len)
{
if(left_len > 256)
{
Flash_Read_Data(addr,256,Prog_data);
addr += 256;
left_len = System_Para.Filesize-4-addr;
for(j=0;j<256;j++)
{
check_sum += Prog_data[j];
}
}
else
{
Flash_Read_Data(addr,left_len,Prog_data);
for(j=0;j<left_len;j++)
{
check_sum += Prog_data[j];
}
left_len = 0;
}
}
flash_read_checknum = Flash_Read_Byte(System_Para.Filesize-2);
flash_read_checknum = (flash_read_checknum<<8) + Flash_Read_Byte(System_Para.Filesize-1);
if(flash_read_checknum == check_sum)
{
//校验和正确
Flash_Read_Data(0,256,Prog_data);
if(((*(__IO uint32_t*)Prog_data) & 0x2FFE0000 ) != 0x20000000)
{
//程序错误,直接返回主程序
return 10;
}
}
else
{
//校验和错误,直接返回主程序
return 10;
}
total_data = System_Para.Filesize;
//擦除程序区,失败就返回0
if(FlashErase((uint32_t)PGM_START_ADDR)) //清除程序空间
{
//FLASH烧写擦除过程中失败,不能直接返回主程序,因为主程序已经没有代码了
return 0;
}
addr = 0;
left_len = total_data;
//开始写入程序
while(left_len)
{
if(left_len > 256)
{
Flash_Read_Data(addr,256,Prog_data);
for(j=0;j<256;j++)
{
Flash_WriteByte(addr+PGM_START_ADDR+j,Prog_data[j]);
while(*((volatile uint8_t*)addr+PGM_START_ADDR+j) != Prog_data[j])
{
retry_time ++;
delay1ms(10);
if(retry_time>10)
return 0;
}
delay100us(2);
}
addr += 256;
left_len = total_data-addr;
}
else //剩余不足256字节
{
Flash_Read_Data(addr,left_len,Prog_data);
for(j=0;j<left_len;j++)
{
Flash_WriteByte(addr+PGM_START_ADDR+j,Prog_data[j]);
while(*((volatile uint8_t*)addr+PGM_START_ADDR+j) != Prog_data[j])
{
retry_time ++;
delay1ms(10);
if(retry_time>10)
return 0;
}
delay100us(2);
}
left_len = 0;
}
}
return 10;
}
|