⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 LPC1700在线升级方案V1.00
💻 C
字号:
/****************************************Copyright (c)****************************************************
**                            Guangzhou ZLGMCU Development Co., LTD
**
**                                 http://www.zlgmcu.com
**
**--------------File Info---------------------------------------------------------------------------------
** File name:           main.c
** Last modified Date:  2011-12-27
** Last Version:        V1.0
** Descriptions:        The main() function example template
**
**--------------------------------------------------------------------------------------------------------
** Created by:          Liu ZhiPeng
** Created date:        2011-12-27
** Version:             V1.00
** Descriptions:        编写应用程序
**
**--------------------------------------------------------------------------------------------------------
** Modified by:         
** Modified date:       
** Version:             
** Descriptions:        
**
**--------------------------------------------------------------------------------------------------------
** Modified by:        
** Modified date:      
** Version:            
** Descriptions:       
**
** Rechecked by:
*********************************************************************************************************/
#include "LPC17xx.h"                                                    /* LPC17xx外设寄存器            */
#include "../UART/uart.h"
#include "../IAP/iap.h"
#include "../CRC/crc.h"
#include "../XMODEM1K/xmodem1k.h"
#include <string.h>

/* 
 * Define flash memory address at which user application is located 
 */
#define APP_START_ADDR						0x00001000UL
#define APP_END_ADDR						0x00040000UL                /* LPC1766 256K Flash           */

/* 
 * Define the flash sectors used by the application 
 */
#define APP_START_SECTOR					1
#define APP_END_SECTOR						21		                    /* LPC1766 256K Flash           */

volatile uint32_t IAPFlagTimeOut;

static uint32_t u32InvalidateApp(void);
void ExceuteApplication(void);
static void vBootLoader_Task(void);
static uint32_t u32BootLoader_AppPresent(void);
static uint32_t u32Bootloader_WriteCRC(uint16_t u16CRC);
static uint32_t u32BootLoader_ProgramFlash(uint8_t *pu8Data, uint16_t u16Len);

/*********************************************************************************************************
** Function name:       Timer0_Init
** Descriptions:        定时器0初始化程序
** input parameters:    无
** output parameters:   无
** Returned value:      无
*********************************************************************************************************/
void  Timer0_Init (uint32_t ulsec)
{
    LPC_TIM0->TCR  = 0x02;
    LPC_TIM0->IR   = 0x01;
    LPC_TIM0->CTCR = 0;
    LPC_TIM0->TC   = 0;
    LPC_TIM0->PR   = 0;
    LPC_TIM0->MR0  = (SystemFrequency/4)*ulsec;                         /* nS中断1次                    */
    LPC_TIM0->MCR  = 0x05;                                              /* 匹配后产生中断               */
    LPC_TIM0->TCR  = 0x01;                                              /* 启动定时器                   */
}

/*********************************************************************************************************
** Function name:       main
** Descriptions:        Bootloader控制循环
** input parameters:    无
** output parameters:   无
** Returned value:      无
*********************************************************************************************************/
int main(void)
{
	uint8_t uartBuffer[16], len;

	SystemInit();

    vUARTInit(BAUD_RATE); 

    vUARTSend((uint8_t *)("\r\nLPC1700 Ready For Updates >"), strlen("\r\nLPC1700 Ready For Updates >"));
    
    Timer0_Init (10);
    len = 0;
    while (1) {
        if ((LPC_TIM0->IR & 0x01) == 0x01) {
             LPC_TIM0->IR   = 0x01;                                     /* 清除中断标志                 */
             IAPFlagTimeOut = 1;										                    /* 等待升级命令超时             */
             vUARTSend((uint8_t *)("\r\nTimeout waiting for the upgrade command!\r\n"), strlen("\r\nTimeout waiting for the upgrade command!\r\n"));
             break;
        }
        if (u8UARTReceive(uartBuffer) > 0){	                            /* 判断升级命令 IAP             */
            
            vUARTSend(uartBuffer, 1);
            if (uartBuffer[0] == 'I') {
                len = 1;
            }
            if (uartBuffer[0] == 'A') {
                if (len == 1) {
                    len = 2;
                } else {
                    len = 0;
                }
            }
            if (uartBuffer[0] == 'P') {
                if (len == 2) {
                    len = 3;
                } else {
                    len = 0;
                }
            }
        }
        if (len == 3) {
                IAPFlagTimeOut = 0;
                vUARTSend((uint8_t *)("\r\nReceiving a successful upgrade command!\r\n"), strlen("\r\nReceiving a successful upgrade command!\r\n"));
                break;

        }
    }

    if (IAPFlagTimeOut == 0) {
        if (u32InvalidateApp() == 0)
	    {		    vUARTSend((uint8_t *)("\r\nErase mark CRC failed!\r\n"), strlen("\r\nErase mark CRC failed!\r\n"));
            if ((u32IAP_PrepareSectors(APP_END_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
            && (u32IAP_EraseSectors(APP_END_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)) {
                vUARTSend((uint8_t *)("\r\nErase the last sector!\r\n"), strlen("\r\nErase the last sector!\r\n"));
            }
            /* Restart and bootloader will begin */
		    SCB->AIRCR = (0x05fa << 16) + 1;
	    }
    }

	/* Verify if a valid user application is present in the upper sectors
	   of flash memory. */
	if (u32BootLoader_AppPresent() == 0)
	{
        vUARTSend((uint8_t *)("Into upgrade state!\r\n"), strlen("Into upgrade state!\r\n"));
        /* Valid application not present, execute bootloader task that will
		   obtain a new application and program it to flash.. */
		vBootLoader_Task();

		/* Above function only returns when new application image has been
		   successfully programmed into flash. Begin execution of this new
		   application by resetting the device. */
		if (u32BootLoader_AppPresent() != 0) {		    vUARTSend((uint8_t *)("\r\nExecute user code!\r\n"), strlen("\r\nExecute user code!\r\n"));
		    SCB->VTOR  = APP_START_ADDR;                                /* 重新映射向量表               */
            ExceuteApplication();
		} else {
		    vUARTSend((uint8_t *)("\r\nUpgrade failure!\r\n"), strlen("\r\nUpgrade failure!\r\n"));
		    SCB->AIRCR = (0x05fa << 16) + 1;
		}
	    
	}
	else
	{
		vUARTSend((uint8_t *)("\r\nExecute user code!\r\n"), strlen("\r\nExecute user code!\r\n"));
        /* Valid application located in the next sector(s) of flash so execute */

		SCB->VTOR  = APP_START_ADDR;                                    /* 重新映射向量表               */
        ExceuteApplication();
											  
		/* User application execution should now start and never return here.... */
	}
	/* This should never be executed.. */
	return 0;
}

__asm void ExceuteApplication(void)
{
		/* Load main stack pointer with application stack pointer initial value,
		   stored at first location of application area */
		ldr r0, =0x1000
		ldr r0, [r0]
		mov sp, r0

		/* Load program counter with application reset vector address, located at
		   second word of application area. */
		ldr r0, =0x1004
		ldr r0, [r0]
        BX  r0
}

/*****************************************************************************
 ** Function name:  vBootLoader_Task
 **
 ** Description:	Erases application flash area and starts XMODEM client so
 ** 				that new application can be downloaded.
 **
 ** Parameters:	    None
 **
 ** Returned value: None
 **
 *****************************************************************************/
static void vBootLoader_Task(void)
{
	/* Erase the application flash area so it is ready to be reprogrammed with the new application */
	if (u32IAP_PrepareSectors(APP_START_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
	{
		if (u32IAP_EraseSectors(APP_START_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
		{
			uint16_t u16CRC = 0;

			/* Start the xmodem client, this function only returns when a
			   transfer is complete. Pass it pointer to function that will
			   handle received data packets */
			vXmodem1k_Client(&u32BootLoader_ProgramFlash);

			/* Programming is now complete, calculate the CRC of the flash image */
			u16CRC = u16CRC_Calc16((const uint8_t *)APP_START_ADDR, (APP_END_ADDR - APP_START_ADDR - 4));
			/* Write the CRC value into the last 16-bit location of flash, this
			   will be used to check for a valid application at startup  */
			(void)u32Bootloader_WriteCRC(u16CRC);
		}
	}
}

/*****************************************************************************
 ** Function name:	u32Bootloader_WriteCRC
 **
 ** Description:	Writes a 16-bit CRC value to the last location in flash
 ** 				memory, the bootloader uses this value to check for a valid
 ** 				application at startup.
 **
 ** Parameters:	    u16CRC - CRC value to be written to flash
 **
 ** Returned value: 1 if CRC written to flash successfully, otherwise 0.
 **
 *****************************************************************************/
static uint32_t u32Bootloader_WriteCRC(uint16_t u16CRC)
{
	uint32_t i;
	uint32_t u32Result = 0;
	uint32_t a32DummyData[IAP_FLASH_PAGE_SIZE_WORDS];
	uint32_t *pu32Mem = (uint32_t *)(APP_END_ADDR - IAP_FLASH_PAGE_SIZE_BYTES);

	/* First copy the data that is currently present in the last page of
	   flash into a temporary buffer */	for (i = 0 ; i < IAP_FLASH_PAGE_SIZE_WORDS; i++)
	{
		a32DummyData[i] = *pu32Mem++;
	}

	/* Set the CRC value to be written back */
	a32DummyData[IAP_FLASH_PAGE_SIZE_WORDS - 1] = (uint32_t)u16CRC;

	if (u32IAP_PrepareSectors(APP_END_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
	{
		/* Now write the data back, only the CRC bits have changed */
		if (u32IAP_CopyRAMToFlash((APP_END_ADDR - IAP_FLASH_PAGE_SIZE_BYTES),
				                  (uint32_t)a32DummyData,
				                  IAP_FLASH_PAGE_SIZE_BYTES) == IAP_STA_CMD_SUCCESS)
		{
			u32Result = 1;
		}
	}
	return (u32Result);
}

/*****************************************************************************
 ** Function name:	u32BootLoader_ProgramFlash
 **
 ** Description:
 **
 ** Parameters:	    None
 **
 ** Returned value: 0 if programming failed, otherwise 1.
 **
 *****************************************************************************/
static uint32_t u32BootLoader_ProgramFlash(uint8_t *pu8Data, uint16_t u16Len)
{
	uint32_t u32Result = 0;

	static uint32_t u32NextFlashWriteAddr = APP_START_ADDR;

	if ((pu8Data != 0) && (u16Len != 0))
	{
		/* Prepare the flash application sectors for reprogramming */
		if (u32IAP_PrepareSectors(APP_START_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
		{
			/* Ensure that amount of data written to flash is at minimum the
			   size of a flash page */
			if (u16Len < IAP_FLASH_PAGE_SIZE_BYTES)
			{
				u16Len = IAP_FLASH_PAGE_SIZE_BYTES;
			}

			/* Write the data to flash */
			if (u32IAP_CopyRAMToFlash(u32NextFlashWriteAddr, (uint32_t)pu8Data, u16Len) == IAP_STA_CMD_SUCCESS)
			{
				/* Check that the write was successful */
				if (u32IAP_Compare(u32NextFlashWriteAddr, (uint32_t)pu8Data, u16Len, 0) == IAP_STA_CMD_SUCCESS)
				{
					/* Write was successful */
					u32NextFlashWriteAddr += u16Len;
					u32Result = 1;
				}
			}
		}
	}
	return (u32Result);
}

/*****************************************************************************
 ** Function name:  u32BootLoader_AppPresent
 **
 ** Description:	Checks if an application is present by comparing CRC of
 ** 				flash contents with value present at last location in flash.
 **
 ** Parameters:	    None
 **
 ** Returned value: 1 if application present, otherwise 0.
 **
 *****************************************************************************/
static uint32_t u32BootLoader_AppPresent(void)
{
	uint16_t u16CRC = 0;
	uint32_t u32AppPresent = 0;
	uint16_t *pu16AppCRC = (uint16_t *)(APP_END_ADDR - 4);

	/* Check if a CRC value is present in application flash area */
	if (*pu16AppCRC != 0xFFFFUL)
	{
		/* Memory occupied by application CRC is not blank so calculate CRC of
		   image in application area of flash memory, and check against this
		   CRC.. */
		u16CRC = u16CRC_Calc16((const uint8_t *)APP_START_ADDR, (APP_END_ADDR - APP_START_ADDR - 4));

		if (*pu16AppCRC == u16CRC)
		{
			u32AppPresent = 1;
		}
	}
	return u32AppPresent;
}

/*****************************************************************************
 ** Function name:  u32InvalidateApp
 **
 ** Description:	Corrupt the application CRC value that is written into the
 ** 				last location of flash by the bootloader.
 **
 ** Parameters:	    None
 **
 ** Returned value: Zero if unsuccessful, otherwise 1
 **
 *****************************************************************************/
uint32_t u32InvalidateApp(void)
{
	uint32_t i;
	uint32_t u32Result = 0;
	uint32_t a32DummyData[IAP_FLASH_PAGE_SIZE_WORDS];
	uint32_t *pu32Mem = (uint32_t *)(APP_END_ADDR - IAP_FLASH_PAGE_SIZE_BYTES);

	/* First copy the data that is currently present in the last page of
	   flash into a temporary buffer */
	for (i = 0 ; i < IAP_FLASH_PAGE_SIZE_WORDS; i++)
	{
		a32DummyData[i] = *pu32Mem++;
	}
 
	/* Set the CRC value to be written back, corrupt by setting all ones to zeros */
	a32DummyData[IAP_FLASH_PAGE_SIZE_WORDS - 1] = 0x0000;

	if (u32IAP_PrepareSectors(APP_END_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
	{
		/* Now write the data back, only the CRC bits have changed */
		if (u32IAP_CopyRAMToFlash((APP_END_ADDR - IAP_FLASH_PAGE_SIZE_BYTES),
				                  (uint32_t)a32DummyData,
				                  IAP_FLASH_PAGE_SIZE_BYTES) == IAP_STA_CMD_SUCCESS)
		{
			u32Result = 1;
		}
	}
	return (u32Result);
}

/*********************************************************************************************************
**  End Of File
*********************************************************************************************************/


/*********************************************************************************************************
  End Of File
*********************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -