打印

GD32H7使用MPU配置cache不起作用

[复制链接]
95|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
代码里面先配置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);
}








使用特权

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

本版积分规则

1

主题

4

帖子

1

粉丝