我在玩STM32H753的L1缓存。
我想要做的是激发-on的目的-缓存和内存之间的不一致性如下:
以下是代码:
volatile uint32_t someDummyVariable ;
int main(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
HAL_Init();
/* Configure the MPU attributes as Write-through for SRAM */
HAL_MPU_Disable();
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x20000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; // -> means write through ?
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes as WT for the Flash */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x08000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
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_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_HARDFAULT_NMI);
SCB_EnableDCache();
// write something in a variable in RAM -> thanks to write-through attribute
// it will be copied to real RAM, not only to the cache
someDummyVariable = 0x12345678;
// disable cache without invalidating it
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */
__DSB();
__ISB();
// write something else to RAM -> will NOT be written to cache
someDummyVariable = 0xAAAAAAAA;
// enable cache again (without invalidating or cleaning it)
__DSB();
SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */
__DSB();
__ISB();
// now we should read the old value that is still in the cache
if ( someDummyVariable != 0x12345678 )
{
__NOP();
}用Keil 5,-O0编译。变量写是通过STR完成的(我的意思是:据我所知,没有奇怪的CPU优化)。
我检查了MPU寄存器值,RAM变量的地址(实际上在MPU区域内)。
算法和/或代码中有什么问题吗?
编辑:修复MPU配置
发布于 2020-11-22 10:09:45
您正在尝试启用/禁用DTCMRAM的缓存,该缓存从地址0x200000000开始。然而,DTCMRAM是紧密耦合的内存。它直接连接到Cortex-M7内核,是,而不是缓存后面的。您可以在(参考手册)的图1 (系统架构)中看到这一点。因此,缓存操作对此内存没有影响。
如果要进行此测试,则必须使用另一个内存区域,例如AXI SRAM (从地址0x24000000开始)。这可以通过修改链接器脚本(可能是启动代码),或者通过使用指针变量直接写入固定内存地址来实现。
请注意,在不禁用缓存的情况下,在RAM和缓存之间创建不匹配的另一种可能性是使用DMA控制器访问与MCU相同的内存。DMA控制器不使用缓存,因此如果DMA控制器写入缓存中的内存,应用程序将读取旧的缓存版本,而不是新写入的数据。然后,您的测试将是这样的:
https://stackoverflow.com/questions/59198934
复制相似问题