打印

GD32H7使用MPU配置cache不起作用

[复制链接]
2207|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
代码里面先配置0x24040000地址后16K的数据禁止cache功能,但写入buf_send数组时,似乎数据依然被写入到cache中,而没写入到实际内存中。使用dma传输数据后,对比发送接收数组数据应该相等,实际仿真数据不相等,会卡死在检测数据是否相等的while循环里面
将cache_enable();和mpu_config();注释掉,dma传输完成后,数据可以对上,代码可以运行到检测数据代码后面的while循环
想请教大佬,MPU配置有什么问题吗,先谢谢各位回复!

#include "gd32h7xx.h"
#include <stdio.h>

__attribute__((aligned(32))) static uint16_t buf_rx[320];

__attribute__((aligned(32))) static uint16_t buf_send[320] __attribute__((section(".ARM.__at_0x24040000")));                         /*A buffer for 10 rows*/
__attribute__((aligned(32))) static uint16_t buf_2[320] __attribute__((section(".ARM.__at_0x24042000")));

void cache_enable(void);
void mpu_config(void);
void dma_config(void);
void nvic_config(void);
void dma_send_data(uint16_t* data, uint32_t len);

int main(void)
{
  volatile uint32_t temp;
  uint32_t i;

/***************************/
  cache_enable();
  mpu_config();                                                        //MPU将0x24040000地址段 cache关闭
/***************************/
       
  dma_config();
       
  SCB_CleanDCache();                                //将cache清除

  for(i = 0; i < 320; i++)
  {
    temp = buf_send;                        //如果0x24040000 MPU配置不起作用,会把buf_send读取到cache中
    buf_rx = 0;                                        //buf_rx赋值为0
    //    temp=buf_2;
  }

  for(i = 0; i < 320; i++)
  {
    buf_send = i;                                //如果0x24000000 MPU配置不起作用,会将数据写入到cache中,不会写到实际地址内存中
  }
       
        //DMA发送数据
  dma_send_data(buf_send, 320);
  while(dma_flag_get(DMA1, DMA_CH0, DMA_FLAG_FTF) == RESET);
  dma_flag_clear(DMA1, DMA_CH0, DMA_FLAG_FTF);

        //清除cache
  SCB_CleanDCache();

        //比较dma发送数组和接收数组数据是否相同
  for(i = 0; i < 320 * 10; i++)
  {
    if(buf_rx != buf_send)        //前面写入数据到buf_send中,如果写入到实际地址中,此处数据可以对上,如果没写入到实际地址中,则数据不相等
    {
      while(1);                                //0x24040000地址段 依然带cache功能
    }
  }


  while(1)                                                //0x24040000配置起作用,数据被写入到实际地址中
  {
  }
}


void cache_enable(void)
{
  /* enable I-Cache */
  SCB_EnableICache();

  /* enable D-Cache */
  SCB_EnableDCache();
}


void mpu_config(void)
{
  mpu_region_init_struct mpu_init_struct;
  mpu_region_struct_para_init(&mpu_init_struct);

  /* disable the MPU */
  ARM_MPU_Disable();
  ARM_MPU_SetRegion(0, 0);

  /* configure the MPU attributes for AXI SRAM */
  mpu_init_struct.region_base_address  = 0x24040000;
  mpu_init_struct.region_size          = MPU_REGION_SIZE_16KB;
  mpu_init_struct.access_permission    = MPU_AP_FULL_ACCESS;
  mpu_init_struct.access_bufferable    = MPU_ACCESS_NON_BUFFERABLE;
  mpu_init_struct.access_cacheable     = MPU_ACCESS_NON_CACHEABLE;
  mpu_init_struct.access_shareable     = MPU_ACCESS_NON_SHAREABLE;
  mpu_init_struct.region_number        = MPU_REGION_NUMBER0;
  mpu_init_struct.subregion_disable    = MPU_SUBREGION_ENABLE;
  mpu_init_struct.instruction_exec     = MPU_INSTRUCTION_EXEC_PERMIT;
  mpu_init_struct.tex_type             = MPU_TEX_TYPE0;
  mpu_region_config(&mpu_init_struct);
  mpu_region_enable();

  /* enable the MPU */
  ARM_MPU_Enable(MPU_MODE_PRIV_DEFAULT);
}

void dma_config(void)
{
  dma_multi_data_parameter_struct dma_init_parameter;

  /* peripheral clock enable */
  rcu_periph_clock_enable(RCU_DMA1);

  dma_deinit(DMA1, DMA_CH0);
  dma_multi_data_para_struct_init(&dma_init_parameter);
  dma_init_parameter.periph_addr        = 0;
  dma_init_parameter.periph_width       = DMA_PERIPH_WIDTH_16BIT;
  dma_init_parameter.periph_inc         = DMA_PERIPH_INCREASE_ENABLE;
  dma_init_parameter.memory0_addr       = (uint32_t)buf_rx;
  dma_init_parameter.memory_width       = DMA_MEMORY_WIDTH_16BIT;
  dma_init_parameter.memory_inc         = DMA_MEMORY_INCREASE_ENABLE;
  dma_init_parameter.memory_burst_width = DMA_MEMORY_BURST_4_BEAT;
  dma_init_parameter.periph_burst_width = DMA_PERIPH_BURST_4_BEAT;
  dma_init_parameter.critical_value     = DMA_FIFO_2_WORD;
  dma_init_parameter.circular_mode      = DMA_CIRCULAR_MODE_DISABLE;
  dma_init_parameter.direction          = DMA_MEMORY_TO_MEMORY;
  dma_init_parameter.number             = 0;
  dma_init_parameter.priority           = DMA_PRIORITY_ULTRA_HIGH;
  dma_multi_data_mode_init(DMA1, DMA_CH0, &dma_init_parameter);
  dma_channel_disable(DMA1, DMA_CH0);
}


void dma_send_data(uint16_t* data, uint32_t len)
{
  dma_channel_disable(DMA1, DMA_CH0);
  dma_periph_address_config(DMA1, DMA_CH0, (uint32_t)data);
  dma_transfer_number_config(DMA1, DMA_CH0, len);
  dma_channel_enable(DMA1, DMA_CH0);
}








使用特权

评论回复
沙发
pigy0754| | 2025-2-23 20:29 | 只看该作者
楼主,你后面有找到原因么?现在也遇到相似的怪问题

使用特权

评论回复
板凳
flycamelaaa| | 2025-2-24 13:37 | 只看该作者
可能是MPU配置错误

使用特权

评论回复
地板
classroom| | 2025-2-24 13:40 | 只看该作者
硬件版本或固件版本可能存在限制或bug

使用特权

评论回复
5
powerantone| | 2025-2-24 15:00 | 只看该作者
cache未使能?

使用特权

评论回复
6
stormwind123| | 2025-2-24 15:26 | 只看该作者
代码或数据访问方式问题

使用特权

评论回复
7
probedog| | 2025-2-24 17:26 | 只看该作者
如果数据被频繁修改且未通过DMA访问,而cache策略设置为写回(write-back),则可能导致数据不一致。

使用特权

评论回复
8
zhuimenghong|  楼主 | 2025-2-24 18:35 | 只看该作者
pigy0754 发表于 2025-2-23 20:29
楼主,你后面有找到原因么?现在也遇到相似的怪问题

没找到    后面直接用SCB->CACR |= 1 << 2;强制将数据写入到内存里面

使用特权

评论回复
9
zhuimenghong|  楼主 | 2025-2-24 18:37 | 只看该作者

代码在cache_enable里面使能了cache      后面用MPU配置一段内存不使用cache

使用特权

评论回复
10
zhuimenghong|  楼主 | 2025-2-24 18:38 | 只看该作者
stormwind123 发表于 2025-2-24 15:26
代码或数据访问方式问题

能详细说一下是那部分的问题吗   谢谢

使用特权

评论回复
11
zhuimenghong|  楼主 | 2025-2-24 18:46 | 只看该作者
probedog 发表于 2025-2-24 17:26
如果数据被频繁修改且未通过DMA访问,而cache策略设置为写回(write-back),则可能导致数据不一致。
...

按配置MPU把0x24040000的cache功能关闭掉了    不是应该没有写回的操作吗

使用特权

评论回复
12
laocuo1142| | 2025-2-24 19:00 | 只看该作者
检查MPU参数设置是否正确。

使用特权

评论回复
13
jcky001| | 2025-2-24 19:59 | 只看该作者
建议查GD32H7的官方文档

使用特权

评论回复
14
两只袜子| | 2025-2-24 20:13 | 只看该作者
使能Cache,优化代码和数据访问方式

使用特权

评论回复
15
更多更合适ii| | 2025-2-28 16:44 | 只看该作者
MPU 配置可能没有完全禁用某些区域的缓存,因此,尽管你希望禁用缓存,但由于 MPU 配置不当,缓存仍然会影响数据的一致性。

使用特权

评论回复
16
更多更合适ii| | 2025-2-28 16:44 | 只看该作者
当你启用缓存时,CPU 会从缓存中读取数据,而不是直接从内存中读取数据。

使用特权

评论回复
17
宝挖小子| | 2025-3-26 16:31 | 只看该作者
jcky001 发表于 2025-2-24 19:59
建议查GD32H7的官方文档

GD32H7的MPU相关文档在哪里啊,一直没找到,数据手册里没有这部分介绍

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

8

帖子

1

粉丝