[技术问答] 求助新唐NANO103 IAP方案

[复制链接]
2322|7
 楼主| kelly1989 发表于 2017-12-5 17:15 | 显示全部楼层 |阅读模式
新唐NANO103系列单片机IAP例程,都是从本地添加.bin文件,然后写入flash中,有没有从串口接收.bin文件的方案,串口接收然后写入flash中,求大神指教
antusheng 发表于 2017-12-5 18:29 | 显示全部楼层
没玩过这个单片机的,看看手册吧,看看里面是怎么分配的,自己写个BootLoader
antusheng 发表于 2017-12-5 18:32 | 显示全部楼层
  1. /******************************************************************************
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     APROM_main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V1.00
  4. * $Revision: 6 $
  5. * $Date: 16/02/16 9:21a $
  6. * [url=home.php?mod=space&uid=247401]@brief[/url]    FMC APROM IAP sample for NANO103 series MCU
  7. *
  8. * @note
  9. * Copyright (C) 2015 Nuvoton Technology Corp. All rights reserved.
  10. *****************************************************************************/
  11. #include <stdio.h>

  12. #include "Nano103.h"

  13. typedef void (FUNC_PTR)(void);

  14. extern uint32_t  loaderImage1Base, loaderImage1Limit;   /* symbol of image start and end */


  15. void SYS_Init(void)
  16. {
  17.     SYS_UnlockReg();                             /* Unlock protected registers */

  18.     /* Set HCLK source form HXT and HCLK source divide 1  */
  19.     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HXT,CLK_HCLK_CLK_DIVIDER(1));

  20.     /* Enable external 12MHz HXT, 32KHz LXT and HIRC */
  21.     CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk | CLK_PWRCTL_LXTEN_Msk | CLK_PWRCTL_HIRC0EN_Msk | CLK_PWRCTL_HIRC1EN_Msk | CLK_PWRCTL_MIRCEN_Msk);

  22.     /* Waiting for clock ready */
  23.     CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk | CLK_STATUS_LXTSTB_Msk | CLK_STATUS_HIRC0STB_Msk | CLK_STATUS_HIRC1STB_Msk | CLK_STATUS_MIRCSTB_Msk);

  24.     CLK_SetCoreClock(32000000);                  /*  Set HCLK frequency 32MHz */

  25.     CLK_EnableModuleClock(UART0_MODULE);         /* Enable UART0 input clock */

  26.     /* Select IP clock source */
  27.     CLK_SetModuleClock(UART0_MODULE,CLK_CLKSEL1_UART0SEL_HIRC,CLK_UART0_CLK_DIVIDER(1));

  28.     /*---------------------------------------------------------------------------------------------------------*/
  29.     /* Init I/O Multi-function                                                                                 */
  30.     /*---------------------------------------------------------------------------------------------------------*/
  31.     /* Set PA multi-function pins for UART0 RXD and TXD */
  32.     SYS->GPB_MFPL &= ~( SYS_GPB_MFPL_PB0MFP_Msk | SYS_GPB_MFPL_PB1MFP_Msk);
  33.     SYS->GPB_MFPL |= (SYS_GPB_MFPL_PB0MFP_UART0_RXD | SYS_GPB_MFPL_PB1MFP_UART0_TXD );

  34.     SYS_LockReg();                               /* Lock protected registers */
  35. }

  36. void UART0_Init(void)
  37. {
  38.     /*---------------------------------------------------------------------------------------------------------*/
  39.     /* Init UART                                                                                               */
  40.     /*---------------------------------------------------------------------------------------------------------*/
  41.     SYS_ResetModule(UART0_RST);        /* Reset UART0 */
  42.     UART_Open(UART0, 115200);          /* Configure UART0 and set UART0 as baudrate 115200, N,8,1 */
  43. }


  44. /**
  45.   * @brief    Check User Configuration CONFIG0 bit 6 IAP boot setting. If it's not boot with IAP
  46.   *           mode, modify it and execute a chip reset to make it take effect.
  47.   * [url=home.php?mod=space&uid=266161]@return[/url]   Is boot with IAP mode or not.
  48.   * @retval   0   Success.
  49.   * @retval   -1  Failed on reading or programming User Configuration.
  50.   */
  51. static int  set_IAP_boot_mode(void)
  52. {
  53.     uint32_t  au32Config[2];           /* User Configuration */

  54.     if (FMC_ReadConfig(au32Config, 2) < 0) {     /* Read User Configuration CONFIG0 and CONFIG1. */
  55.         printf("\nRead User Config failed!\n");
  56.         return -1;                     /* Failed on reading User Configuration */
  57.     }

  58.     if (au32Config[0] & 0x40) {        /* Check if it's boot from APROM/LDROM with IAP. */
  59.         FMC_ENABLE_CFG_UPDATE();       /* Enable User Configuration update. */
  60.         au32Config[0] &= ~0x40;        /* Select IAP boot mode. */
  61.         FMC_WriteConfig(au32Config, 2);/* Update User Configuration CONFIG0 and CONFIG1. */

  62.         SYS->IPRST1 = SYS_IPRST1_CHIPRST_Msk;    /* Perform chip reset to make new User Config take effect. */
  63.     }
  64.     return 0;                          /* success */
  65. }


  66. /*
  67. *  Set stack base address to SP register.
  68. */
  69. #ifdef __ARMCC_VERSION                 /* for Keil compiler */
  70. __asm __set_SP(uint32_t _sp)
  71. {
  72.     MSR MSP, r0
  73.     BX lr
  74. }
  75. #endif


  76. /**
  77.   * @brief    Load an image to specified flash address. The flash area must have been enabled by
  78.   *           caller. For example, if caller want to program an image to LDROM, FMC_ENABLE_LD_UPDATE()
  79.   *           must be called prior to calling this function.
  80.   * @return   Image is successfully programmed or not.
  81.   * @retval   0   Success.
  82.   * @retval   -1  Program/verify failed.
  83.   */
  84. static int  load_image_to_flash(uint32_t image_base, uint32_t image_limit, uint32_t flash_addr, uint32_t max_size)
  85. {
  86.     uint32_t   i, j, u32Data, u32ImageSize, *pu32Loader;

  87.     u32ImageSize = max_size;           /* Give the maximum size of programmable flash area. */

  88.     printf("Program image to flash address 0x%x...", flash_addr);    /* information message */

  89.     /*
  90.      * program the whole image to specified flash area
  91.      */
  92.     pu32Loader = (uint32_t *)image_base;
  93.     for (i = 0; i < u32ImageSize; i += FMC_FLASH_PAGE_SIZE)  {

  94.         FMC_Erase(flash_addr + i);     /* erase a flash page */
  95.         for (j = 0; j < FMC_FLASH_PAGE_SIZE; j += 4) {               /* program image to this flash page */
  96.             FMC_Write(flash_addr + i + j, pu32Loader[(i + j) / 4]);
  97.         }
  98.     }
  99.     printf("OK.\nVerify ...");

  100.     /* Verify loader */
  101.     for (i = 0; i < u32ImageSize; i += FMC_FLASH_PAGE_SIZE) {
  102.         for (j = 0; j < FMC_FLASH_PAGE_SIZE; j += 4) {
  103.             u32Data = FMC_Read(flash_addr + i + j);        /* read a word from flash memory */

  104.             if (u32Data != pu32Loader[(i+j)/4]) {          /* check if the word read from flash be matched with original image */
  105.                 printf("data mismatch on 0x%x, [0x%x], [0x%x]\n", flash_addr + i + j, u32Data, pu32Loader[(i+j)/4]);
  106.                 return -1;             /* image program failed */
  107.             }

  108.             if (i + j >= u32ImageSize) /* check if it reach the end of image */
  109.                 break;
  110.         }
  111.     }
  112.     printf("OK.\n");
  113.     return 0;                          /* success */
  114. }


  115. int main()
  116. {
  117.     uint8_t     u8Item;                /* menu item */
  118.     uint32_t    u32Data;               /* temporary data word */
  119.     FUNC_PTR    *func;                 /* function pointer */

  120.     SYS_Init();                        /* Init System, IP clock and multi-function I/O */
  121.     UART0_Init();                      /* initialize UART0 */

  122.     /*---------------------------------------------------------------------------------------------------------*/
  123.     /* SAMPLE CODE                                                                                             */
  124.     /*---------------------------------------------------------------------------------------------------------*/

  125.     printf("\n\n");
  126.     printf("+----------------------------------------+\n");
  127.     printf("|     Nano103 FMC_IAP Sample Code        |\n");
  128.     printf("|           [APROM code]                 |\n");
  129.     printf("+----------------------------------------+\n");

  130.     SYS_UnlockReg();                   /* Unlock register lock protect */

  131.     FMC_Open();                        /* Enable FMC ISP function */

  132.     /*
  133.      *  Check if User Configuration CBS is boot with IAP mode.
  134.      *  If not, modify it.
  135.      */
  136.     if (set_IAP_boot_mode() < 0) {
  137.         printf("Failed to set IAP boot mode!\n");
  138.         goto lexit;                    /* Failed to set IAP boot mode. Program aborted. */
  139.     }

  140.     /* Read BS */
  141.     printf("  Boot Mode ............................. ");
  142.     if (FMC_GetBootSource() == 0)      /* Get boot source */
  143.         printf("[APROM]\n");           /* Is booting from APROM */
  144.     else {
  145.         printf("[LDROM]\n");           /* Is booting from LDROM */
  146.         printf("  WARNING: The sample code must execute in APROM!\n");
  147.         goto lexit;                    /* This sample program must execute in APROM. Program aborted. */
  148.     }

  149.     u32Data = FMC_ReadCID();           /* get company ID */
  150.     printf("  Company ID ............................ [0x%08x]\n", u32Data);

  151.     u32Data = FMC_ReadPID();           /* get product ID */
  152.     printf("  Product ID ............................ [0x%08x]\n", u32Data);

  153.     /* Read User Configuration CONFIG0 */
  154.     printf("  User Config 0 ......................... [0x%08x]\n", FMC_Read(FMC_CONFIG_BASE));
  155.     /* Read User Configuration CONFIG1 */
  156.     printf("  User Config 1 ......................... [0x%08x]\n", FMC_Read(FMC_CONFIG_BASE+4));

  157.     do {
  158.         printf("\n\n\n");
  159.         printf("+----------------------------------------+\n");
  160.         printf("|               Select                   |\n");
  161.         printf("+----------------------------------------+\n");
  162.         printf("| [0] Load IAP code to LDROM             |\n");
  163.         printf("| [1] Run IAP program (in LDROM)         |\n");
  164.         printf("+----------------------------------------+\n");
  165.         printf("Please select...");
  166.         u8Item = getchar();            /* block waiting to receive any one character from UART0 */
  167.         printf("%c\n", u8Item);        /* print out the selected item */

  168.         switch (u8Item) {
  169.         case '0':
  170.             FMC_ENABLE_LD_UPDATE();    /* Enable LDROM update capability */
  171.             /*
  172.              *  The binary image of LDROM code is embedded in this sample.
  173.              *  load_image_to_flash() will program this LDROM code to LDROM.
  174.              */
  175.             if (load_image_to_flash((uint32_t)&loaderImage1Base, (uint32_t)&loaderImage1Limit,
  176.                                     FMC_LDROM_BASE, FMC_LDROM_SIZE) != 0) {
  177.                 printf("Load image to LDROM failed!\n");
  178.                 goto lexit;            /* Load LDROM code failed. Program aborted. */
  179.             }
  180.             FMC_DISABLE_LD_UPDATE();   /* Disable LDROM update capability */
  181.             break;

  182.         case '1':
  183.             printf("\n\nChange VECMAP and branch to LDROM...\n");
  184.             while (!(UART0->FIFOSTS & UART_FIFOSTS_TXEMPTY_Msk));      /* Wait for UART0 TX FIFO cleared */

  185.             /*  NOTE!
  186.              *     Before change VECMAP, user MUST disable all interrupts.
  187.              *     The following code CANNOT locate in address 0x0 ~ 0x200.
  188.              */

  189.             /* FMC_SetVectorPageAddr(FMC_LDROM_BASE) */
  190.             FMC->ISPCMD = FMC_ISPCMD_VECMAP;              /* ISP command */
  191.             FMC->ISPADDR = FMC_LDROM_BASE;                /* Vector remap address */
  192.             FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;           /* Trigger ISP command */
  193.             while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) ;  /* Wait for ISP command done. */

  194.             /*
  195.              *  The reset handler address of an executable image is located at offset 0x4.
  196.              *  Thus, this sample get reset handler address of LDROM code from FMC_LDROM_BASE + 0x4.
  197.              */
  198.             func = (FUNC_PTR *)*(uint32_t *)(FMC_LDROM_BASE + 4);
  199.             /*
  200.              *  The stack base address of an executable image is located at offset 0x0.
  201.              *  Thus, this sample get stack base address of LDROM code from FMC_LDROM_BASE + 0x0.
  202.              */
  203.             __set_SP(*(uint32_t *)FMC_LDROM_BASE);
  204.             /*
  205.              *  Brach to the LDROM code's reset handler in way of function call.
  206.              */
  207.             func();
  208.             break;

  209.         default :
  210.             continue;                  /* invalid selection */
  211.         }
  212.     } while (1);


  213. lexit:                                 /* program exit */

  214.     FMC_Close();                       /* Disable FMC ISP function */

  215.     SYS_LockReg();                     /* Lock protected registers */

  216.     printf("\nFMC Sample Code Completed.\n");

  217.     while (1);
  218. }

  219. /*** (C) COPYRIGHT 2015 Nuvoton Technology Corp. ***/


antusheng 发表于 2017-12-5 18:32 | 显示全部楼层
  1. /******************************************************************************
  2. * @file     LDROM_main.c
  3. * @version  V1.00
  4. * $Revision: 6 $
  5. * $Date: 16/02/16 9:21a $
  6. * @brief    FMC LDROM IAP sample program for Nano103 MCU
  7. *
  8. * @note
  9. * Copyright (C) 2015 Nuvoton Technology Corp. All rights reserved.
  10. *****************************************************************************/
  11. #include <stdio.h>

  12. #include "Nano103.h"

  13. typedef void (FUNC_PTR)(void);


  14. void SYS_Init(void)
  15. {
  16.     SYS_UnlockReg();                             /* Unlock protected registers */

  17.     /* Set HCLK source form HXT and HCLK source divide 1  */
  18.     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HXT,CLK_HCLK_CLK_DIVIDER(1));

  19.     /* Enable external 12MHz HXT, 32KHz LXT and HIRC */
  20.     CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk | CLK_PWRCTL_LXTEN_Msk | CLK_PWRCTL_HIRC0EN_Msk | CLK_PWRCTL_HIRC1EN_Msk | CLK_PWRCTL_MIRCEN_Msk);

  21.     /* Waiting for clock ready */
  22.     CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk | CLK_STATUS_LXTSTB_Msk | CLK_STATUS_HIRC0STB_Msk | CLK_STATUS_HIRC1STB_Msk | CLK_STATUS_MIRCSTB_Msk);

  23.     CLK_SetCoreClock(32000000);                  /*  Set HCLK frequency 32MHz */

  24.     CLK_EnableModuleClock(UART0_MODULE);         /* Enable UART0 input clock */

  25.     /* Select IP clock source */
  26.     CLK_SetModuleClock(UART0_MODULE,CLK_CLKSEL1_UART0SEL_HIRC,CLK_UART0_CLK_DIVIDER(1));

  27.     /*---------------------------------------------------------------------------------------------------------*/
  28.     /* Init I/O Multi-function                                                                                 */
  29.     /*---------------------------------------------------------------------------------------------------------*/
  30.     /* Set PA multi-function pins for UART0 RXD and TXD */
  31.     SYS->GPB_MFPL &= ~( SYS_GPB_MFPL_PB0MFP_Msk | SYS_GPB_MFPL_PB1MFP_Msk);
  32.     SYS->GPB_MFPL |= (SYS_GPB_MFPL_PB0MFP_UART0_RXD | SYS_GPB_MFPL_PB1MFP_UART0_TXD );

  33.     SYS_LockReg();                               /* Lock protected registers */
  34. }

  35. void UART0_Init(void)
  36. {
  37.     /*---------------------------------------------------------------------------------------------------------*/
  38.     /* Init UART                                                                                               */
  39.     /*---------------------------------------------------------------------------------------------------------*/
  40.     SYS_ResetModule(UART0_RST);        /* Reset UART0 */
  41.     UART_Open(UART0, 115200);          /* Configure UART0 and set UART0 as baudrate 115200, N,8,1 */
  42. }


  43. /*
  44. *  Set stack base address to SP register.
  45. */
  46. #ifdef __ARMCC_VERSION                 /* for Keil compiler */
  47. __asm __set_SP(uint32_t _sp)
  48. {
  49.     MSR MSP, r0
  50.     BX lr
  51. }
  52. #endif


  53. int main()
  54. {
  55.     FUNC_PTR    *func;                 /* function pointer */

  56.     SYS_Init();                        /* Init System, IP clock and multi-function I/O */
  57.     UART0_Init();                      /* Initialize UART 0. */

  58.     /*---------------------------------------------------------------------------------------------------------*/
  59.     /* SAMPLE CODE                                                                                             */
  60.     /*---------------------------------------------------------------------------------------------------------*/

  61.     printf("\n\n");
  62.     printf("+----------------------------------------+\n");
  63.     printf("|     Nano103 FMC IAP Sample Code        |\n");
  64.     printf("|           [LDROM code]                 |\n");
  65.     printf("+----------------------------------------+\n");

  66.     SYS_UnlockReg();                   /* Unlock protected registers */

  67.     FMC_Open();                        /* Enable FMC ISP function */

  68.     printf("\n\nPress any key to branch to APROM...\n");
  69.     getchar();                         /* block on waiting for any one character input from UART0 */

  70.     printf("\n\nChange VECMAP and branch to LDROM...\n");
  71.     while (!(UART0->FIFOSTS & UART_FIFOSTS_TXEMPTY_Msk));       /* wait until UART0 TX FIFO is empty */

  72.     /*  NOTE!
  73.      *     Before change VECMAP, user MUST disable all interrupts.
  74.      */
  75.     FMC_SetVectorPageAddr(FMC_APROM_BASE);        /* Vector remap APROM page 0 to address 0. */
  76.     SYS_LockReg();                                /* Lock protected registers */

  77.     /*
  78.      *  The reset handler address of an executable image is located at offset 0x4.
  79.      *  Thus, this sample get reset handler address of APROM code from FMC_APROM_BASE + 0x4.
  80.      */
  81.     func = (FUNC_PTR *)*(uint32_t *)(FMC_APROM_BASE + 4);

  82.     /*
  83.      *  The stack base address of an executable image is located at offset 0x0.
  84.      *  Thus, this sample get stack base address of APROM code from FMC_APROM_BASE + 0x0.
  85.      */
  86.     __set_SP(*(uint32_t *)FMC_APROM_BASE);

  87.     /*
  88.      *  Brach to the LDROM code's reset handler in way of function call.
  89.      */
  90.     func();

  91.     while (1);
  92. }

  93. /*** (C) COPYRIGHT 2015 Nuvoton Technology Corp. ***/
antusheng 发表于 2017-12-5 18:36 | 显示全部楼层
不小心发现官方提供的有,给你发来了。你参考参考。
dongnanxibei 发表于 2017-12-5 20:33 | 显示全部楼层
新唐官方的BSP都提供的有对应的
dongnanxibei 发表于 2017-12-5 20:34 | 显示全部楼层
IAP.
看来你没看过官方的BSP。
小明的同学 发表于 2017-12-5 20:58 | 显示全部楼层
莫非新唐的单片机都可以做IAP,太强大了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

50

主题

1115

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部