野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 4390|回复: 1

求解读RT1052官方提供的Bootloader参考示例

[复制链接]
发表于 2022-10-7 14:52:17 | 显示全部楼层 |阅读模式
       采用https://mcuxpresso.nxp.com/en/selectMCUXpresso SDK Builder在线生成SDK,勾选所有工程后,在“SDK_2_12_1_EVKB-IMXRT1050\boards\evkbimxrt1050\bootloader_examples”目录下有“flashloader”工程,该工程是基于“MIMXRT1052_ram_flashloader”的配置, MIMXRT1052_ram_flashloader.zip (907 Bytes, 下载次数: 11) 实际上RT1052是使用512KB的SDRAM,地址应该是从0x8000 0000开始,而该工程编译出来的MAP文件,显示的是从0x2000 0000,这是怎么回事? flashloader.zip (84.58 KB, 下载次数: 14)

       如果采用32M的外挂NorFlash,使用xip功能,能否在boot阶段直接跳转实现jump_to_application(applicationAddress, stackPointer)?具体又是如何操作的呢?期盼各位坛友的各抒己见,提供宝贵的见解,谢谢。
       bl_main.c的代码展示:
  1. /*
  2. * Copyright (c) 2013-2015 Freescale Semiconductor, Inc.
  3. * Copyright 2016-2019 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */

  8. #define exit exit_default
  9. #include <stdbool.h>
  10. #include "bl_context.h"
  11. #include "bl_peripheral.h"
  12. #include "bl_shutdown_cleanup.h"
  13. #include "bootloader.h"
  14. #include "bootloader_common.h"
  15. #include "fsl_assert.h"
  16. #if !BL_FEATURE_HAS_NO_INTERNAL_FLASH
  17. #if !BL_DEVICE_IS_LPC_SERIES
  18. #include "fsl_flash.h"
  19. #else
  20. #include "fsl_iap.h"
  21. #endif
  22. #endif // #if !BL_FEATURE_HAS_NO_INTERNAL_FLASH
  23. #include "fsl_rtos_abstraction.h"
  24. #include "microseconds.h"
  25. #include "property.h"
  26. #include "vector_table_info.h"
  27. #if BL_FEATURE_CRC_CHECK
  28. #include "bl_app_crc_check.h"
  29. #endif
  30. #if BL_FEATURE_QSPI_MODULE
  31. #include "qspi.h"
  32. #endif
  33. #include "memory.h"

  34. #if BL_FEATURE_RELIABLE_UPDATE
  35. #include "bl_reliable_update.h"
  36. #endif

  37. //! @addtogroup bl_core
  38. //! @{

  39. ////////////////////////////////////////////////////////////////////////////////
  40. // Prototypes
  41. ////////////////////////////////////////////////////////////////////////////////

  42. #if defined(DEBUG) || defined(_DEBUG)
  43. static const char *get_peripheral_name(uint32_t peripheralTypeMask);
  44. #endif

  45. #if !BL_FEATURE_TIMEOUT
  46. static void get_user_application_entry(uint32_t *appEntry, uint32_t *appStack);
  47. static void jump_to_application(uint32_t applicationAddress, uint32_t stackPointer);
  48. static bool is_direct_boot(void);
  49. #endif // !BL_FEATURE_TIMEOUT
  50. static peripheral_descriptor_t const *get_active_peripheral(void);
  51. static void bootloader_init(void);
  52. static void bootloader_run(void);
  53. #if !BL_FEATURE_HAS_NO_INTERNAL_FLASH
  54. static void bootloader_flash_init(void);
  55. #endif // #if !BL_FEATURE_HAS_NO_INTERNAL_FLASH
  56. #if BL_FEATURE_QSPI_MODULE
  57. static void configure_quadspi_as_needed(void);
  58. #endif

  59. int main(void);

  60. // Not used, but needed to resolve reference in startup.s.
  61. // uint32_t g_bootloaderTree;

  62. ////////////////////////////////////////////////////////////////////////////////
  63. // Variables
  64. ////////////////////////////////////////////////////////////////////////////////

  65. ////////////////////////////////////////////////////////////////////////////////
  66. // Code
  67. ////////////////////////////////////////////////////////////////////////////////

  68. #if defined(DEBUG) || defined(_DEBUG)
  69. //! [url=home.php?mod=space&uid=41770]@brief[/url] Returns the name of a peripheral given its type mask.
  70. const char *get_peripheral_name(uint32_t peripheralTypeMask)
  71. {
  72.     const char *const kPeripheralNames[] = {
  73.         "UART", // kPeripheralType_UART
  74.         "I2C",  // kPeripheralType_I2CSlave
  75.         "SPI",  // kPeripheralType_SPISlave
  76.         "CAN",  // kPeripheralType_CAN
  77.         "HID",  // kPeripheralType_USB_HID
  78.         "CDC",  // kPeripheralType_USB_CDC
  79.         "DFU",  // kPeripheralType_USB_DFU
  80.         "MSD"   // kPeripheralType_USB_MSC
  81.     };
  82.     uint32_t i;
  83.     for (i = 0; i < ARRAY_SIZE(kPeripheralNames); ++i)
  84.     {
  85.         if (peripheralTypeMask & (1 << i))
  86.         {
  87.             return kPeripheralNames[i];
  88.         }
  89.     }

  90.     return "Unknown peripheral";
  91. }
  92. #endif // DEBUG

  93. #if !BL_FEATURE_TIMEOUT
  94. //! @brief Returns the user application address and stack pointer.
  95. //!
  96. //! For flash-resident and rom-resident target, gets the user application address
  97. //! and stack pointer from the APP_VECTOR_TABLE.
  98. //! Ram-resident version does not support jumping to application address.
  99. static void get_user_application_entry(uint32_t *appEntry, uint32_t *appStack)
  100. {
  101.     assert(appEntry);
  102.     assert(appStack);

  103. #ifdef BL_TARGET_RAM
  104.     *appEntry = 0;
  105.     *appStack = 0;
  106. #else
  107. #if FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL
  108.     // Check if address of SP and PC is in an execute-only region.
  109.     if (!is_in_execute_only_region(kDefaultVectorTableAddress, 8))
  110.     {
  111.         *appEntry = APP_VECTOR_TABLE[kInitialPC];
  112.         *appStack = APP_VECTOR_TABLE[kInitialSP];
  113.     }
  114.     else
  115.     {
  116.         // Set to invalid value when vector table is in execute-only region,
  117.         // as ROM doesn't support jumping to an application in such region so far.
  118.         // The main purpose of below operation is to prevent ROM from inifinit loop
  119.         // between NVIC_SystemReset() and fetching SP and PC frome execute-only region.
  120.         *appEntry = 0;
  121.         *appStack = 0;
  122.     }
  123. #else
  124. #if BL_FEATURE_RELIABLE_UPDATE
  125.     if (g_bootloaderContext.imageStart != 0xffffffffu)
  126.     {
  127.         uint32_t *appVectorTable = (uint32_t *)g_bootloaderContext.imageStart;
  128.         *appEntry = appVectorTable[kInitialPC];
  129.         *appStack = appVectorTable[kInitialSP];
  130.     }
  131.     else
  132.     {
  133.         *appEntry = 0xffffffffu;
  134.         *appStack = 0xffffffffu;
  135.     }
  136. #else
  137.     *appEntry = APP_VECTOR_TABLE[kInitialPC];
  138.     *appStack = APP_VECTOR_TABLE[kInitialSP];
  139. #endif // BL_FEATURE_RELIABLE_UPDATE
  140. #endif //  FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL
  141. #endif // BL_TARGET_RAM
  142. }
  143. #endif // BL_FEATURE_TIMEOUT

  144. #if !BL_FEATURE_TIMEOUT
  145. bool is_direct_boot(void)
  146. {
  147.     bootloader_configuration_data_t *configurationData =
  148.         &g_bootloaderContext.propertyInterface->store->configurationData;

  149.     return (~configurationData->bootFlags) & kBootFlag_DirectBoot;
  150. }
  151. #endif // !BL_FEATURE_TIMEOUT

  152. #if !BL_FEATURE_TIMEOUT
  153. //! @brief Exits bootloader and jumps to the user application.
  154. static void jump_to_application(uint32_t applicationAddress, uint32_t stackPointer)
  155. {
  156. #if BL_FEATURE_OTFAD_MODULE
  157.     quadspi_cache_clear();
  158.     oftfad_resume_as_needed();
  159. #endif

  160.     shutdown_cleanup(kShutdownType_Shutdown);

  161.     // Create the function call to the user application.
  162.     // Static variables are needed since changed the stack pointer out from under the compiler
  163.     // we need to ensure the values we are using are not stored on the previous stack
  164.     static uint32_t s_stackPointer = 0;
  165.     s_stackPointer = stackPointer;
  166.     static void (*farewellBootloader)(void) = 0;
  167.     farewellBootloader = (void (*)(void))applicationAddress;

  168.     // Set the VTOR to the application vector table address.
  169.     SCB->VTOR = (uint32_t)APP_VECTOR_TABLE;

  170.     // Set stack pointers to the application stack pointer.
  171.     __set_MSP(s_stackPointer);
  172.     __set_PSP(s_stackPointer);

  173.     // Jump to the application.
  174.     farewellBootloader();
  175.     // Dummy fcuntion call, should never go to this fcuntion call
  176.     shutdown_cleanup(kShutdownType_Shutdown);
  177. }
  178. #endif // !BL_FEATURE_TIMEOUT

  179. //! A given jump address is considered valid if:
  180. //! - Not 0x00000000
  181. //! - Not 0xffffffff
  182. //! - Not the reset handler entry point for the bootloader
  183. //! - Is in flash or is in RAM or QuadSPI (if available)
  184. //! [url=home.php?mod=space&uid=87825]@note[/url] this interface is also used by the configure_quadspi command
  185. bool is_valid_application_location(uint32_t applicationAddress)
  186. {
  187.     const memory_map_entry_t *map;
  188.     // Verify that the jumpLocation is non zero and then either within flash or RAM, both calculations are:
  189.     // (jumpLocation >= startAddress) && (jumpLocation < (startAddress + size))
  190.     if ((!applicationAddress) ||              // address is not null AND
  191.         (applicationAddress == 0xffffffff) || // address is not blank Flash (0xff) AND
  192.         (applicationAddress == (uint32_t)&Reset_Handler))
  193.     {
  194.         return false;
  195.     }

  196.     bool isValid = false;
  197.     const uint32_t minThumb2InstructionSize = 2; // smallest thumb2 instruction size is 16-bit.
  198.     // Check if the application address is in valid executable memory range
  199.     status_t status = find_map_entry(applicationAddress, minThumb2InstructionSize, &map);
  200.     if ((status == kStatus_Success) && (map->memoryProperty & kMemoryIsExecutable))
  201.     {
  202.         isValid = true;
  203.     }

  204.     return isValid;
  205. }

  206. bool is_valid_stackpointer_location(uint32_t stackpointerAddress)
  207. {
  208.     const memory_map_entry_t *map;
  209.     bool isValid = false;

  210.     map = &g_bootloaderContext.memoryMap[0];

  211.     while (map->memoryInterface != NULL)
  212.     {
  213.         if ((map->memoryProperty & kMemoryIsExecutable) && (map->memoryProperty & kMemoryType_RAM))
  214.         {
  215.             if ((stackpointerAddress > map->startAddress) && (stackpointerAddress <= (map->endAddress + 1)))
  216.             {
  217.                 isValid = true;
  218.                 break;
  219.             }
  220.         }

  221.         ++map;
  222.     }

  223.     return isValid;
  224. }

  225. #if !BL_FEATURE_TIMEOUT
  226. //! @brief Jump application is considered ready for executing if the location is valid and crc check is passed
  227. static bool is_application_ready_for_executing(uint32_t applicationAddress)
  228. {
  229.     bool result = is_valid_application_location(applicationAddress);

  230. #if BL_FEATURE_OTFAD_MODULE
  231.     if (result && is_qspi_present())
  232.     {
  233.         quadspi_cache_clear();
  234.         status_t status = otfad_init_as_needed();
  235.         if (status != kStatus_Success)
  236.         {
  237.             result = false;
  238.         }
  239.         update_qspi_otfad_init_status(status);
  240.     }
  241. #endif

  242. #if BL_FEATURE_CRC_CHECK
  243.     // Validate application crc only if its location is valid
  244.     if (result)
  245.     {
  246.         result = is_application_crc_check_pass();
  247.     }

  248. #if BL_FEATURE_OTFAD_MODULE
  249.     otfad_bypass_as_needed();
  250. #endif // BL_FEATURE_OTFAD_MODULE

  251. #endif

  252.     return result;
  253. }
  254. #endif // !BL_FEATURE_TIMEOUT

  255. //! @brief Determines the active peripheral.
  256. //!
  257. //! This function has several stages:
  258. //! - Init enabled peripherals.
  259. //! - Compute timeout.
  260. //! - Wait for peripheral activity with timeout.
  261. //! - Shutdown inactive peripherals.
  262. //!
  263. //! If peripheral detection times out, then this function will call jump_to_application() to
  264. //! directly enter the user application.
  265. //!
  266. //! The timeout value comes from the BCA if set, or the #BL_DEFAULT_PERIPHERAL_DETECT_TIMEOUT
  267. //! configuration macro. If the boot pin is asserted, or if there is not a valid user application
  268. //! in flash, then the timeout is disabled and peripheral detection will continue infinitely.
  269. static peripheral_descriptor_t const *get_active_peripheral(void)
  270. {
  271.     peripheral_descriptor_t const *peripheral;
  272.     peripheral_descriptor_t const *activePeripheral = NULL;
  273.     bootloader_configuration_data_t *configurationData =
  274.         &g_bootloaderContext.propertyInterface->store->configurationData;

  275.     // Bring up all the peripherals
  276.     for (peripheral = g_peripherals; peripheral->typeMask != 0; ++peripheral)
  277.     {
  278.         // Check that the peripheral is enabled in the user configuration data
  279.         if (configurationData->enabledPeripherals & peripheral->typeMask)
  280.         {
  281.             assert(peripheral->controlInterface->init);

  282. #if defined(DEBUG) || defined(_DEBUG)
  283.             debug_printf("Initing %s\r\n", get_peripheral_name(peripheral->typeMask));
  284. #endif
  285.             peripheral->controlInterface->init(peripheral, peripheral->packetInterface->byteReceivedCallback);
  286.         }
  287.     }

  288. #if !BL_FEATURE_TIMEOUT
  289. #if BL_FEATURE_POWERDOWN
  290.     bool shortTimeout = false;
  291. #endif
  292.     const uint64_t ticksPerMillisecond = microseconds_convert_to_ticks(1000);

  293.     // Get the user application entry point and stack pointer.
  294.     uint32_t applicationAddress, stackPointer;
  295.     get_user_application_entry(&applicationAddress, &stackPointer);

  296.     uint64_t lastTicks = 0;    // Value of our last recorded ticks second marker
  297.     uint64_t timeoutTicks = 0; // The number of ticks we will wait for timeout, 0 means no timeout

  298.     // If the boot to rom option is not set AND there is a valid jump application determine the timeout value
  299.     if (!is_boot_pin_asserted() && is_application_ready_for_executing(applicationAddress))
  300.     {
  301.         if (is_direct_boot())
  302.         {
  303.             jump_to_application(applicationAddress, stackPointer);
  304.         }

  305.         // Calculate how many ticks we need to wait based on the bootloader config. Check to see if
  306.         // there is a valid configuration data value for the timeout. If there's not, use the
  307.         // default timeout value.
  308.         uint32_t milliseconds;
  309.         if (configurationData->peripheralDetectionTimeoutMs != 0xFFFF)
  310.         {
  311.             milliseconds = configurationData->peripheralDetectionTimeoutMs;
  312.         }
  313.         else
  314.         {
  315.             milliseconds = BL_DEFAULT_PERIPHERAL_DETECT_TIMEOUT;
  316.         }
  317.         timeoutTicks = milliseconds * ticksPerMillisecond;

  318.         // save how many ticks we're currently at before the detection loop starts
  319.         lastTicks = microseconds_get_ticks();
  320. #if BL_FEATURE_POWERDOWN
  321.         shortTimeout = true;
  322. #endif
  323.     }
  324. #if BL_FEATURE_POWERDOWN
  325.     else
  326.     {
  327.         timeoutTicks = BL_DEFAULT_POWERDOWN_TIMEOUT * ticksPerMillisecond;
  328.         lastTicks = microseconds_get_ticks();
  329.     }
  330. #endif
  331. #endif // !BL_FEATURE_TIMEOUT

  332.     // Wait for a peripheral to become active
  333.     while (activePeripheral == NULL)
  334.     {
  335. #if !BL_FEATURE_TIMEOUT
  336.         // If timeout is enabled, check to see if we've exceeded it.
  337.         if (timeoutTicks)
  338.         {
  339.             // Note that we assume that the tick counter won't overflow and wrap back to 0.
  340.             // The timeout value is only up to 65536 milliseconds, and the tick count starts
  341.             // at zero when when inited the microseconds driver just a few moments ago.
  342.             uint64_t elapsedTicks = microseconds_get_ticks() - lastTicks;

  343.             // Check if the elapsed time is longer than the timeout.
  344.             if (elapsedTicks >= timeoutTicks)
  345.             {
  346. #if BL_FEATURE_POWERDOWN
  347.                 if (shortTimeout)
  348.                 {
  349. #endif
  350.                     // In the case of the typical peripheral timeout, jump to the user application.
  351.                     jump_to_application(applicationAddress, stackPointer);
  352. #if BL_FEATURE_POWERDOWN
  353.                 }
  354.                 else
  355.                 {
  356.                     // Make sure a timeout value has been defined before shutting down.
  357.                     if (BL_DEFAULT_POWERDOWN_TIMEOUT)
  358.                     {
  359.                         // Shut down the bootloader and return to reset-type state prior to low
  360.                         // power entry
  361.                         shutdown_cleanup(kShutdownType_Shutdown);

  362.                         // Enter VLLS1 low power mode
  363.                         enter_vlls1();
  364.                     }
  365.                 }
  366. #endif
  367.             }
  368.         }
  369. #endif // !BL_FEATURE_TIMEOUT
  370.        // Traverse through all the peripherals
  371.         for (peripheral = g_peripherals; peripheral->typeMask != 0; ++peripheral)
  372.         {
  373.             // Check that the peripheral is enabled in the user configuration data
  374.             if (configurationData->enabledPeripherals & peripheral->typeMask)
  375.             {
  376.                 assert(peripheral->controlInterface->pollForActivity);

  377.                 if (peripheral->controlInterface->pollForActivity(peripheral))
  378.                 {
  379. #if defined(DEBUG) && !defined(DEBUG_PRINT_DISABLE)
  380.                     debug_printf("%s is active\r\n", get_peripheral_name(peripheral->typeMask));
  381. #endif
  382.                     activePeripheral = peripheral;
  383.                     break;
  384.                 }
  385.             }
  386.         }
  387.     }

  388.     // Shut down all non active peripherals
  389.     for (peripheral = g_peripherals; peripheral->typeMask != 0; ++peripheral)
  390.     {
  391.         // Check that the peripheral is enabled in the user configuration data
  392.         if (configurationData->enabledPeripherals & peripheral->typeMask)
  393.         {
  394.             if (activePeripheral != peripheral)
  395.             {
  396. #if defined(DEBUG) && !defined(DEBUG_PRINT_DISABLE)
  397.                 debug_printf("Shutting down %s\r\n", get_peripheral_name(peripheral->typeMask));
  398. #endif
  399.                 assert(peripheral->controlInterface->shutdown);
  400.                 peripheral->controlInterface->shutdown(peripheral);
  401.             }
  402.         }
  403.     }

  404.     return activePeripheral;
  405. }

  406. #if BL_FEATURE_QSPI_MODULE
  407. static void configure_quadspi_as_needed(void)
  408. {
  409.     // Start the lifetime counter
  410.     microseconds_init();
  411.     if (qspi_need_configure())
  412.     {
  413.         status_t qspiOtfadInitStatus = kStatus_QspiNotConfigured;
  414.         // Try to configure QuadSPI module based on on qspi_config_block_pointer in BCA first,
  415.         // If bootloader cannot get qspi config block from internal flash, try to configure QSPI
  416.         // based on default place (start address of QuadSPI memory).
  417.         uint32_t qspi_config_block_base =
  418.             g_bootloaderContext.propertyInterface->store->configurationData.qspi_config_block_pointer;

  419.         // Get the start address and flash size
  420.         // Note: Basically BCA is always stored in Main flash memory
  421.         uint32_t flashStart;
  422.         g_bootloaderContext.flashDriverInterface->flash_get_property(g_bootloaderContext.allFlashState,
  423.                                                                      kFLASH_PropertyPflash0BlockBaseAddr, &flashStart);
  424.         uint32_t flashSize;
  425.         g_bootloaderContext.flashDriverInterface->flash_get_property(g_bootloaderContext.allFlashState,
  426.                                                                      kFLASH_PropertyPflash0TotalSize, &flashSize);

  427.         // Check if the pointer of qspi config block is valid.
  428.         if ((qspi_config_block_base != 0xFFFFFFFF) && (qspi_config_block_base > flashStart) &&
  429.             (qspi_config_block_base <= (flashStart + flashSize - sizeof(qspi_config_t))))
  430.         {
  431. #if FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL
  432.             if (!is_in_execute_only_region(qspi_config_block_base, sizeof(qspi_config_t)))
  433.             {
  434.                 qspiOtfadInitStatus = quadspi_init((void *)qspi_config_block_base);
  435.             }
  436. #else
  437.             qspiOtfadInitStatus = quadspi_init((void *)qspi_config_block_base);
  438. #endif // FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL
  439.         }

  440.         if (qspiOtfadInitStatus == kStatus_QspiNotConfigured)
  441.         {
  442.             qspiOtfadInitStatus = quadspi_init(NULL);
  443.         }
  444.         update_qspi_otfad_init_status(qspiOtfadInitStatus);
  445.     }
  446.     // Shutdown the lifetime counter before configuring clock.
  447.     lock_acquire();
  448.     microseconds_shutdown();
  449.     lock_release();
  450. }
  451. #endif

  452. #if !BL_FEATURE_HAS_NO_INTERNAL_FLASH
  453. static void bootloader_flash_init(void)
  454. {
  455.     g_bootloaderContext.flashDriverInterface->flash_init(g_bootloaderContext.allFlashState);
  456. #if !BL_DEVICE_IS_LPC_SERIES
  457.     (void)FTFx_CACHE_Init(g_bootloaderContext.allFlashCacheState);
  458. #endif
  459. #if BL_FEATURE_SUPPORT_DFLASH
  460.     check_available_dFlash();
  461.     if (g_bootloaderContext.dflashDriverInterface != NULL)
  462.     {
  463.         (void)g_bootloaderContext.dflashDriverInterface->flash_init(g_bootloaderContext.dFlashState);
  464.     }
  465. #endif // BL_FEATURE_SUPPORT_DFLASH
  466. }
  467. #endif // #if !BL_FEATURE_HAS_NO_INTERNAL_FLASH

  468. //! @brief Initialize the bootloader and peripherals.
  469. //!
  470. //! This function initializes hardware and clocks, loads user configuration data, and initialzes
  471. //! a number of drivers. It then enters the active peripheral detection phase by calling
  472. //! get_active_peripheral(). Once the peripheral is detected, the packet and comand interfaces
  473. //! are initialized.
  474. //!
  475. //! Note that this routine may not return if peripheral detection times out and the bootloader
  476. //! jumps directly to the user application in flash.
  477. static void bootloader_init(void)
  478. {
  479.     // Init the global irq lock
  480.     lock_init();

  481.     // Init pinmux and other hardware setup.
  482.     init_hardware();

  483. #if !BL_FEATURE_HAS_NO_INTERNAL_FLASH
  484.     // Init flash driver.
  485.     bootloader_flash_init();
  486. #endif // #if !BL_FEATURE_HAS_NO_INTERNAL_FLASH

  487. // Init QSPI module if needed
  488. #if BL_FEATURE_QSPI_MODULE
  489.     configure_quadspi_as_needed();
  490. #endif // BL_FEATURE_QSPI_MODULE

  491.     // Configure clocks.
  492.     configure_clocks(kClockOption_EnterBootloader);

  493.     // Start the lifetime counter
  494.     microseconds_init();

  495. #if BL_FEATURE_BYPASS_WATCHDOG
  496.     bootloader_watchdog_init();
  497. #endif // BL_FEATURE_BYPASS_WATCHDOG

  498.     // Init address range of flash array, SRAM_L and SRAM U.
  499.     g_bootloaderContext.memoryInterface->init();
  500.    
  501. #if BL_FEATURE_PHANTOM_UPDATE
  502.     // Update the flash_size, ram_size and available peripherals and falshy_swap based on IFR   
  503.     phantom_update();     
  504. #endif // BL_FEATURE_PHANTOM_UPDATE
  505.    
  506.     // Fully init the property store.
  507.     g_bootloaderContext.propertyInterface->init();

  508. #if BL_FEATURE_RELIABLE_UPDATE
  509.     bootloader_reliable_update_as_requested(kReliableUpdateOption_Normal, 0);
  510. #endif // BL_FEATURE_RELIABLE_UPDATE

  511.     // Message so python instantiated debugger can tell the
  512.     // bootloader application is running on the target.
  513.     debug_printf("\r\n\r\nRunning bootloader...\r\n");

  514. #if defined(DEBUG) && !defined(DEBUG_PRINT_DISABLE)
  515.     standard_version_t version = g_bootloaderContext.propertyInterface->store->bootloaderVersion;
  516.     debug_printf("Bootloader version %c%d.%d.%d\r\n", version.name, version.major, version.minor, version.bugfix);
  517. #endif

  518.     //    generate_key_blob_test();

  519.     // Wait for a peripheral to become active.
  520.     g_bootloaderContext.activePeripheral = get_active_peripheral();
  521.     assert(g_bootloaderContext.activePeripheral);

  522.     // Validate required active peripheral interfaces.
  523.     assert(g_bootloaderContext.activePeripheral->controlInterface);

  524. #if defined(BL_FEATURE_6PINS_PERIPHERAL) && BL_FEATURE_6PINS_PERIPHERAL
  525.     // Fully configure the pinmux
  526.     if (g_bootloaderContext.activePeripheral->pinmuxConfig)
  527.     {
  528.         g_bootloaderContext.activePeripheral->pinmuxConfig(g_bootloaderContext.activePeripheral->instance,
  529.                                                            kPinmuxType_Peripheral);
  530.     }
  531. #endif // BL_FEATURE_6PINS_PERIPHERAL

  532.     // Init the active peripheral.
  533.     if (g_bootloaderContext.activePeripheral->byteInterface &&
  534.         g_bootloaderContext.activePeripheral->byteInterface->init)
  535.     {
  536.         g_bootloaderContext.activePeripheral->byteInterface->init(g_bootloaderContext.activePeripheral);
  537.     }
  538.     if (g_bootloaderContext.activePeripheral->packetInterface &&
  539.         g_bootloaderContext.activePeripheral->packetInterface->init)
  540.     {
  541.         g_bootloaderContext.activePeripheral->packetInterface->init(g_bootloaderContext.activePeripheral);
  542.     }

  543.     // Initialize the command processor component.
  544.     g_bootloaderContext.commandInterface->init();
  545. }

  546. //! @brief Bootloader outer loop.
  547. //!
  548. //! Infinitely calls the command interface and active peripheral control interface pump routines.
  549. static void bootloader_run(void)
  550. {
  551.     const peripheral_descriptor_t *activePeripheral = g_bootloaderContext.activePeripheral;

  552.     assert(g_bootloaderContext.commandInterface->pump);

  553.     // Read and execute commands.
  554.     while (1)
  555.     {
  556.         g_bootloaderContext.commandInterface->pump();

  557.         // Pump the active peripheral.
  558.         if (activePeripheral->controlInterface->pump)
  559.         {
  560.             activePeripheral->controlInterface->pump(activePeripheral);
  561.         }
  562.     }
  563. }

  564. //! @brief Entry point for the bootloader.
  565. int main(void)
  566. {
  567.     bootloader_init();
  568.     bootloader_run();

  569.     // Should never end up here.
  570.     debug_printf("Warning: reached end of main()\r\n");
  571.     return 0;
  572. }

  573. //! Since we never exit this gets rid of the C standard functions that cause
  574. //! extra ROM size usage.
  575. #undef exit
  576. void exit(int arg) {}

  577. #if defined(__CC_ARM) || (__ARMCC_VERSION)
  578. #define ITM_Port8(n) (*((volatile unsigned char *)(0xE0000000 + 4 * n)))
  579. #define ITM_Port16(n) (*((volatile unsigned short *)(0xE0000000 + 4 * n)))
  580. #define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000 + 4 * n)))

  581. #define DEMCR (*((volatile unsigned long *)(0xE000EDFC)))
  582. #define TRCENA 0x01000000

  583. FILE __stdout;
  584. FILE __stdin;

  585. int fputc(int ch, FILE *f)
  586. {
  587.     if (DEMCR & TRCENA)
  588.     {
  589.         while (ITM_Port32(0) == 0)
  590.             ;
  591.         ITM_Port8(0) = ch;
  592.     }
  593.     return (ch);
  594. }
  595. #endif

  596. //! @}

  597. ////////////////////////////////////////////////////////////////////////////////
  598. // EOF
  599. ////////////////////////////////////////////////////////////////////////////////
复制代码


回复

使用道具 举报

发表于 2022-11-10 17:04:18 | 显示全部楼层
回复

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-4-26 09:02 , Processed in 0.036908 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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