• 正文
  • 相关推荐
申请入驻 产业图谱

STM32N6的超大外部SPRAM:让鱼和熊掌可以兼得

10/24 09:14
2800
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

STM32N6作为M55内核的MCU,其内存结构和传统的STM32系列有着很大的区别。片上集成高达数MB的SRAM(分布在多个域以支持并行处理和低延迟访问),相较于传统的STM32,它并没有片上FLash,需要依赖片外FLash来存放用户程序。

由于片上SRAM的大小在4.2MB(实际上好像会小一点),然后我塞入了一个YOLO模型,大小在2.3MB左右的大小,然后我又想摄像头显示画面,那么片上SRAM的空间就有些不够了。

例如这个YOLO模型的大小占用RAM总共2.38Mib,图像一帧的缓存大概1MB多,内部RAM大小岌岌可危。

为了解决这个问题STM32N6570-DK在片外集成有256Mbit(32MB)大小的Hexadeca-SPI SPRAM(不是SDRAM哦)作为可扩展内存,既可以解决片内RAM不够的问题,也可以放下多数的大体积模型,做到鱼和熊掌兼得。

本期我们就介绍如何映射外部SPRAM作为拓展内存使用。

1、XSPI介绍

STM32的XSPI接口是在高性能系列(如 STM32H7、STM32N6)上提供的一种增强型外部存储接口,它是对传统 SPI/QSPI/OSPI 的扩展与统一,主要用于连接 大容量、高带宽的外部存储器。其特点可以总结如下:

多线数据通道:支持 1-bit(SPI)、2-bit(DSPI)、4-bit(QSPI)、8-bit(OSPI),甚至扩展到 16-bit 的数据线。

灵活的存储:支持可挂载NOR Flash、NAND Flash、PSRAM、HyperRAM、DRAM 等。

存储映射模式支持:内存映射(Memory-mapped mode),使外部 Flash/PSRAM 看起来就像 MCU 内部存储一样,可以直接通过地址访问,无需显式调用读写函数。

高效传输机制:内置 FIFO 和缓存,支持 DMA 加速,减少 CPU 干预。

在STM32N6的内存分配中,我们可以看到XSPI1会被映射到内存地址0x90000000中,这代表着如果我们使用XSPI1作为SPRAM的话,代表着从0x90000000之后就是外扩内存的地址。

在XSPI的工作模式选择中,可以看到有多种模式,分别是:Octo-SPI 模式(Octal SPI,8 线SPI)可以理解为 QSPI 的升级版,把 4 根数据线扩展成 8 根。

Hexa-SPI 模式(Hexadeca SPI,16 线 SPI)可以看作是 Octo-SPI 的再扩展版,把 8 线翻倍到 16 线。

HyperBus 模式Cypres推出的高性能内存总线协议,HyperBus 是一个标准化协议,不只是“几根线”的区别,它规定了命令、地址、数据的时序,兼容性更好。

我们用作图像处理的话,可以选择Hexa-SPI模式,有着更高的带宽来传输图像。

在 STM32 的 XSPI 配置中,这些参数共同决定了外部存储器的访问方式:FIFO Threshold 用于设置缓冲触发阈值;Memory Mode 控制是否启用内存映射;Memory Type 和 Memory Size 对应外部存储器的类型与容量;Chip Select High Time Cycle 规定两次访问间的片选保持时间;Free Running Clock 决定空闲时是否持续输出时钟;Clock Mode 定义时钟极性与相位;Wrap Size 设置突发访问的环绕长度;Clock Prescaler 用来分频生成总线时钟;而 Sample Shifting 则在高速通信下调整采样点以保证时序稳定。

2、XSPI使用

其实主要是配置好XSPI模式,之后在CubeMX中进行初始化,STM32N6通过FSBL来加载引导程序。

可以看到,在STM32N6的Application工程中,CubeMX提供了多个链接方案,默认情况下选择的是:ROMxspi2.ld,也就是使用外部FLASH(xspi2)和内部RAM。

接着打开项目设置,在项目的链接文件中选择ROMxspi2_RAMxspi1.ld,即用户程序ROM链接到xspi2,SPRAM链接到xspi1.ld,映射到内存空间,即Flash从0x70000000开始,SPRAM从0x90000000开始。

在这个方案中,系统将会使用0x9000000开始共计0x04000000长度的内存作为外部RAM使用。

    /* Camera single frame buffer in EXTRAM (NOLOAD, non-initialized) */  .camera_buf (NOLOAD) :  {    . = ALIGN(32);    __scamera_buf = .;          /* camera buffer start symbol */    KEEP(*(.camera_buffer))     /* keep any object placed in .camera_buffer */    . = ALIGN(32);    __ecamera_buf = .;          /* camera buffer end symbol */  } >EXTRAM

在.ld文件中添加片段描述来,届时方便指定图像的缓存地址。

__attribute__ ((section (".camera_buf")))__attribute__ ((aligned (32)))uint8_t lcd_bg_buffer[800 * 480 * 2];

使用__attribute__将图像缓存区定义到片外RAM即可。

STM32N6570-DK的SPRAM空间很大,即便是我们将缓存区扩大到了50倍,也依旧绰绰有余。

如果没有放到SPRAM,就会出现内存不够的问题。

相关推荐