STM32H7 RAM的使用

STM32H743 具有多种不同类型的 RAM,如 ITCM、DTCM、AXI SRAM、SRAM1、SRAM2 等,每种 RAM 都有其特点和适用场景。下面将详细介绍如何充分利用这些 RAM。

各类 RAM 的特点

  • ITCM(Instruction Tightly - Coupled Memory)
    • 与 CPU 紧密耦合,专门用于存储指令,具有零等待状态,访问速度极快,可显著提高代码执行效率。
    • 容量通常较小,STM32H743 中 ITCM 大小为 128KB。
  • DTCM(Data Tightly - Coupled Memory)
    • 同样与 CPU 紧密耦合,用于存储数据,访问速度快,零等待状态。
    • 容量一般为 128KB,适合存储需要快速访问的数据,如关键变量、数组等。
  • AXI SRAM
    • 通过 AXI 总线连接到系统,访问速度较快,容量较大(STM32H743 中为 512KB)。
    • 可被多个总线主设备(如 CPU、DMA 等)同时访问,适用于数据共享和高速数据传输。
  • SRAM1 和 SRAM2
    • 通用静态随机存取存储器,容量分别为 128KB 和 128KB。
    • 访问速度相对 AXI SRAM 稍慢,但足以满足大多数应用场景,可用于存储一般性的数据和代码。

使用方法

1. 代码和数据的合理分配

  • 将关键代码存放在 ITCM
    • 在 Keil 中,可以通过修改链接脚本(.sct 文件)来指定代码段存储在 ITCM 中。例如:

收起

plaintext

; ITCM 区域定义
LR_IROM1 0x00200000 0x00020000  {    ; load region size_region
  ER_IROM1 0x00200000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00020000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

  • 在 GCC 中,可以通过修改链接脚本(.ld 文件)实现:

收起

plaintext

MEMORY
{
  ITCM_RAM (xrw) : ORIGIN = 0x00200000, LENGTH = 128K
  DTCM_RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
  AXI_SRAM (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
  SRAM1 (xrw)    : ORIGIN = 0x30000000, LENGTH = 128K
  SRAM2 (xrw)    : ORIGIN = 0x30020000, LENGTH = 128K
}

SECTIONS
{
  .text :
  {
    *(.text)
  } > ITCM_RAM
}

  • 将关键数据存放在 DTCM
    • 在 C 语言中,可以使用 __attribute__ 关键字指定变量存储在 DTCM 中:

收起

c

#define DTCM_RAM __attribute__((section(".dtcm_data")))

DTCM_RAM uint32_t critical_data[100];

  • 同时需要在链接脚本中为 .dtcm_data 段分配 DTCM 空间。
2. 利用 AXI SRAM 进行数据共享

  • AXI SRAM 可被多个总线主设备同时访问,适合用于 DMA 数据传输和多任务间的数据共享。例如,在使用 DMA 进行数据传输时,可以将 DMA 目标地址设置为 AXI SRAM:

收起

c

// 初始化 DMA 传输到 AXI SRAM
DMA_InitTypeDef DMA_InitStruct = {0};
DMA_InitStruct.Direction = DMA_PERIPH_TO_MEMORY;
DMA_InitStruct.PeriphInc = DMA_PINC_DISABLE;
DMA_InitStruct.MemInc = DMA_MINC_ENABLE;
DMA_InitStruct.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
DMA_InitStruct.MemDataAlignment = DMA_MDATAALIGN_BYTE;
DMA_InitStruct.Mode = DMA_NORMAL;
DMA_InitStruct.Priority = DMA_PRIORITY_LOW;
DMA_InitStruct.MemAddress = (uint32_t)0x24000000; // AXI SRAM 起始地址
3. SRAM1 和 SRAM2 的使用

  • SRAM1 和 SRAM2 可用于存储一般性的数据和代码。可以在链接脚本中为它们分配相应的段,然后将不需要快速访问的数据和代码存放在这些区域。例如:

收起

plaintext

// GCC 链接脚本中为 SRAM1 分配段
SECTIONS
{
  .sram1_data :
  {
    *(.sram1_data)
  } > SRAM1
}

c

// 将变量存放在 SRAM1
#define SRAM1_DATA __attribute__((section(".sram1_data")))

SRAM1_DATA uint8_t general_data[200];

注意事项

  • 地址冲突:在使用不同的 RAM 时,要确保各区域的地址不会发生冲突,避免数据混乱。
  • 数据一致性:当多个总线主设备同时访问 RAM 时,要注意数据一致性问题,避免出现数据读写错误。可以使用同步机制(如互斥锁)来保证数据的正确性。
  • 容量管理:合理规划各 RAM 的使用,避免某个 RAM 区域容量不足,影响系统性能。

在 IAR 中使用 STM32H743 的各类 RAM(如 ITCM、DTCM、AXI SRAM、SRAM1、SRAM2 等),可以通过以下步骤和方法来实现合理分配与使用。

1. 配置内存区域

在 IAR 中,需要在链接器配置文件(通常为 .icf 文件)里对不同的内存区域进行定义和分配。以下是一个示例 .icf 文件的部分内容,展示如何定义 STM32H743 的各类 RAM 区域:

收起

plaintext

// 定义内存区域
define region ITCM_region   = mem:[from 0x00200000 size 128K];
define region DTCM_region   = mem:[from 0x20000000 size 128K];
define region AXI_SRAM_region = mem:[from 0x24000000 size 512K];
define region SRAM1_region  = mem:[from 0x30000000 size 128K];
define region SRAM2_region  = mem:[from 0x30020000 size 128K];

// 定义段并分配到相应的内存区域
define symbol __ICFEDIT_intvec_start__ = 0x00200000;
define symbol __ICFEDIT_size_cstack__ = 0x400;

// 代码段分配到 ITCM
place at start of ITCM_region { readonly section .intvec, readonly section .text };

// 数据段分配到 DTCM
place in DTCM_region { section .data, section .bss };

// 其他区域可根据需求分配,例如将一些大数组放到 AXI SRAM
define block LARGE_ARRAY_BLOCK with alignment = 4 {
    readonly variable large_array[1024];
};
place in AXI_SRAM_region { block LARGE_ARRAY_BLOCK };

2. 将代码存放在 ITCM

若要将特定的代码存放在 ITCM 中,可以使用 IAR 的 @ 语法或者 __no_init 等关键字。以下是示例代码:

收起

c

// 使用 @ 语法将函数存放在 ITCM
#pragma location = 0x00200000
void critical_function(void) {
    // 关键代码
}

3. 将数据存放在 DTCM

可以使用 __no_init 和 __attribute__ 等方式将数据存放在 DTCM 中。示例如下:

收起

c

// 使用 __no_init 和 section 属性将变量存放在 DTCM
__no_init uint32_t critical_data[100] @ 0x20000000;

4. 利用 AXI SRAM 进行数据共享

对于需要多设备访问或者进行 DMA 传输的数据,可以将其存放在 AXI SRAM 中。在代码中可以通过指定地址来访问 AXI SRAM 中的数据。

收起

c

// 定义指向 AXI SRAM 的指针
volatile uint32_t *axi_sram_ptr = (volatile uint32_t *)0x24000000;

// 向 AXI SRAM 写入数据
axi_sram_ptr[0] = 0x12345678;

// 从 AXI SRAM 读取数据
uint32_t read_data = axi_sram_ptr[0];

5. 使用 SRAM1 和 SRAM2

同样可以通过指定地址的方式来使用 SRAM1 和 SRAM2。以下是访问 SRAM1 的示例:

收起

c

// 定义指向 SRAM1 的指针
volatile uint8_t *sram1_ptr = (volatile uint8_t *)0x30000000;

// 向 SRAM1 写入数据
sram1_ptr[0] = 0xAA;

// 从 SRAM1 读取数据
uint8_t read_byte = sram1_ptr[0];

注意事项

  • 内存保护:在使用不同的 RAM 区域时,要注意避免越界访问,防止破坏其他区域的数据。
  • 初始化问题:对于存放在特定 RAM 区域的数据,要确保其初始化操作符合要求,避免出现未定义行为。
  • 链接器配置检查:修改 .icf 文件后,要仔细检查链接器的输出信息,确保代码和数据被正确分配到指定的 RAM 区域。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值