硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2616|回复: 2
收起左侧

[SPI/QSPI] STM32H7的QSPI内存映射模式,自动查询模式和间接模式例程学习

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
发表于 2018-10-8 01:33:13 | 显示全部楼层 |阅读模式
HAL库配套了如下几个例子:
QQ截图20181008013139.png

对应的硬件如下:

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107122
QQ
 楼主| 发表于 2018-10-8 01:49:13 | 显示全部楼层
例程1:QSPI_ExecuteInPlace

这个例子做的有点意思,是在工程里面专门编写了一个函数GpioToggle,并通过脚本和SENTION设置,将其编排到QSPI的地址空间,系统上电后,通过用户程序将其复制到QSPI里面

然后跳转到这个函数执行,也就是跳转到QSPI执行了。


代码:

  1. /* Private typedef -----------------------------------------------------------*/
  2. /* Private define ------------------------------------------------------------*/
  3. /* Private macro -------------------------------------------------------------*/
  4. #if defined(__CC_ARM)
  5. extern uint32_t Load$QSPI$Base;
  6. extern uint32_t Load$QSPI$Length;
  7. #elif defined(__ICCARM__)
  8. #pragma section =".qspi"
  9. #pragma section =".qspi_init"
  10. #elif defined(__GNUC__)
  11. extern uint32_t _qspi_init_base;
  12. extern uint32_t _qspi_init_length;
  13. #endif

  14. /* Private variables ---------------------------------------------------------*/
  15. QSPI_HandleTypeDef QSPIHandle;
  16. __IO uint8_t CmdCplt, RxCplt, TxCplt, StatusMatch;

  17. /* Private function prototypes -----------------------------------------------*/
  18. static void SystemClock_Config(void);
  19. static void Error_Handler(void);
  20. static void CPU_CACHE_Enable(void);
  21. static void QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi);
  22. static void QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi);
  23. static void QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi);
  24. static void GpioToggle(void);

  25. /* Private functions ---------------------------------------------------------*/

  26. /**
  27.   * @brief  Main program
  28.   * @param  None
  29.   * @retval None
  30.   */
  31. int main(void)
  32. {
  33.   QSPI_CommandTypeDef      sCommand;
  34.   QSPI_MemoryMappedTypeDef sMemMappedCfg;
  35.   __IO uint32_t qspi_addr = 0;
  36.   uint8_t *flash_addr = NULL;
  37.   __IO uint8_t step = 0;
  38.   uint32_t max_size, size = 0;

  39.   /* Enable the CPU Cache */
  40.   CPU_CACHE_Enable();
  41.         
  42.   /* STM32H7xx HAL library initialization:

  43.        - Systick timer is configured by default as source of time base, but user
  44.          can eventually implement his proper time base source (a general purpose
  45.          timer for example or other time source), keeping in mind that Time base
  46.          duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
  47.          handled in milliseconds basis.
  48.        - Set NVIC Group Priority to 4
  49.        - Low Level Initialization
  50.      */
  51.   HAL_Init();

  52.   /* Configure the system clock to 400 MHz */
  53.   SystemClock_Config();

  54.   BSP_LED_Init(LED1);
  55.   BSP_LED_Init(LED2);
  56.   BSP_LED_Init(LED3);
  57.   BSP_LED_Init(LED4);

  58.   /* Initialize QuadSPI ------------------------------------------------------ */
  59.   QSPIHandle.Instance = QUADSPI;
  60.   HAL_QSPI_DeInit(&QSPIHandle);

  61.   QSPIHandle.Init.ClockPrescaler     = 1;
  62.   QSPIHandle.Init.FifoThreshold      = 4;
  63.   QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
  64.   QSPIHandle.Init.FlashSize          = QSPI_FLASH_SIZE;
  65.   QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
  66.   QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;
  67.   QSPIHandle.Init.FlashID            = QSPI_FLASH_ID_1;
  68.   QSPIHandle.Init.DualFlash          = QSPI_DUALFLASH_DISABLE;

  69.   if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
  70.   {
  71.     Error_Handler();
  72.   }


  73.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  74.   sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
  75.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  76.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  77.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  78.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;

  79. #if defined(__CC_ARM)
  80.   max_size = (uint32_t)(&Load$QSPI$Length);
  81. #elif defined(__ICCARM__)
  82.   max_size = __section_size(".qspi_init");
  83. #elif defined(__GNUC__)
  84.   max_size = (uint32_t)((uint8_t *)(&_qspi_init_length));
  85. #endif

  86.   while(1)
  87.   {
  88.     switch(step)
  89.     {
  90.       case 0:
  91.         CmdCplt = 0;

  92.         /* Enable write operations ------------------------------------------- */
  93.         QSPI_WriteEnable(&QSPIHandle);

  94.         /* Erasing Sequence -------------------------------------------------- */
  95.         sCommand.Instruction = SECTOR_ERASE_CMD;
  96.         sCommand.AddressMode = QSPI_ADDRESS_1_LINE;
  97.         sCommand.Address     = qspi_addr;
  98.         sCommand.DataMode    = QSPI_DATA_NONE;
  99.         sCommand.DummyCycles = 0;

  100.         if (HAL_QSPI_Command_IT(&QSPIHandle, &sCommand) != HAL_OK)
  101.         {
  102.           Error_Handler();
  103.         }

  104.         step++;
  105.         break;

  106.       case 1:
  107.         if(CmdCplt != 0)
  108.         {
  109.           CmdCplt = 0;
  110.           StatusMatch = 0;

  111.           /* Configure automatic polling mode to wait for end of erase ------- */  
  112.           QSPI_AutoPollingMemReady(&QSPIHandle);

  113. #if defined(__CC_ARM)
  114.             flash_addr = (uint8_t *)(&Load$QSPI$Base);
  115. #elif defined(__ICCARM__)
  116.           flash_addr = (uint8_t *)(__section_begin(".qspi_init"));
  117. #elif defined(__GNUC__)
  118.             flash_addr = (uint8_t *)(&_qspi_init_base);
  119. #endif
  120.          
  121.           /* Copy only one page if the section is bigger */
  122.           if (max_size > QSPI_PAGE_SIZE)
  123.           {
  124.             size = QSPI_PAGE_SIZE;
  125.           }
  126.           else
  127.           {
  128.             size = max_size;
  129.           }

  130.           step++;
  131.         }
  132.         break;

  133.       case 2:
  134.         if(StatusMatch != 0)
  135.         {
  136.           StatusMatch = 0;
  137.           TxCplt = 0;
  138.          
  139.               /* Enable write operations ----------------------------------------- */
  140.             QSPI_WriteEnable(&QSPIHandle);

  141.             /* Writing Sequence ------------------------------------------------ */
  142.             sCommand.Instruction = QUAD_IN_FAST_PROG_CMD;
  143.             sCommand.AddressMode = QSPI_ADDRESS_1_LINE;
  144.             sCommand.Address     = qspi_addr;
  145.             sCommand.DataMode    = QSPI_DATA_4_LINES;
  146.             sCommand.NbData      = size;

  147.             if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  148.             {
  149.               Error_Handler();
  150.             }

  151.             if (HAL_QSPI_Transmit_DMA(&QSPIHandle, flash_addr) != HAL_OK)
  152.             {
  153.               Error_Handler();
  154.             }

  155.             step++;

  156.         }
  157.         break;

  158.       case 3:
  159.         if(TxCplt != 0)
  160.         {
  161.           TxCplt = 0;
  162.           StatusMatch = 0;

  163.           /* Configure automatic polling mode to wait for end of program ----- */  
  164.           QSPI_AutoPollingMemReady(&QSPIHandle);

  165.           step++;
  166.         }
  167.         break;

  168.       case 4:
  169.         if(StatusMatch != 0)
  170.         {
  171.           qspi_addr += size;
  172.           flash_addr += size;

  173.           /* Check if a new page writing is needed */
  174.           if (qspi_addr < max_size)
  175.           {
  176.             /* Update the remaining size if it is less than the page size */
  177.             if ((qspi_addr + size) > max_size)
  178.             {
  179.               size = (max_size - qspi_addr);
  180.             }
  181.             step = 2;
  182.           }
  183.           else
  184.           {
  185.             StatusMatch = 0;
  186.             RxCplt = 0;

  187.             /* Configure Volatile Configuration register (with new dummy cycles) */
  188.             QSPI_DummyCyclesCfg(&QSPIHandle);
  189.          

  190.             /* Reading Sequence ------------------------------------------------ */
  191.             sCommand.Instruction = QUAD_OUT_FAST_READ_CMD;
  192.             sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;

  193.             sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;

  194.             if (HAL_QSPI_MemoryMapped(&QSPIHandle, &sCommand, &sMemMappedCfg) != HAL_OK)
  195.             {
  196.               Error_Handler();
  197.             }

  198.             step++;
  199.           }
  200.         }
  201.         break;
  202.         
  203.       case 5:
  204.           /* Execute the code from QSPI memory ------------------------------- */
  205.           GpioToggle();
  206.         break;
  207.         
  208.       default :
  209.         Error_Handler();
  210.     }
  211.   }
  212. }

  213. /**
  214.   * @brief  Command completed callbacks.
  215.   * @param  hqspi: QSPI handle
  216.   * @retval None
  217.   */
  218. void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
  219. {
  220.   CmdCplt++;
  221. }

  222. /**
  223.   * @brief  Rx Transfer completed callbacks.
  224.   * @param  hqspi: QSPI handle
  225.   * @retval None
  226.   */
  227. void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
  228. {
  229.   RxCplt++;
  230. }

  231. /**
  232.   * @brief  Tx Transfer completed callbacks.
  233.   * @param  hqspi: QSPI handle
  234.   * @retval None
  235.   */
  236. void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
  237. {
  238.   TxCplt++;
  239. }

  240. /**
  241.   * @brief  Status Match callbacks
  242.   * @param  hqspi: QSPI handle
  243.   * @retval None
  244.   */
  245. void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi)
  246. {
  247.   StatusMatch++;
  248. }

  249. /**
  250.   * @brief  System Clock Configuration
  251.   *         The system Clock is configured as follow :
  252.   *            System Clock source            = PLL (HSE)
  253.   *            SYSCLK(Hz)                     = 400000000 (CPU Clock)
  254.   *            HCLK(Hz)                       = 200000000 (AXI and AHBs Clock)
  255.   *            AHB Prescaler                  = 2
  256.   *            D1 APB3 Prescaler              = 2 (APB3 Clock  100MHz)
  257.   *            D2 APB1 Prescaler              = 2 (APB1 Clock  100MHz)
  258.   *            D2 APB2 Prescaler              = 2 (APB2 Clock  100MHz)
  259.   *            D3 APB4 Prescaler              = 2 (APB4 Clock  100MHz)
  260.   *            HSE Frequency(Hz)              = 25000000
  261.   *            PLL_M                          = 5
  262.   *            PLL_N                          = 160
  263.   *            PLL_P                          = 2
  264.   *            PLL_Q                          = 4
  265.   *            PLL_R                          = 2
  266.   *            VDD(V)                         = 3.3
  267.   *            Flash Latency(WS)              = 4
  268.   * @param  None
  269.   * @retval None
  270.   */
  271. static void SystemClock_Config(void)
  272. {
  273.   RCC_ClkInitTypeDef RCC_ClkInitStruct;
  274.   RCC_OscInitTypeDef RCC_OscInitStruct;
  275.   HAL_StatusTypeDef ret = HAL_OK;
  276.   
  277.   /*!< Supply configuration update enable */
  278.   MODIFY_REG(PWR->CR3, PWR_CR3_SCUEN, 0);

  279.   /* The voltage scaling allows optimizing the power consumption when the device is
  280.      clocked below the maximum system frequency, to update the voltage scaling value
  281.      regarding system frequency refer to product datasheet.  */
  282.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  283.   while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
  284.   
  285.   /* Enable HSE Oscillator and activate PLL with HSE as source */
  286.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  287.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  288.   RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
  289.   RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
  290.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  291.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

  292.   RCC_OscInitStruct.PLL.PLLM = 5;
  293.   RCC_OscInitStruct.PLL.PLLN = 160;
  294.   RCC_OscInitStruct.PLL.PLLP = 2;
  295.   RCC_OscInitStruct.PLL.PLLR = 2;
  296.   RCC_OscInitStruct.PLL.PLLQ = 4;

  297.   RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  298.   RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
  299.   ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
  300.   if(ret != HAL_OK)
  301.   {
  302.     Error_Handler();
  303.   }
  304.   
  305. /* Select PLL as system clock source and configure  bus clocks dividers */
  306.   RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \
  307.                                  RCC_CLOCKTYPE_PCLK2  | RCC_CLOCKTYPE_D3PCLK1);

  308.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  309.   RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  310.   RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  311.   RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;  
  312.   RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  313.   RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  314.   RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
  315.   ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
  316.   if(ret != HAL_OK)
  317.   {
  318.     Error_Handler();
  319.   }
  320.   
  321.   /*activate CSI clock mondatory for I/O Compensation Cell*/
  322.   __HAL_RCC_CSI_ENABLE() ;
  323.    
  324.   /* Enable SYSCFG clock mondatory for I/O Compensation Cell */
  325.   __HAL_RCC_SYSCFG_CLK_ENABLE() ;
  326.   
  327.   /* Enables the I/O Compensation Cell */
  328.   HAL_EnableCompensationCell();
  329. }
  330. /**
  331.   * @brief  This function send a Write Enable and wait it is effective.
  332.   * @param  hqspi: QSPI handle
  333.   * @retval None
  334.   */
  335. static void QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
  336. {
  337.   QSPI_CommandTypeDef     sCommand;
  338.   QSPI_AutoPollingTypeDef sConfig;

  339.   /* Enable write operations ------------------------------------------ */
  340.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  341.   sCommand.Instruction       = WRITE_ENABLE_CMD;
  342.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  343.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  344.   sCommand.DataMode          = QSPI_DATA_NONE;
  345.   sCommand.DummyCycles       = 0;
  346.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  347.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  348.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;

  349.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  350.   {
  351.     Error_Handler();
  352.   }
  353.   
  354.   /* Configure automatic polling mode to wait for write enabling ---- */  
  355.   sConfig.Match           = 0x02;
  356.   sConfig.Mask            = 0x02;
  357.   sConfig.MatchMode       = QSPI_MATCH_MODE_AND;
  358.   sConfig.StatusBytesSize = 1;
  359.   sConfig.Interval        = 0x10;
  360.   sConfig.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;

  361.   sCommand.Instruction    = READ_STATUS_REG_CMD;
  362.   sCommand.DataMode       = QSPI_DATA_1_LINE;

  363.   if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  364.   {
  365.     Error_Handler();
  366.   }
  367. }

  368. /**
  369.   * @brief  This function read the SR of the memory and wait the EOP.
  370.   * @param  hqspi: QSPI handle
  371.   * @retval None
  372.   */
  373. static void QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi)
  374. {
  375.   QSPI_CommandTypeDef     sCommand;
  376.   QSPI_AutoPollingTypeDef sConfig;

  377.   /* Configure automatic polling mode to wait for memory ready ------ */  
  378.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  379.   sCommand.Instruction       = READ_STATUS_REG_CMD;
  380.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  381.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  382.   sCommand.DataMode          = QSPI_DATA_1_LINE;
  383.   sCommand.DummyCycles       = 0;
  384.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  385.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  386.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;

  387.   sConfig.Match           = 0x00;
  388.   sConfig.Mask            = 0x01;
  389.   sConfig.MatchMode       = QSPI_MATCH_MODE_AND;
  390.   sConfig.StatusBytesSize = 1;
  391.   sConfig.Interval        = 0x10;
  392.   sConfig.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;

  393.   if (HAL_QSPI_AutoPolling_IT(&QSPIHandle, &sCommand, &sConfig) != HAL_OK)
  394.   {
  395.     Error_Handler();
  396.   }
  397. }

  398. /**
  399.   * @brief  This function configure the dummy cycles on memory side.
  400.   * @param  hqspi: QSPI handle
  401.   * @retval None
  402.   */
  403. static void QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
  404. {
  405.   QSPI_CommandTypeDef sCommand;
  406.   uint8_t reg;

  407.   /* Read Volatile Configuration register --------------------------- */
  408.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  409.   sCommand.Instruction       = READ_VOL_CFG_REG_CMD;
  410.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  411.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  412.   sCommand.DataMode          = QSPI_DATA_1_LINE;
  413.   sCommand.DummyCycles       = 0;
  414.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  415.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  416.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  417.   sCommand.NbData            = 1;

  418.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  419.   {
  420.     Error_Handler();
  421.   }

  422.   if (HAL_QSPI_Receive(&QSPIHandle, &#174;, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  423.   {
  424.     Error_Handler();
  425.   }

  426.   /* Enable write operations ---------------------------------------- */
  427.   QSPI_WriteEnable(&QSPIHandle);

  428.   /* Write Volatile Configuration register (with new dummy cycles) -- */  
  429.   sCommand.Instruction = WRITE_VOL_CFG_REG_CMD;
  430.   MODIFY_REG(reg, 0xF0, (DUMMY_CLOCK_CYCLES_READ_QUAD << POSITION_VAL(0xF0)));
  431.       
  432.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  433.   {
  434.     Error_Handler();
  435.   }

  436.   if (HAL_QSPI_Transmit(&QSPIHandle, &#174;, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  437.   {
  438.     Error_Handler();
  439.   }
  440. }



  441. /**
  442.   * @brief  This function is executed in case of error occurrence.
  443.   * @param  None
  444.   * @retval None
  445.   */
  446. static void Error_Handler(void)
  447. {
  448.   BSP_LED_On(LED3);

  449.   /* User may add here some code to deal with this error */
  450.   while(1)
  451.   {
  452.   }
  453. }

  454. /**
  455.   * @brief  CPU L1-Cache enable.
  456.   * @param  None
  457.   * @retval None
  458.   */
  459. static void CPU_CACHE_Enable(void)
  460. {
  461.   /* Enable I-Cache */
  462.   SCB_EnableICache();

  463.   /* Enable D-Cache */
  464.   SCB_EnableDCache();
  465. }


  466. #ifdef  USE_FULL_ASSERT
  467. /**
  468.   * @brief  Reports the name of the source file and the source line number
  469.   *         where the assert_param error has occurred.
  470.   * @param  file: pointer to the source file name
  471.   * @param  line: assert_param error line source number
  472.   * @retval None
  473.   */
  474. void assert_failed(uint8_t *file, uint32_t line)
  475. {
  476.   /* User can add his own implementation to report the file name and line number,
  477.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  478.   /* Infinite loop */
  479.   while (1)
  480.   {
  481.   }
  482. }
  483. #endif

  484. /**
  485.   * @brief  Toggle the GPIOs
  486.   * @param  None
  487.   * @retval None
  488.   */
  489. #if defined(__CC_ARM)
  490. #pragma arm section code = ".qspi"
  491. #pragma no_inline
  492. static void GpioToggle(void)
  493. #elif defined(__ICCARM__)
  494. static void GpioToggle(void) @ ".qspi"
  495. #elif defined(__GNUC__)
  496. static void __attribute__((section(".qspi"), noinline)) GpioToggle(void)
  497. #endif
  498. {
  499.   BSP_LED_Toggle(LED1);
  500.   /* Insert delay 100 ms */
  501.   HAL_Delay(100);
  502.   BSP_LED_Toggle(LED2);
  503.   /* Insert delay 100 ms */
  504.   HAL_Delay(100);
  505.   BSP_LED_Toggle(LED3);
  506.   /* Insert delay 100 ms */
  507.   HAL_Delay(100);
  508.   BSP_LED_Toggle(LED4);
  509.   /* Insert delay 100 ms */
  510.   HAL_Delay(100);
  511. }
  512. #if defined(__CC_ARM)
  513. #pragma arm section code
  514. #endif
复制代码





回复

使用道具 举报

5

主题

54

回帖

69

积分

初级会员

积分
69
发表于 2023-1-18 10:43:15 | 显示全部楼层
我APP程序是分两部分,一部分在内部flash,一部分在qspi flash (w25q256中),bootloader中需要更新这两部分程序,bootloader中需要退出内存映射模式吗?
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-19 02:07 , Processed in 0.157679 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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