这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【STM32H7S78-DK评测】XIP运行流程分析

共5条 1/1 1 跳转至

【STM32H7S78-DK评测】XIP运行流程分析

工程师
2024-09-03 23:15:08   被打赏 50 分(兑奖)     打赏

简介:

感谢社区提供的评测机会,本次评测的板卡为 STM32H7S78-DK先来张上电运行图片。

image.png


image.png

image.png

该板卡有着丰富的外设资源,主要特性如下:

-这款开发板基于 Arm® Cortex®-M7 的 STM32H7S7L8H6H 微控制器,采用 TFBGA225 封装,具有 64KB 闪存和 620KB SRAM。

- 带电容式触摸屏的 5 英寸 LCD 模块

- 带 USB 2.0 HS 接口的 USB Type-C®

- USB Type-C®,带 USB 2.0 FS 接口

- 以太网符合 IEEE-802.3-2002 标准

- I2S 音频编

- 一个 ST-MEMS 数字麦克风

- 1-Gbit Octo-SPI NOR FLASH

- 256-Mbit Hexadeca-SPI PSRAM

- 附带 Wi-Fi® 模块(符合 802.11 b/g/n 标准)

- 四个用户 LED 指示灯

- 用户和复位按钮

- 两个 USB Type-C

- 以太网 RJ45

- 摄像头接口: FPC 连接器

- microSD™ 卡

- 立体声耳机插孔,包括模拟麦克风输入

- 音频 MEMS 子板扩展连接器

- ARDUINO® Uno V3 扩展连接器

- STMod+ 扩展连接器

- Pmod™ 扩展连接器

芯片的主要外设资源说明如下:

image.png

芯片内部只有64KB 的flash 资源,该芯片可以用来开发大型的MCU 程序,显然如果程序都放在片内flash 运行是放不下的,板卡上通过XSPI 模块分别挂载了1-Gbit Octo-SPI NOR FLASH(128MB 的nor flash), 256-Mbit Hexadeca-SPI PSRAM (32MB)的RAM资源,这下才是运行大型嵌入式程序及GUI 该有的资源配置, 芯片是支持XIP模式运行在nor flash 上的,本次的主题就是检讨如何将程序存储在NOR FLASH 上运行。


XIP 配置

对于XIP的 运行方式,ST 的HAL 软件包 STM32Cube_FW_H7RS_V1.1.0\Projects\STM32H7S78-DK\Templates\Template_XIP 路径下提供了IAR/MDK/CUBEIDE 的工程模板来方便我们直接XIP方式运行程序,在开始探讨XIP运行方式前我们先看下XIP 像款的user flash/xspi1/xspi2 这三段外设的地址映射空间。

user flash 映射到芯片的-0x08000000~0x0800ffff

xspi1(RAM)映射到芯片 -0x90000000~0x9fffffff

xspi2(NOR flash)映射到芯片-0x70000000~0x7fffffff

image.png

STM32Cube_FW_H7RS_V1.1.0\Projects\STM32H7S78-DK\Templates\Template_XIP 模板路径下可以看到一个boot工程和Appli工程,boot 工程会编译出一个运行在user flash的镜像该镜像会完成完成XSPI1 和 XSPI2 的初始化将app 工程使用的RAM及ROM映射到上述的地址空间,然后跳转到appi 运行,本次试用IAR环境运行XIP工程,我们查看boot 工程代码来验证上述的XIP运行方式。

以下是boot 工程对应的IAR 化境的linkfile(stm32h7s7xx_flash.icf)

image.png

从上述link 文件的layout 可知boot 程序运行于user flash,堆栈空间存放在Dtcm。

从boot 工程的如下代码可以看出boot 工程会配置对应的pin 脚为xspi 功能,并对其进行初始化。

/**
* @brief XSPI MSP Initialization
* This function configures the hardware resources used in this example
* @param hxspi: XSPI handle pointer
* @retval None
*/
void HAL_XSPI_MspInit(XSPI_HandleTypeDef* hxspi)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(hxspi->Instance==XSPI1)
  {
  /* USER CODE BEGIN XSPI1_MspInit 0 */

  /* USER CODE END XSPI1_MspInit 0 */

  /** Initializes the peripherals clock
  */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_XSPI1;
    PeriphClkInit.Xspi1ClockSelection = RCC_XSPI1CLKSOURCE_PLL2S;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }

    /* Peripheral clock enable */
    HAL_RCC_XSPIM_CLK_ENABLED++;
    if(HAL_RCC_XSPIM_CLK_ENABLED==1){
      __HAL_RCC_XSPIM_CLK_ENABLE();
    }
    __HAL_RCC_XSPI1_CLK_ENABLE();

    __HAL_RCC_GPIOO_CLK_ENABLE();
    __HAL_RCC_GPIOP_CLK_ENABLE();
    /**XSPI1 GPIO Configuration
    PO3     ------> XSPIM_P1_DQS1
    PP10     ------> XSPIM_P1_IO10
    PP12     ------> XSPIM_P1_IO12
    PP14     ------> XSPIM_P1_IO14
    PP2     ------> XSPIM_P1_IO2
    PP5     ------> XSPIM_P1_IO5
    PO2     ------> XSPIM_P1_DQS0
    PP1     ------> XSPIM_P1_IO1
    PP11     ------> XSPIM_P1_IO11
    PP15     ------> XSPIM_P1_IO15
    PP3     ------> XSPIM_P1_IO3
    PP0     ------> XSPIM_P1_IO0
    PP7     ------> XSPIM_P1_IO7
    PP8     ------> XSPIM_P1_IO8
    PP13     ------> XSPIM_P1_IO13
    PP4     ------> XSPIM_P1_IO4
    PO4     ------> XSPIM_P1_CLK
    PP6     ------> XSPIM_P1_IO6
    PO0     ------> XSPIM_P1_NCS1
    PP9     ------> XSPIM_P1_IO9
    */
    GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_XSPIM_P1;
    HAL_GPIO_Init(GPIOO, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_2
                          |GPIO_PIN_5|GPIO_PIN_1|GPIO_PIN_11|GPIO_PIN_15
                          |GPIO_PIN_3|GPIO_PIN_0|GPIO_PIN_7|GPIO_PIN_8
                          |GPIO_PIN_13|GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_XSPIM_P1;
    HAL_GPIO_Init(GPIOP, &GPIO_InitStruct);

  /* USER CODE BEGIN XSPI1_MspInit 1 */

  /* USER CODE END XSPI1_MspInit 1 */
  }
  else if(hxspi->Instance==XSPI2)
  {
  /* USER CODE BEGIN XSPI2_MspInit 0 */

  /* USER CODE END XSPI2_MspInit 0 */

  /** Initializes the peripherals clock
  */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_XSPI2;
    PeriphClkInit.Xspi2ClockSelection = RCC_XSPI2CLKSOURCE_PLL2S;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }

    /* Peripheral clock enable */
    HAL_RCC_XSPIM_CLK_ENABLED++;
    if(HAL_RCC_XSPIM_CLK_ENABLED==1){
      __HAL_RCC_XSPIM_CLK_ENABLE();
    }
    __HAL_RCC_XSPI2_CLK_ENABLE();

    __HAL_RCC_GPION_CLK_ENABLE();
    /**XSPI2 GPIO Configuration
    PN1     ------> XSPIM_P2_NCS1
    PN3     ------> XSPIM_P2_IO1
    PN0     ------> XSPIM_P2_DQS0
    PN11     ------> XSPIM_P2_IO7
    PN10     ------> XSPIM_P2_IO6
    PN9     ------> XSPIM_P2_IO5
    PN2     ------> XSPIM_P2_IO0
    PN6     ------> XSPIM_P2_CLK
    PN8     ------> XSPIM_P2_IO4
    PN4     ------> XSPIM_P2_IO2
    PN5     ------> XSPIM_P2_IO3
    */
    GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_0|GPIO_PIN_11
                          |GPIO_PIN_10|GPIO_PIN_9|GPIO_PIN_2|GPIO_PIN_6
                          |GPIO_PIN_8|GPIO_PIN_4|GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_XSPIM_P2;
    HAL_GPIO_Init(GPION, &GPIO_InitStruct);

  /* USER CODE BEGIN XSPI2_MspInit 1 */

  /* USER CODE END XSPI2_MspInit 1 */
  }

}

/**
* @brief XSPI MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hxspi: XSPI handle pointer
* @retval None
*/
void HAL_XSPI_MspDeInit(XSPI_HandleTypeDef* hxspi)
{
  if(hxspi->Instance==XSPI1)
  {
  /* USER CODE BEGIN XSPI1_MspDeInit 0 */

  /* USER CODE END XSPI1_MspDeInit 0 */
    /* Peripheral clock disable */
    HAL_RCC_XSPIM_CLK_ENABLED--;
    if(HAL_RCC_XSPIM_CLK_ENABLED==0){
      __HAL_RCC_XSPIM_CLK_DISABLE();
    }
    __HAL_RCC_XSPI1_CLK_DISABLE();

    /**XSPI1 GPIO Configuration
    PO3     ------> XSPIM_P1_DQS1
    PP10     ------> XSPIM_P1_IO10
    PP12     ------> XSPIM_P1_IO12
    PP14     ------> XSPIM_P1_IO14
    PP2     ------> XSPIM_P1_IO2
    PP5     ------> XSPIM_P1_IO5
    PO2     ------> XSPIM_P1_DQS0
    PP1     ------> XSPIM_P1_IO1
    PP11     ------> XSPIM_P1_IO11
    PP15     ------> XSPIM_P1_IO15
    PP3     ------> XSPIM_P1_IO3
    PP0     ------> XSPIM_P1_IO0
    PP7     ------> XSPIM_P1_IO7
    PP8     ------> XSPIM_P1_IO8
    PP13     ------> XSPIM_P1_IO13
    PP4     ------> XSPIM_P1_IO4
    PO4     ------> XSPIM_P1_CLK
    PP6     ------> XSPIM_P1_IO6
    PO0     ------> XSPIM_P1_NCS1
    PP9     ------> XSPIM_P1_IO9
    */
    HAL_GPIO_DeInit(GPIOO, GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_0);

    HAL_GPIO_DeInit(GPIOP, GPIO_PIN_10|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_2
                          |GPIO_PIN_5|GPIO_PIN_1|GPIO_PIN_11|GPIO_PIN_15
                          |GPIO_PIN_3|GPIO_PIN_0|GPIO_PIN_7|GPIO_PIN_8
                          |GPIO_PIN_13|GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9);

  /* USER CODE BEGIN XSPI1_MspDeInit 1 */

  /* USER CODE END XSPI1_MspDeInit 1 */
  }
  else if(hxspi->Instance==XSPI2)
  {
  /* USER CODE BEGIN XSPI2_MspDeInit 0 */

  /* USER CODE END XSPI2_MspDeInit 0 */
    /* Peripheral clock disable */
    HAL_RCC_XSPIM_CLK_ENABLED--;
    if(HAL_RCC_XSPIM_CLK_ENABLED==0){
      __HAL_RCC_XSPIM_CLK_DISABLE();
    }
    __HAL_RCC_XSPI2_CLK_DISABLE();

    /**XSPI2 GPIO Configuration
    PN1     ------> XSPIM_P2_NCS1
    PN3     ------> XSPIM_P2_IO1
    PN0     ------> XSPIM_P2_DQS0
    PN11     ------> XSPIM_P2_IO7
    PN10     ------> XSPIM_P2_IO6
    PN9     ------> XSPIM_P2_IO5
    PN2     ------> XSPIM_P2_IO0
    PN6     ------> XSPIM_P2_CLK
    PN8     ------> XSPIM_P2_IO4
    PN4     ------> XSPIM_P2_IO2
    PN5     ------> XSPIM_P2_IO3
    */
    HAL_GPIO_DeInit(GPION, GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_0|GPIO_PIN_11
                          |GPIO_PIN_10|GPIO_PIN_9|GPIO_PIN_2|GPIO_PIN_6
                          |GPIO_PIN_8|GPIO_PIN_4|GPIO_PIN_5);

  /* USER CODE BEGIN XSPI2_MspDeInit 1 */

  /* USER CODE END XSPI2_MspDeInit 1 */
  }

}

以下代码段会对xspi 进行初始化配置。

/**
  * @brief XSPI1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_XSPI1_Init(void)
{

  /* USER CODE BEGIN XSPI1_Init 0 */

  /* USER CODE END XSPI1_Init 0 */

  XSPIM_CfgTypeDef sXspiManagerCfg = {0};

  /* USER CODE BEGIN XSPI1_Init 1 */

  /* USER CODE END XSPI1_Init 1 */
  /* XSPI1 parameter configuration*/
  hxspi1.Instance = XSPI1;
  hxspi1.Init.FifoThresholdByte = 2;
  hxspi1.Init.MemoryMode = HAL_XSPI_SINGLE_MEM;
  hxspi1.Init.MemoryType = HAL_XSPI_MEMTYPE_APMEM_16BITS;
  hxspi1.Init.MemorySize = HAL_XSPI_SIZE_32GB;
  hxspi1.Init.ChipSelectHighTimeCycle = 1;
  hxspi1.Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE;
  hxspi1.Init.ClockMode = HAL_XSPI_CLOCK_MODE_0;
  hxspi1.Init.WrapSize = HAL_XSPI_WRAP_NOT_SUPPORTED;
  hxspi1.Init.ClockPrescaler = 0;
  hxspi1.Init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE;
  hxspi1.Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_ENABLE;
  hxspi1.Init.ChipSelectBoundary = HAL_XSPI_BONDARYOF_8KB;
  hxspi1.Init.MaxTran = 0;
  hxspi1.Init.Refresh = 0;
  hxspi1.Init.MemorySelect = HAL_XSPI_CSSEL_NCS1;
  if (HAL_XSPI_Init(&hxspi1) != HAL_OK)
  {
    Error_Handler();
  }
  sXspiManagerCfg.nCSOverride = HAL_XSPI_CSSEL_OVR_NCS1;
  sXspiManagerCfg.IOPort = HAL_XSPIM_IOPORT_1;
  if (HAL_XSPIM_Config(&hxspi1, &sXspiManagerCfg, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN XSPI1_Init 2 */

  /* USER CODE END XSPI1_Init 2 */

}

/**
  * @brief XSPI2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_XSPI2_Init(void)
{

  /* USER CODE BEGIN XSPI2_Init 0 */

  /* USER CODE END XSPI2_Init 0 */

  XSPIM_CfgTypeDef sXspiManagerCfg = {0};

  /* USER CODE BEGIN XSPI2_Init 1 */

  /* USER CODE END XSPI2_Init 1 */
  /* XSPI2 parameter configuration*/
  hxspi2.Instance = XSPI2;
  hxspi2.Init.FifoThresholdByte = 4;
  hxspi2.Init.MemoryMode = HAL_XSPI_SINGLE_MEM;
  hxspi2.Init.MemoryType = HAL_XSPI_MEMTYPE_MACRONIX;
  hxspi2.Init.MemorySize = HAL_XSPI_SIZE_32GB;
  hxspi2.Init.ChipSelectHighTimeCycle = 2;
  hxspi2.Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE;
  hxspi2.Init.ClockMode = HAL_XSPI_CLOCK_MODE_0;
  hxspi2.Init.WrapSize = HAL_XSPI_WRAP_NOT_SUPPORTED;
  hxspi2.Init.ClockPrescaler = 0;
  hxspi2.Init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE;
  hxspi2.Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_ENABLE;
  hxspi2.Init.ChipSelectBoundary = HAL_XSPI_BONDARYOF_NONE;
  hxspi2.Init.MaxTran = 0;
  hxspi2.Init.Refresh = 0;
  hxspi2.Init.MemorySelect = HAL_XSPI_CSSEL_NCS1;
  if (HAL_XSPI_Init(&hxspi2) != HAL_OK)
  {
    Error_Handler();
  }
  sXspiManagerCfg.nCSOverride = HAL_XSPI_CSSEL_OVR_NCS1;
  sXspiManagerCfg.IOPort = HAL_XSPIM_IOPORT_2;
  if (HAL_XSPIM_Config(&hxspi2, &sXspiManagerCfg, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN XSPI2_Init 2 */

  /* USER CODE END XSPI2_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPION_CLK_ENABLE();
  __HAL_RCC_GPIOO_CLK_ENABLE();
  __HAL_RCC_GPIOP_CLK_ENABLE();

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

对xspi初始化完成后,调用该接口跳转到app 程序运行,跳转前配置跳转后的运行环境,然后跳转到XIP地址运行。

/**
  *  @addtogroup BOOT_XIP_Exported_Functions Boot XIP exported functions
  * @{
  */

BOOTStatus_TypeDef BOOT_Application(void)
{
  BOOTStatus_TypeDef retr;

  /* mount the memory */
  retr = MapMemory();
  if (BOOT_OK == retr)
  {
    /* jump on the application */
    retr = JumpToApplication();
  }
  return retr;
}

BOOTStatus_TypeDef JumpToApplication(void)
{
  uint32_t primask_bit;
  typedef  void (*pFunction)(void);
  pFunction JumpToApp;
  uint32_t Application_vector;

  if (EXTMEM_OK != EXTMEM_GetMapAddress(EXTMEM_MEMORY_BOOTXIP, &Application_vector))
  {
      return BOOT_ERROR_INCOMPATIBLEMEMORY;
  }

  /* Suspend SysTick */
  HAL_SuspendTick();

  /* Disable I-Cache---------------------------------------------------------*/
  SCB_DisableICache();

  /* Disable D-Cache---------------------------------------------------------*/
  SCB_DisableDCache();

  /* Initialize user application's Stack Pointer & Jump to user application  */
  primask_bit = __get_PRIMASK();
  __disable_irq();

  /* Apply offsets for image location and vector table offset */
  Application_vector += EXTMEM_XIP_IMAGE_OFFSET + EXTMEM_HEADER_OFFSET;

  SCB->VTOR = (uint32_t)Application_vector;
  JumpToApp = (pFunction) (*(__IO uint32_t *)(Application_vector + 4u));

#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
     (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
     (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1))    )
  /* on ARM v8m, set MSPLIM before setting MSP to avoid unwanted stack overflow faults */
  __set_MSPLIM(0x00000000);
#endif  /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */

  __set_MSP(*(__IO uint32_t*) Application_vector);

  /* Re-enable the interrupts */
  __set_PRIMASK(primask_bit);

  JumpToApp();
  return BOOT_OK;
}

app 程序使用的linkfile 的链接地址为xspi1和xspi2 对应的空间,程序需要加载在nor flash上运行。

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__     = 0x70000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x70000000;
define symbol __ICFEDIT_region_ROM_end__   = 0x77FFFFFF;
define symbol NONCACHEABLEBUFFER_size      = 0x400;
define symbol __ICFEDIT_region_RAM_start__ = 0x24000000;
define symbol __ICFEDIT_region_RAM_end__   = 0x24071FFF - NONCACHEABLEBUFFER_size;
define symbol NONCACHEABLEBUFFER_start  = __ICFEDIT_region_RAM_end__ + 1;
define symbol NONCACHEABLEBUFFER_end    = __ICFEDIT_region_RAM_end__ + NONCACHEABLEBUFFER_size;

/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__   = 0x200;
/**** End of ICF editor section. ###ICF###*/

define symbol __region_ITCM_start__ = 0x00000000;
define symbol __region_ITCM_end__   = 0x0000FFFF;
define symbol __region_DTCM_start__ = 0x20000000;
define symbol __region_DTCM_end__   = 0x2000FFFF;
define symbol __region_SRAMAHB_start__ = 0x30000000;
define symbol __region_SRAMAHB_end__   = 0x30007FFF;
define symbol __region_BKPSRAM_start__ = 0x38800000;
define symbol __region_BKPSRAM_end__   = 0x38800FFF;
define symbol __region_EXTRAM_start__ = 0x90000000;
define symbol __region_EXTRAM_end__   = 0x91FFFFFF;

export symbol NONCACHEABLEBUFFER_start;
export symbol NONCACHEABLEBUFFER_size;

export symbol __ICFEDIT_region_ROM_start__;
export symbol __ICFEDIT_region_ROM_end__;

export symbol __region_EXTRAM_start__;
export symbol __region_EXTRAM_end__;

define memory mem with size = 4G;
define region ROM_region      = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region      = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define region EXTRAM_region   = mem:[from __region_EXTRAM_start__ to __region_EXTRAM_end__];
define region NONCACHEABLE_region   = mem:[from NONCACHEABLEBUFFER_start to NONCACHEABLEBUFFER_end];
define region ITCM_region     = mem:[from __region_ITCM_start__ to __region_ITCM_end__];
define region DTCM_region     = mem:[from __region_DTCM_start__ to __region_DTCM_end__];
define region SRAMAHB_region  = mem:[from __region_SRAMAHB_start__ to __region_SRAMAHB_end__];
define region BKPSRAM_region  = mem:[from __region_BKPSRAM_start__ to __region_BKPSRAM_end__];

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };
do not initialize  { section .noinit, section noncacheable_buffer };


place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in ROM_region    { readonly };
place in RAM_region    { readwrite };
place in NONCACHEABLE_region { section noncacheable_buffer };
place in DTCM_region   { block CSTACK, block HEAP };

IAR app 工程在debug时会同时将boot 工程的image 下载到user flash ,从而在上电时先运行user flash 的boot程序准备xip运行环境然后跳转到xip 运行。

image.png

IAR debug 运行appI 程序发现程序运行的地址为0x70000000 的地址空间,外挂的RAM 也可以正常访问。

image.png


从debug log 窗口也可以看出,IAR 在现在app 程序后会把boot 程序下载到user flash

image.png

后续在XIP工程基础上继续验证其他功能。








关键词: STM32H7S78     XIP运行流程    

专家
2024-09-04 11:11:45     打赏
2楼

动作真快,板子收到就开始研究啊


专家
2024-09-04 21:02:09     打赏
3楼

感谢分享


专家
2024-09-07 10:21:58     打赏
4楼

这个开发板提供的测试资源很丰富哈,流口水了。


专家
2024-09-07 12:42:08     打赏
5楼

感谢分享


共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]