更新文件存储地址定义
#define FLASH_SECTION (4096u) /*扇区大小*/
#define FLASH_PAGE (256u) /*页大小*/
#define FLASH_SIZE (8 * 1024 * 1024)
#define FLASH_ADDR_BASE (0x80000000)/*Flash区域的偏移地址*/
#define FLASH_SAV_SIZE 0x00040000 //256K
#define FLASH_SAV_ADDR_OLD (FLASH_SIZE - FLASH_SAV_SIZE)
#define FLASH_SAV_ADDR_NEW (FLASH_SIZE - FLASH_SAV_SIZE * 2)
#define SU_BUF_LEN 1024
1、通过USB升级
USHORT Update_USB()
{
BYTE FileID;
SYS_VER Version;
UINT WriteAddr;
if (USB_Init() == 0)
{
FileID = USB_Open("App.bin", 0);
if (FileID == 0)
{
printf("Open USB error\n");
return ERR_READ_FILE;
}
USB_Seek(FileID, SYS_HEADER_OFFSET + 8);
USB_Read(FileID, (BYTE*)&Version, sizeof(SYS_VER));
DisplayVersion(&Version);
//compare the new & old version
if (Version.ProjID[0] != PROJECT_ID[0])
{
printf("Update file version error...\n");
USB_Close(FileID);
return ERR_DAT_PARA;
}
printf("Update file copying...\n");
WriteAddr = FLASH_SAV_ADDR_NEW;
USB_Seek(FileID, 0);
while(USB_Read(FileID, UpdateBuf, SU_BUF_LEN) != 0)
{
Flash_WriteBytes(WriteAddr, UpdateBuf, SU_BUF_LEN);
WriteAddr += SU_BUF_LEN;
}
USB_Close(FileID);
}
else
{
return ERR_READ_FILE;
}
return UpdateCheck();
}
2、通过以太网升级,按照协议,将受到的升级文件数据写到flash存储升级文件地址上。
3、通过BootLoader 完成升级
#define BANK_A_START_ADDR 0x1A000000 //Bank A起始地址
#define BANK_B_START_ADDR 0x1B000000 //Bank B起始地址
#define SYS_APP_OFFSET 0x00008000 //Bootloader Size: 32K
#define SYS_ROM1_SIZE 0x00038000 //Bank A Code:240K
#define SYS_ROM2_SIZE 0x00040000 //Bank B Code:256K
#define SYS_CODE1_START (BANK_A_START_ADDR + SYS_APP_OFFSET)
#define SYS_CODE2_START (BANK_B_START_ADDR)
#define SYS_CODE1_END (SYS_CODE1_START + SYS_ROM1_SIZE)
#define SYS_CODE2_END (SYS_CODE2_START + SYS_ROM2_SIZE)
void BackupSystem(void)
{
UINT SaveAddr;
UINT CodeSize1;
UINT CodeSize2;
UINT CodeSize;
USHORT CRCResult;
BYTE *pSyscode;
CodeSize1 = GetSysCodeLen(0); //Get Bank A Code Size
CodeSize2 = GetSysCodeLen(1); //Get Bank B Code Size
CRCResult = 0;
SaveAddr = FLASH_SAV_ADDR_OLD;
UINT2MSB((BYTE *)&CodeSize, CodeSize1);
WriteFlashBuf(&SaveAddr, (BYTE*)&CodeSize, 4);
WriteFlashBuf(&SaveAddr, (BYTE*)&CRCResult, 2);
UINT2MSB((BYTE *)&CodeSize, CodeSize2);
WriteFlashBuf(&SaveAddr, (BYTE*)&CodeSize, 4);
WriteFlashBuf(&SaveAddr, (BYTE*)&CRCResult, 2);
//Backup the bank A code
pSyscode = (BYTE*)SYS_CODE1_START;
while (CodeSize1)
{
if (CodeSize1 >= IAP_FLASH_PAGE)
{
WriteFlashBuf(&SaveAddr, pSyscode, IAP_FLASH_PAGE);
pSyscode += IAP_FLASH_PAGE;
CodeSize1 -= IAP_FLASH_PAGE;
}
else
{
WriteFlashBuf(&SaveAddr, pSyscode, CodeSize1);
CodeSize1 = 0;
}
}
//Backup the bank B code
pSyscode = (BYTE*)SYS_CODE2_START;
while (CodeSize2)
{
if (CodeSize2 >= IAP_FLASH_PAGE)
{
WriteFlashBuf(&SaveAddr, pSyscode, IAP_FLASH_PAGE);
pSyscode += IAP_FLASH_PAGE;
CodeSize2 -= IAP_FLASH_PAGE;
}
else
{
WriteFlashBuf(&SaveAddr, pSyscode, CodeSize2);
CodeSize2 = 0;
}
}
if(UpdateBufLen)
{
Flash_WriteBytes(SaveAddr, UpdateBuf, UpdateBufLen);
UpdateBufLen = 0;
}
}
UINT CheckCodeCRC(BYTE CodeFlag)
{
UINT FlashAddr = 0;
UINT FileSize1 = 0;
UINT FileSize2 = 0;
USHORT CrcValue1;
USHORT CrcValue2;
USHORT CrcCalc;
if (CodeFlag == IAP_CODE_OLD)
{
return 0;
}
FlashAddr = FLASH_SAV_ADDR_NEW;
CrcValue1 = 0;
CrcValue2 = 0;
Flash_ReadBytes(FlashAddr, (BYTE *)&FileSize1, 4);
FileSize1 = MSB2UINT((BYTE *)&FileSize1);
Flash_ReadBytes(FlashAddr + 4, (BYTE *)&CrcValue1, 2);
CrcCalc = CrcValue1 & 0xFF;
CrcCalc <<= 8;
CrcCalc += (CrcValue1 >> 8) & 0xFF;
CrcValue1 = CrcCalc;
Flash_ReadBytes(FlashAddr + 6, (BYTE *)&FileSize2, 4);
FileSize2 = MSB2UINT((BYTE *)&FileSize2);
Flash_ReadBytes(FlashAddr + 10, (BYTE *)&CrcValue2, 2);
CrcCalc = CrcValue2 & 0xFF;
CrcCalc <<= 8;
CrcCalc += (CrcValue2 >> 8) & 0xFF;
CrcValue2 = CrcCalc;
FlashAddr += (4 + 2) + (4 + 2);
CrcCalc = GetFlashCodeCrc(FlashAddr, FileSize1);
if (CrcCalc != CrcValue1)
{
return 1;
}
FlashAddr += FileSize1;
CrcCalc = GetFlashCodeCrc(FlashAddr, FileSize2);
if (CrcCalc != CrcValue2)
{
return 1;
}
return 0;
}
BYTE CopySystemCode(BYTE CodeFlag)
{
UINT FlashAddr = 0;
UINT FileSize1;
UINT FileSize2;
BYTE Result;
if(CheckCodeCRC(CodeFlag) !=0 )
{
//CRC失败,不再尝试升级
IAP_WriteFlag(IAP_FLAG_NEWCODE, IAP_FLAG_CLEAR);
return 1;
}
if(CodeFlag == IAP_CODE_OLD)
{
FlashAddr = FLASH_SAV_ADDR_OLD;
}
else
{
FlashAddr = FLASH_SAV_ADDR_NEW;
}
Flash_ReadBytes(FlashAddr, (BYTE *)&FileSize1, 4);
FileSize1 = MSB2UINT((BYTE *)&FileSize1);
if (FileSize1 > SYS_ROM1_SIZE)
{
return 1;
}
Flash_ReadBytes(FlashAddr+6, (BYTE *)&FileSize2, 4);
FileSize2 = MSB2UINT((BYTE *)&FileSize2);
if (FileSize2 > SYS_ROM2_SIZE)
{
return 1;
}
FlashAddr += (4 + 2) + (4 + 2);
IAP_WriteFlag(IAP_FLAG_COPY_START, IAP_FLAG_MARK);
IAP_WriteFlag(IAP_FLAG_COPY_END, IAP_FLAG_CLEAR);
if (EraseBank(SYS_BANK_A))
{
//Display log information
return 1;
}
Result = CopyCodeToBank(SYS_BANK_A, FlashAddr, FileSize1);
if (Result != 0)
{
return 1;
}
if (EraseBank(SYS_BANK_B))
{
//Display log information
return 1;
}
FlashAddr += FileSize1;
Result = CopyCodeToBank(SYS_BANK_B, FlashAddr, FileSize2);
if (Result != 0)
{
return 1;
}
IAP_WriteFlag(IAP_FLAG_COPY_START, IAP_FLAG_CLEAR);
IAP_WriteFlag(IAP_FLAG_COPY_END, IAP_FLAG_MARK);
return 0;
}
void StartSystem(void) //启动系统
{
UINT BootAddr;
UINT *BootPtr;
Func Boot;
BootAddr = SYS_CODE1_START;
BootPtr = ((UINT *)BootAddr + 1);
Boot = (Func)*BootPtr;
Boot();
}
int BootLoader_start(void)
{
SYS_VER Version;
UINT Addr;
SystemInit();
SystemCoreClock = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M3CORE);
E2P_Init();
//Flash_Init();
//NFTL_INIT();
Drv_Init();
NFTL_INIT();
SDRAM_Init();
//Check system
Addr = SYS_CODE1_START + 0x200;
memcpy((BYTE *)&Version, (BYTE*)Addr, sizeof(SYS_VER));
__disable_irq();
//是否有升级程序
if(IAP_ReadFlag(IAP_FLAG_NEWCODE) == IAP_FLAG_MARK)
{
DelayMs(100);
BackupSystem(); //备份原来的程序
if (CopySystemCode(IAP_CODE_NEW) == 0)
{
IAP_WriteFlag(IAP_FLAG_NEWCODE, IAP_FLAG_CLEAR);
IAP_WriteFlag(IAP_FLAG_NEWRUN, IAP_FLAG_MARK);
}
DelayMs(1000);
}
else
{
//是否上次升级程序运行出错
if(IAP_ReadFlag(IAP_FLAG_NEWRUN) == IAP_FLAG_MARK)
{
DelayMs(500);
CopySystemCode(IAP_CODE_OLD);
}
}
__enable_irq();
StartSystem();
return 0;
}