单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 310|回复: 0
收起左侧

NXP LPC1758 Bootloader 使用串口0 支持xmodem1k协议

[复制链接]
kevinjzw 发表于 2020-2-24 12:28 | 显示全部楼层 |阅读模式
NXP LPC1758 Bootloader 使用串口0 支持xmodem1k协议,可以使用超级终端将应用程序上传到FLASH实现IAP程序升级

单片机源程序如下:
  1. #include "LPC17xx.h"   /* LPC17xx外设寄存器            */
  2. #include "../UART/uart.h"
  3. #include "../IAP/iap.h"
  4. #include "../CRC/crc.h"
  5. #include "../XMODEM1K/xmodem1k.h"
  6. #include <string.h>

  7. extern uint32_t SystemFrequency;
  8. /*
  9. * Define flash memory address at which user application is located
  10. */
  11. #define APP_START_ADDR                                                0x00010000UL
  12. #define APP_END_ADDR                                                0x00080000UL                /* LPC1766 256K Flash           */

  13. /*
  14. * Define the flash sectors used by the application
  15. */
  16. #define APP_START_SECTOR                                        16
  17. #define APP_END_SECTOR                                                29                            /* LPC1766 256K Flash           */

  18. volatile uint32_t IAPFlagTimeOut;

  19. static uint32_t u32InvalidateApp(void);
  20. void ExceuteApplication(void);
  21. static void vBootLoader_Task(void);
  22. static uint32_t u32BootLoader_AppPresent(void);
  23. static uint32_t u32Bootloader_WriteCRC(uint16_t u16CRC);
  24. static uint32_t u32BootLoader_ProgramFlash(uint8_t *pu8Data, uint16_t u16Len);

  25. /*********************************************************************************************************
  26. ** Function name:       Timer0_Init
  27. ** Descriptions:        定时器0初始化程序
  28. ** input parameters:    无
  29. ** output parameters:   无
  30. ** Returned value:      无
  31. *********************************************************************************************************/
  32. void  Timer0_Init (uint32_t ulsec)
  33. {
  34.     LPC_TIM0->TCR  = 0x02;
  35.     LPC_TIM0->IR   = 0x01;
  36.     LPC_TIM0->CTCR = 0;
  37.     LPC_TIM0->TC   = 0;
  38.     LPC_TIM0->PR   = 0;
  39.     LPC_TIM0->MR0  = (SystemFrequency/4)*ulsec;                         /* nS中断1次                    */
  40.     LPC_TIM0->MCR  = 0x05;                                              /* 匹配后产生中断               */
  41.     LPC_TIM0->TCR  = 0x01;                                              /* 启动定时器                   */
  42. }

  43. /*********************************************************************************************************
  44. ** Function name:       JMP_Boot
  45. ** Descriptions:        跳转到应用程序
  46. ** input parameters:    address 应用程序地址
  47. ** output parameters:   无
  48. ** Returned value:      无
  49. *********************************************************************************************************/
  50. __asm void JMP_Boot( uint32_t address ){
  51.    LDR SP, [R0]                ;Load new stack pointer address
  52.    LDR PC, [R0, #4]        ;Load new program counter address
  53. }

  54. /*********************************************************************************************************
  55. ** Function name:       Boot
  56. ** Descriptions:        跳转到应用程序
  57. ** input parameters:    无
  58. ** output parameters:   无
  59. ** Returned value:      无
  60. *********************************************************************************************************/
  61. void Boot( void )
  62. {
  63.         SCB->VTOR = APP_START_ADDR & 0x1FFFFF80;        //修改中断向量表
  64.         //SCB->VTOR = APP_START_ADDR;
  65.         JMP_Boot(APP_START_ADDR);
  66. }

  67. /*********************************************************************************************************
  68. ** Function name:       main
  69. ** Descriptions:        Bootloader控制循环
  70. ** input parameters:    无
  71. ** output parameters:   无
  72. ** Returned value:      无
  73. *********************************************************************************************************/
  74. int main(void)
  75. {
  76.         uint8_t uartBuffer[16], len;
  77.         SystemInit();
  78.     vUARTInit(BAUD_RATE); //P0.2,P0.3对就串口0,115200
  79.     vUARTSend((uint8_t *)("\r\nLPC1700 Ready For Updates >"), strlen("\r\nLPC1700 Ready For Updates >"));   
  80.     Timer0_Init (10);
  81.     len = 0;
  82.         //获取IAP升级命令IAP
  83.     while (1)
  84.         {
  85.         if ((LPC_TIM0->IR & 0x01) == 0x01)
  86.                 {
  87.              LPC_TIM0->IR   = 0x01;                                     /* 清除中断标志                 */
  88.              IAPFlagTimeOut = 1;                                                                                /* 等待升级命令超时             */
  89.              vUARTSend((uint8_t *)("\r\nTimeout waiting for the upgrade command!\r\n"), strlen("\r\nTimeout waiting for the upgrade command!\r\n"));
  90.              break;
  91.         }
  92.                 //等待置信IAP字例 入IAP升级,超进退出。
  93.         if (u8UARTReceive(uartBuffer) > 0)
  94.                 {                                    /* 判断升级命令 IAP             */
  95.             
  96.             vUARTSend(uartBuffer, 1);
  97.             if (uartBuffer[0] == 'I')
  98.                         {
  99.                 len = 1;
  100.             }
  101.             if (uartBuffer[0] == 'A')
  102.                         {
  103.                 if (len == 1)
  104.                                 {
  105.                     len = 2;
  106.                 }
  107.                                 else
  108.                                 {
  109.                     len = 0;
  110.                 }
  111.             }
  112.             if (uartBuffer[0] == 'P')
  113.                         {
  114.                 if (len == 2)
  115.                                 {
  116.                     len = 3;
  117.                 }
  118.                                 else
  119.                                 {
  120.                     len = 0;
  121.                 }
  122.             }
  123.         }
  124.         if (len == 3)
  125.                 {
  126.                 IAPFlagTimeOut = 0;
  127.                 vUARTSend((uint8_t *)("\r\nReceiving a successful upgrade command!\r\n"), strlen("\r\nReceiving a successful upgrade command!\r\n"));
  128.                 break;
  129.         }
  130.     }

  131.     if (IAPFlagTimeOut == 0)
  132.         {
  133.         if (u32InvalidateApp() == 0)
  134.             {
  135.                     vUARTSend((uint8_t *)("\r\nErase mark CRC failed!\r\n"), strlen("\r\nErase mark CRC failed!\r\n"));
  136.             if ((u32IAP_PrepareSectors(APP_END_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
  137.             && (u32IAP_EraseSectors(APP_END_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS))
  138.                         {
  139.                 vUARTSend((uint8_t *)("\r\nErase the last sector!\r\n"), strlen("\r\nErase the last sector!\r\n"));
  140.             }
  141.             /* Restart and bootloader will begin */
  142.                     SCB->AIRCR = (0x05fa << 16) + 1;
  143.             }
  144.     }

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

  153.                 /* Above function only returns when new application image has been
  154.                    successfully programmed into flash. Begin execution of this new
  155.                    application by resetting the device. */
  156.                 if (u32BootLoader_AppPresent() != 0) {
  157.                     vUARTSend((uint8_t *)("\r\nExecute user code!\r\n"), strlen("\r\nExecute user code!\r\n"));
  158.                     //SCB->VTOR  = APP_START_ADDR & 0x1FFFFF80;                                /* 重新映射向量表               */
  159.             //vUARTSend((uint8_t *)("\r\VTOR\r\n"), strlen("\r\VTOR\r\n"));
  160.                         //ExceuteApplication();
  161.                         LPC_TIM0->IR = 0x00; //关闭定时器
  162.                         Boot();
  163.                         vUARTSend((uint8_t *)("\r\boot faild\r\n"), strlen("\r\boot faild\r\n"));
  164.                 } else {
  165.                     vUARTSend((uint8_t *)("\r\nUpgrade failure!\r\n"), strlen("\r\nUpgrade failure!\r\n"));
  166.                     SCB->AIRCR = (0x05fa << 16) + 1;
  167.                 }
  168.             
  169.         }
  170.         else
  171.         {
  172.                 vUARTSend((uint8_t *)("\r\nExecute user code!\r\n"), strlen("\r\nExecute user code!\r\n"));
  173.         /* Valid application located in the next sector(s) of flash so execute */

  174.                 //SCB->VTOR  = APP_START_ADDR & 0x1FFFFF80;                                    /* 重新映射向量表               */
  175.         //vUARTSend((uint8_t *)("\r\VTOR1\r\n"), strlen("\r\VTOR1\r\n"));
  176.                 //ExceuteApplication();
  177.                 LPC_TIM0->IR = 0x00; //关闭定时器
  178.                 Boot();
  179.                 vUARTSend((uint8_t *)("\r\boot faild!!\r\n"), strlen("\r\boot faild!!\r\n"));
  180.                                                                                           
  181.                 /* User application execution should now start and never return here.... */
  182.         }
  183.         /* This should never be executed.. */
  184.         return 0;
  185. }

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

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

  199. /*****************************************************************************
  200. ** Function name:  vBootLoader_Task
  201. **
  202. ** Description:        Erases application flash area and starts XMODEM client so
  203. **                                 that new application can be downloaded.
  204. **
  205. ** Parameters:            None
  206. **
  207. ** Returned value: None
  208. **
  209. *****************************************************************************/
  210. static void vBootLoader_Task(void)
  211. {
  212.         /* Erase the application flash area so it is ready to be reprogrammed with the new application */
  213.         if (u32IAP_PrepareSectors(APP_START_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
  214.         {
  215.                 if (u32IAP_EraseSectors(APP_START_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
  216.                 {
  217.                         uint16_t u16CRC = 0;

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

  222.                         /* Programming is now complete, calculate the CRC of the flash image */
  223.                         u16CRC = u16CRC_Calc16((const uint8_t *)APP_START_ADDR, (APP_END_ADDR - APP_START_ADDR - 4));

  224.                         /* Write the CRC value into the last 16-bit location of flash, this
  225.                            will be used to check for a valid application at startup  */
  226.                         (void)u32Bootloader_WriteCRC(u16CRC);
  227.                 }
  228.         }
  229. }

  230. /*****************************************************************************
  231. ** Function name:        u32Bootloader_WriteCRC
  232. **
  233. ** Description:        Writes a 16-bit CRC value to the last location in flash
  234. **                                 memory, the bootloader uses this value to check for a valid
  235. **                                 application at startup.
  236. **
  237. ** Parameters:            u16CRC - CRC value to be written to flash
  238. **
  239. ** Returned value: 1 if CRC written to flash successfully, otherwise 0.
  240. **
  241. *****************************************************************************/
  242. static uint32_t u32Bootloader_WriteCRC(uint16_t u16CRC)
  243. {
  244.         uint32_t i;
  245.         uint32_t u32Result = 0;
  246.         uint32_t a32DummyData[IAP_FLASH_PAGE_SIZE_WORDS];
  247.         uint32_t *pu32Mem = (uint32_t *)(APP_END_ADDR - IAP_FLASH_PAGE_SIZE_BYTES);

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

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

  256.         if (u32IAP_PrepareSectors(APP_END_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
  257.         {
  258.                 /* Now write the data back, only the CRC bits have changed */
  259.                 if (u32IAP_CopyRAMToFlash((APP_END_ADDR - IAP_FLASH_PAGE_SIZE_BYTES),
  260.                                                   (uint32_t)a32DummyData,
  261.                                                   IAP_FLASH_PAGE_SIZE_BYTES) == IAP_STA_CMD_SUCCESS)
  262.                 {
  263.                         u32Result = 1;
  264.                 }
  265.         }
  266.         return (u32Result);
  267. }

  268. /*****************************************************************************
  269. ** Function name:        u32BootLoader_ProgramFlash
  270. **
  271. ** Description:
  272. **
  273. ** Parameters:            None
  274. **
  275. ** Returned value: 0 if programming failed, otherwise 1.
  276. **
  277. *****************************************************************************/
  278. static uint32_t u32BootLoader_ProgramFlash(uint8_t *pu8Data, uint16_t u16Len)
  279. {
  280.         uint32_t u32Result = 0;

  281.         static uint32_t u32NextFlashWriteAddr = APP_START_ADDR;

  282.         if ((pu8Data != 0) && (u16Len != 0))
  283.         {
  284.                 /* Prepare the flash application sectors for reprogramming */
  285.                 if (u32IAP_PrepareSectors(APP_START_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
  286.                 {
  287.                         /* Ensure that amount of data written to flash is at minimum the
  288.                            size of a flash page */
  289.                         if (u16Len < IAP_FLASH_PAGE_SIZE_BYTES)
  290.                         {
  291.                                 u16Len = IAP_FLASH_PAGE_SIZE_BYTES;
  292.                         }

  293.                         /* Write the data to flash */
  294.                         if (u32IAP_CopyRAMToFlash(u32NextFlashWriteAddr, (uint32_t)pu8Data, u16Len) == IAP_STA_CMD_SUCCESS)
  295.                         {
  296.                                 /* Check that the write was successful */
  297.                                 if (u32IAP_Compare(u32NextFlashWriteAddr, (uint32_t)pu8Data, u16Len, 0) == IAP_STA_CMD_SUCCESS)
  298.                                 {
  299.                                         /* Write was successful */
  300.                                         u32NextFlashWriteAddr += u16Len;
  301.                                         u32Result = 1;
  302.                                 }
  303.                         }
  304.                 }
  305.         }
  306.         return (u32Result);
  307. }

  308. /*****************************************************************************
  309. ** Function name:  u32BootLoader_AppPresent
  310. **
  311. ** Description:        Checks if an application is present by comparing CRC of
  312. **                                 flash contents with value present at last location in flash.
  313. **
  314. ** Parameters:            None
  315. **
  316. ** Returned value: 1 if application present, otherwise 0.
  317. **
  318. *****************************************************************************/
  319. static uint32_t u32BootLoader_AppPresent(void)
  320. {
  321.         uint16_t u16CRC = 0;
  322.         uint32_t u32AppPresent = 0;
  323.         uint16_t *pu16AppCRC = (uint16_t *)(APP_END_ADDR - 4);

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

  331.                 if (*pu16AppCRC == u16CRC)
  332.                 {
  333.                         u32AppPresent = 1;
  334.                 }
  335.         }
  336.         return u32AppPresent;
  337. }

  338. /*****************************************************************************
  339. ** Function name:  u32InvalidateApp
  340. **
  341. ** Description:        Corrupt the application CRC value that is written into the
  342. **                                 last location of flash by the bootloader.
  343. **
  344. ** Parameters:            None
  345. **
  346. ** Returned value: Zero if unsuccessful, otherwise 1
  347. **
  348. *****************************************************************************/
  349. uint32_t u32InvalidateApp(void)
  350. {
  351.         uint32_t i;
  352.         uint32_t u32Result = 0;
  353.         uint32_t a32DummyData[IAP_FLASH_PAGE_SIZE_WORDS];
  354.         uint32_t *pu32Mem = (uint32_t *)(APP_END_ADDR - IAP_FLASH_PAGE_SIZE_BYTES);

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

  361.         /* Set the CRC value to be written back, corrupt by setting all ones to zeros */
  362.         a32DummyData[IAP_FLASH_PAGE_SIZE_WORDS - 1] = 0x0000;

  363.         if (u32IAP_PrepareSectors(APP_END_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
  364.         {
  365.                 /* Now write the data back, only the CRC bits have changed */
  366.                 if (u32IAP_CopyRAMToFlash((APP_END_ADDR - IAP_FLASH_PAGE_SIZE_BYTES),
  367.                                                   (uint32_t)a32DummyData,
  368.                                                   IAP_FLASH_PAGE_SIZE_BYTES) == IAP_STA_CMD_SUCCESS)
  369.                 {
  370.                         u32Result = 1;
  371.                 }
  372.         }
  373.         return (u32Result);
  374. }
复制代码

所有资料51hei提供下载:
Bootloader.rar (370.03 KB, 下载次数: 3)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表