|
发表于 2019-5-13 15:21:20
|
显示全部楼层
本帖最后由 艾那的小强 于 2019-5-13 15:22 编辑
请教楼主及硬汉哥。
打开cache,并使用下面的MPU配置代码:
- MPU_InitStruct.Enable = MPU_REGION_ENABLE;
- MPU_InitStruct.BaseAddress = 0x24000000;
- MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
- MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
- MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;//这里改成不缓冲
- MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
- MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
- MPU_InitStruct.Number = MPU_REGION_NUMBER0;
- MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
- MPU_InitStruct.SubRegionDisable = 0x00;
- MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
复制代码
使用该区域的一块内存作为DMA串口接收缓冲区dma_buffer,然后定义了一个串口读接口,
int dma_rx(char *data, int length)
{
...
memcpy(data, dma_buffer + get_index, recv_len);
}
读接口内部是拷贝DMA缓冲区的数据,但测试的结果是,该接口返回的数据总是0(也就是没有拷贝出来)。
但是使用jlink仿真时,断点下到memcpy那里,可以看到dma_buffer里面是有数据的。
看了硬汉歌的教程之后,知道在memcpy之前加一句SCB_InvalidateDCache_by_Addr就行了。
另外,不使用cache时,该接口返回正常。
我的问题是:
1. 如果使用了DMA的功能,那么DMA用到(读或者写)的那块内存缓存区位于哪个Domain就把那个Domain按上面的MPU配置进行设置,并且在CPU操作这块DMA缓存区时都要SCB_InvalidateDCache_by_Addr一下吗?
2. 如果为DMA缓存区单独配置一个MPU的话应该也可以达到目的,不过,如果系统中有多个DMA功能时,该怎么使用cache及MPU呢?
还请楼主及硬汉哥给指点迷津。谢谢。 |
|