STM32H750使用QSPI-Flash实现片上程序执行出错【已解决】

2020-01-04 19:03发布

本帖最后由 wzd5230 于 2019-1-28 13:23 编辑

        项目中使用的MCU是STM32H750,core最高频率400MHz,内部flash只有128KB,是无法满足目前我们的应用的,遂考虑外部扩展存储,并且片上执行(因为内部RAM也只有1MB),扩展的方案有2个,其一,通过QSPI外扩串行Flash,该MCU支持QSPI外接存储设备的XIP功能;其二,通过FSMC接口,外接并行的norFlash,这种方式耗费MCU的引脚比较多。因此采用QSPI外接Flash的方式。
        目前在测试阶段,在MCU内部Flash中,包含了一个类似于Boot的程序,该程序初始化QSPI工作在内存映射模式,以及进行程序跳转。MCU的QSPI最高频率支持200MHz。外部Flash最高clock支持133MHz,已经包含了一个有效、可用的程序,该程序对某一IO口进行翻转。
        【遇到的问题】:
        1、QSPI的clock如果设置的比较高(>=50MHz),MCU就会进入hardfault_handler(),这可以理解,因为从Flash中读取的数据就是“指令”,指令不正确,肯定会出问题。如果QSPI的clock设置的比较低,如33MHz,那么是可以正常跳转,并且外部flash中的程序也执行了,IO正常翻转。
        2、【测试1】,仅配置QSPI工作在内存映射模式,并不进行跳转,这样可以直接使用指针去读取数据,并且可以在IAR的memory窗口直接看到flash所映射地址的数据。测试结果是QSPI低速时通过JLink可以查看到数据,使用指针也可以正常访问到数据。如果QSPI设置clock高了,直接MCU进入异常状态。
        3、【测试2】,将上述的【测试1】在一个STM32H743的评估板上验证(该板卡没有外接flash),即使QSPI的频率设置到100MHz,MCU也没有死,由于外部没有数据,映射的数据全为0xFF(我将SIO0..3直接接到VCC)。
        4、不使用QSPI的内存映射模式,而是使用最简单的间接模式,对Flash中的数据进行读取,测试发现,当QSPI的clock速度提高了,mcu也还是死机。
        5、还有很多其他的对比测试,我就不具体列出了。
        【咨询的问题】
        1、是否有使用过STMH750这一系列MCU的童鞋,我怀疑这个芯片的QSPI速度有限制,和STM32H743是不同的,当QSPI速度提升了,整个MCU进入异常。
        2、是否有哪位使用STMH750这个MCU,外部通过QSPI扩展Flash实现片上执行程序(其实是取指令)。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
22条回答
wzd5230
2020-01-06 02:39
clesun 发表于 2019-1-28 15:27
能否贴出来差异,我们也学习下,平常得模板都是cubemx出得,这下就吓人了。 ...


区别在于这个函数HAL_QSPI_MspInit

CubeMX原始生成:
  1.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  2.   if(hqspi->Instance==QUADSPI)
  3.   {
  4.   /* USER CODE BEGIN QUADSPI_MspInit 0 */

  5.   /* USER CODE END QUADSPI_MspInit 0 */
  6.     /* Peripheral clock enable */
  7.     __HAL_RCC_QSPI_CLK_ENABLE();
  8.   
  9.     __HAL_RCC_GPIOB_CLK_ENABLE();
  10.     __HAL_RCC_GPIOE_CLK_ENABLE();
  11.     __HAL_RCC_GPIOC_CLK_ENABLE();
  12.     /**QUADSPI GPIO Configuration   
  13.     PB2     ------> QUADSPI_CLK
  14.     PE7     ------> QUADSPI_BK2_IO0
  15.     PE8     ------> QUADSPI_BK2_IO1
  16.     PE9     ------> QUADSPI_BK2_IO2
  17.     PE10     ------> QUADSPI_BK2_IO3
  18.     PC11     ------> QUADSPI_BK2_NCS
  19.     */
  20.     GPIO_InitStruct.Pin = GPIO_PIN_2;
  21.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  22.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  23.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  24.     GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
  25.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  26.     GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
  27.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  28.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  29.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  30.     GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
  31.     HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  32.     GPIO_InitStruct.Pin = GPIO_PIN_11;
  33.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  34.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  35.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  36.     GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
  37.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  38.   /* USER CODE BEGIN QUADSPI_MspInit 1 */

  39.   /* USER CODE END QUADSPI_MspInit 1 */
  40.   }
复制代码

修改后的:
  1.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  2.   if(hqspi->Instance==QUADSPI)
  3.   {
  4.     /*##-1- Enable peripherals and GPIO Clocks #################################*/
  5.     /* Enable the QuadSPI memory interface clock */
  6.     __HAL_RCC_QSPI_CLK_ENABLE();
  7.     /* Reset the QuadSPI memory interface */
  8.     __HAL_RCC_QSPI_FORCE_RESET();
  9.     __HAL_RCC_QSPI_RELEASE_RESET();   
  10.     /* Enable GPIO clocks */
  11.     __HAL_RCC_QSPI_CLK_ENABLE();
  12.     __HAL_RCC_GPIOB_CLK_ENABLE();
  13.     __HAL_RCC_GPIOC_CLK_ENABLE();
  14.     __HAL_RCC_GPIOE_CLK_ENABLE();
  15.     __HAL_RCC_GPIOF_CLK_ENABLE();
  16.     /* Enable DMA clock */
  17.     __HAL_RCC_MDMA_CLK_ENABLE();  
  18.    
  19.     /*##-2- Configure peripheral GPIO ##########################################*/
  20.     /**QUADSPI GPIO Configuration   
  21.     PB2     ------> QUADSPI_CLK
  22.     PE7     ------> QUADSPI_BK2_IO0
  23.     PE8     ------> QUADSPI_BK2_IO1
  24.     PE9     ------> QUADSPI_BK2_IO2
  25.     PE10     ------> QUADSPI_BK2_IO3
  26.     PC11     ------> QUADSPI_BK2_NCS
  27.     */
  28.     GPIO_InitStruct.Pin = GPIO_PIN_2;
  29.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  30.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  31.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  32.     GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
  33.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  34.     GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
  35.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  36.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  37.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  38.     GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
  39.     HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  40.     GPIO_InitStruct.Pin = GPIO_PIN_11;
  41.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  42.     GPIO_InitStruct.Pull = GPIO_PULLUP;
  43.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  44.     GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
  45.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  46.   /* USER CODE BEGIN QUADSPI_MspInit 1 */

  47.   /* USER CODE END QUADSPI_MspInit 1 */
  48.   }
复制代码

一周热门 更多>