代码里面先配置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);
}
|