NXP LPC1758 Bootloader 使用串口0 支持xmodem1k協議,可以使用超級終端將應用程序上傳到FLASH實現IAP程序升級
單片機源程序如下:
- #include "LPC17xx.h" /* LPC17xx外設寄存器 */
- #include "../UART/uart.h"
- #include "../IAP/iap.h"
- #include "../CRC/crc.h"
- #include "../XMODEM1K/xmodem1k.h"
- #include <string.h>
- extern uint32_t SystemFrequency;
- /*
- * Define flash memory address at which user application is located
- */
- #define APP_START_ADDR 0x00010000UL
- #define APP_END_ADDR 0x00080000UL /* LPC1766 256K Flash */
- /*
- * Define the flash sectors used by the application
- */
- #define APP_START_SECTOR 16
- #define APP_END_SECTOR 29 /* 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: JMP_Boot
- ** Descriptions: 跳轉到應用程序
- ** input parameters: address 應用程序地址
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- __asm void JMP_Boot( uint32_t address ){
- LDR SP, [R0] ;Load new stack pointer address
- LDR PC, [R0, #4] ;Load new program counter address
- }
- /*********************************************************************************************************
- ** Function name: Boot
- ** Descriptions: 跳轉到應用程序
- ** input parameters: 無
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- void Boot( void )
- {
- SCB->VTOR = APP_START_ADDR & 0x1FFFFF80; //修改中斷向量表
- //SCB->VTOR = APP_START_ADDR;
- JMP_Boot(APP_START_ADDR);
- }
- /*********************************************************************************************************
- ** Function name: main
- ** Descriptions: Bootloader控制循環
- ** input parameters: 無
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- int main(void)
- {
- uint8_t uartBuffer[16], len;
- SystemInit();
- vUARTInit(BAUD_RATE); //P0.2,P0.3對就串口0,115200
- vUARTSend((uint8_t *)("\r\nLPC1700 Ready For Updates >"), strlen("\r\nLPC1700 Ready For Updates >"));
- Timer0_Init (10);
- len = 0;
- //獲取IAP升級命令IAP
- 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;
- }
- //等待置信IAP字例 入IAP升級,超進退出。
- 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 & 0x1FFFFF80; /* 重新映射向量表 */
- //vUARTSend((uint8_t *)("\r\VTOR\r\n"), strlen("\r\VTOR\r\n"));
- //ExceuteApplication();
- LPC_TIM0->IR = 0x00; //關閉定時器
- Boot();
- vUARTSend((uint8_t *)("\r\boot faild\r\n"), strlen("\r\boot faild\r\n"));
- } 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 & 0x1FFFFF80; /* 重新映射向量表 */
- //vUARTSend((uint8_t *)("\r\VTOR1\r\n"), strlen("\r\VTOR1\r\n"));
- //ExceuteApplication();
- LPC_TIM0->IR = 0x00; //關閉定時器
- Boot();
- vUARTSend((uint8_t *)("\r\boot faild!!\r\n"), strlen("\r\boot faild!!\r\n"));
-
- /* 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);
- }
復制代碼
所有資料51hei提供下載:
Bootloader.rar
(370.03 KB, 下載次數: 13)
2020-2-24 12:26 上傳
點擊文件名下載附件
|