2026 / 07 / 22
RA 系列:Cortex-M33 MCU 在未配置 MPU 的情况下启用 s-cache 时的潜在问题

Issue:

瑞萨的一些 Cortex-M33 MCU为了提升性能,配置了两个缓存。它们位于 Cortex-M33 和 AHB 总线矩阵之间,c-cache 位于指令总线上,s-cache 位于数据总线上。启用 s-cache 后,用户可能会遇到一些通信失败的情况,例如:

· 外部QSPI存储器

· 外部 OSPI 存储器

· 与 SRAM 中的 CPU 共享内存(以太网、Segger RTT viewer)


Answer

有两种方法可以解决此问题:

1. 使用 s-cache 刷新(invalidate/clean) 指令。

2. 使用 MPU(内存保护单元)。

有关 s-cache 刷新的使用、DMA/DTC 的缓存一致性问题和 MPU 的更多信息,请参阅以下链接。
https://www.renesas.com/us/en/document/apn/ra-family-guidelines-using-s-cache-system-bus

第二种方法是使用 MPU,即仅在导致问题发生的用户可配置内存的特定区域中禁用 s-cache。下面我们说明如何通过配置 MPU 来解决这个问题。 有关每个 MPU 设置的详细信息,请参阅文末附上的参考文档。

以下定义将在所有要说明的 3 种情况下通用。

#define CTRL_PV 1
#define CTRL_HN 1
#define ARM_MPU_CTRL(PV, HN) \
(((PV) << MPU_CTRL_PRIVDEFENA_Pos) | \
(HN) << MPU_CTRL_HFNMIENA_Pos)
 
#define MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL 0x04
#define MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX 0
#define MPU_ARMV8M_MAIR_ATTR_CODE_VAL 0xAA
#define MPU_ARMV8M_MAIR_ATTR_CODE_IDX 1
#define MPU_ARMV8M_MAIR_ATTR_DATA_VAL 0xFF
#define MPU_ARMV8M_MAIR_ATTR_DATA_IDX 2
#define MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_VAL 0x44
#define MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX 3


(1) 外部QSPI存储器

使用以下代码禁用 QSPI 内存位置上的 s-cache。如果您所用的 MCU 具有不同的 QSPI 地址映射,请在 “ARM_MPU_RBAR”和“ARM_MPU_RLAR”中更改相应的地址。

0x6000 0000 - 0x63FF FFFF:外部SPI设备

0x6400 0000 - 0x67FF FFFF:QSPI I/O寄存器

const ARM_MPU_Region_t mpuTable[2] = {
    //                         BASE          SH              RO   NP   XN
    { .RBAR = ARM_MPU_RBAR(0x60000000UL, ARM_MPU_SH_NON, 0UL, 1UL, 1UL),
    //                        LIMIT         ATTR
      .RLAR = ARM_MPU_RLAR(0x63FFFFFFUL, MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX) },
 
    //                         BASE          SH              RO   NP   XN
    { .RBAR = ARM_MPU_RBAR(0x64000000UL, ARM_MPU_SH_NON, 0UL, 1UL, 1UL),
    //                         LIMIT         ATTR
      .RLAR = ARM_MPU_RLAR(0x67FFFFFFUL, MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX) }
};
 
void mpu_config_quadspi(void)
{
ARM_MPU_Disable();
 
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX, MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_CODE_IDX, MPU_ARMV8M_MAIR_ATTR_CODE_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DATA_IDX, MPU_ARMV8M_MAIR_ATTR_DATA_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX, MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_VAL);
 
  ARM_MPU_Load(0, mpuTable, 2);
 
  ARM_MPU_Enable(ARM_MPU_CTRL(CTRL_PV, CTRL_HN));
}
 
void hal_entry(void)
{
  mpu_config_quadspi();
enable_s_cache();
 
qspi_init();
 
  while(1)
  {


(2) 外部 OSPI 存储器

使用以下代码禁用 OSPI 区域上的 s-cache。如果您的 MCU 具有不同的 OSPI 地址映射,请相应地更改“ARM_MPU_RBAR”和“ARM_MPU_RLAR”中的地址。

0x6800 0000 - 0x6FFF FFFF : CS0

0x7000 0000 - 0x7FFF FFFF : CS1

void mpu_config_octaspi(void)
{
ARM_MPU_Disable();
 
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX, MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_CODE_IDX, MPU_ARMV8M_MAIR_ATTR_CODE_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DATA_IDX, MPU_ARMV8M_MAIR_ATTR_DATA_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX, MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_VAL);
 
  ARM_MPU_Load(0, mpuTable, 2);
 
  ARM_MPU_Enable(ARM_MPU_CTRL(CTRL_PV, CTRL_HN));
}
 
void hal_entry(void)
{
  mpu_config_octaspi();
enable_s_cache();
 
ospi_init();
 
  while(1)
  {


(3) SRAM中与CPU共享存储器

以太网 (EDMAC)

使用以下代码禁用 EDMAC 描述符和缓冲区区域上的 s-cache。e2 studio 项目的默认链接器脚本会将 EDMAC 描述符和缓冲区放在 “.ns_buffer.eth”区域,这些地址可能会随着代码更改而更改。因此,请相应地更改“ARM_MPU_RBAR”和“ARM_MPU_RLAR”的地址,或将 EDMAC 描述符和缓冲区放在有固定地址的区域。

图1 内存映射文件片段(EDMAC)


使用上面给定的内存映射文件片段示例后,覆盖了 EDMAC 描述符和缓冲区的内存区域将为:

起始地址:0x2003 CF80

结束地址:0x2003 FFFF (0x2003CF80 + 0x3080 – 1)

请注意,MPU 地址应为 32 字节的倍数。

const ARM_MPU_Region_t mpuTable[1] = {
    //                       BASE          SH              RO   NP   XN
    { .RBAR = ARM_MPU_RBAR(0x2003CF80, ARM_MPU_SH_NON, 0UL, 1UL, 1UL),
    //                       LIMIT         ATTR
      .RLAR = ARM_MPU_RLAR(0x2003FFFF, MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX) },
};
 
void mpu_config_eth(void)
{
ARM_MPU_Disable();
 
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX, MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_CODE_IDX, MPU_ARMV8M_MAIR_ATTR_CODE_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DATA_IDX, MPU_ARMV8M_MAIR_ATTR_DATA_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX, MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_VAL);
 
  ARM_MPU_Load(0, mpuTable, 1);
  ARM_MPU_Enable(ARM_MPU_CTRL(CTRL_PV, CTRL_HN));
}
 
void hal_entry(void)
{
  mpu_config_eth();
enable_s_cache();
 
  while(1)
  {


Segger RTT
Viewer

使用以下代码禁用 Segger RTT 区域上的 s-cache。Segger RTT 使用一部分用户 SRAM 来输出调试信息,以及接收用户的输入。以下 3 个区域的起始地址和结束地址可以在项目编译后的内存映射文件中找到,请在“ARM_MPU_RBAR”和“ARM_MPU_RLAR”中修改相应地址。

.bss._SEGGER_RTT

.bss._acUpBuffer

.bss._acDownBuffer

图2 内存映射文件片段(Segger RTT Viewer)


使用了上面给定的内存映射文件片段示例,覆盖了所有 3 个区域的内存区域将为:

起始地址:0x2000 01D4

结束地址:0x2000 128B

MPU 地址应为 32 字节的倍数,因此:

起始地址:0x2000 01C0

结束地址:0x2000 129F

const ARM_MPU_Region_t mpuTable[1] = {
    //                         BASE          SH              RO   NP   XN
    { .RBAR = ARM_MPU_RBAR(0x200001C0UL, ARM_MPU_SH_NON, 0UL, 1UL, 1UL),
    //                         LIMIT         ATTR
      .RLAR = ARM_MPU_RLAR(0x2000129FUL, MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX) },
};
 
void mpu_config_rtt(void)
{
ARM_MPU_Disable();
 
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX, MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_CODE_IDX, MPU_ARMV8M_MAIR_ATTR_CODE_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DATA_IDX, MPU_ARMV8M_MAIR_ATTR_DATA_VAL);
  ARM_MPU_SetMemAttr(MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX, MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_VAL);
 
  ARM_MPU_Load(0, mpuTable, 1);
 
  ARM_MPU_Enable(ARM_MPU_CTRL(CTRL_PV, CTRL_HN));
}
 
void hal_entry(void)
{
  mpu_config_rtt();
enable_s_cache();
 
SEGGER_RTT_printf(“HELLO”);
 
  while(1)
  {


Arm Cortex-M33 处理器技术参考手册
https://documentation-service.arm.com/static/5f15c42420b7cf4bc5247f3a


Armv8-M 架构参考手册
https://documentation-service.arm.com/static/5f8efe85f86e16515cdbe596


系统总线上 S 高速缓存的使用指南
https://www.renesas.com/us/en/document/apn/ra-family-guidelines-using-s-cache-system-bus

文件下载
隐私条款

一、接受条款 使用者(也称"您")在访问或使用本网站及其服务时,即已经表示同意并不加修改地接受本《用户协议》、本网站的《隐私声明》、《法律声明》以及其关或相链接的网页和网站的条件和条款的规定。我们强烈建议:在您阅读和接受本《用户协议》时,也应阅读并接受本《用户协议》中所提到《隐私声明》、《法律声明》及其相关或相链接网页或网站所包含的资料,因为《隐私声明》、《法律声明》及其它相关网页或网站可能包含对您适用的进一步规定。(请注意:点击划有底线的词句即可链接到上述《隐私声明》、《法律声明》及其它相关或相链接的网页和网站。

 

二、使用者的资格要求 在本网站中"使用者"指的是浏览、阅读、使用本网站信息或服务的任何个人或组织。本网站的服务仅适用于根据相关法律的规定具有签订有约束力的合同的个人或组织并仅由其使用。本网站的服务不向18周岁以下的个人使用者提供,也不向临时被本网站中止或取消使用者资格的使用者提供。如果使用者不符合本条规定,请停止使用本网站或本网站的服务。

样品
申请

应用
资源

微信