NXP LPC43XX 应用程序需升级

更新文件存储地址定义

#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;
}

猜你喜欢

转载自blog.csdn.net/ggggyj/article/details/85260624