NetBurner 3.5.0
PDF Version
 
ARM Cache Management

When using some features like DMA or otherwise experiencing cache coherency issues and instability, you may want to disable memory caching.

Details

What happens if memory changes a region AND there is a delayed write to the same region? Who wins? Is this an issue for things like ethernet where both CPU and DMA hardware can both change an area? Whoever writes to RAM later wins: For example if the CPU has the address in the cache and writes to it, and then the Hardware writes to it, then the CPU evicts the cache line and flushes, the CPU wins. If the CPU writes to the RAM first, then the Hardware writes to it, the Hardware wins. Either way, this will be a poorly defined system that will fail in real opperations.

Whenever DMA is expected to write to memory, the CPU shall not write to that region. Whenever the CPU needs to read data that DMA has written, unless the region is known to be non-cached, the code shall issue a cache invalidation for the region in question.

Whenever the CPU writes to a region that is cached and needs DMA to read a coherent state of the memory, the software shall issue a cache cleaning for the region in question.

Instructions

Turning cache on/off

  • SCB_EnableDCache();
  • SCB_DisableDCache();
  • SCB_EnableICache();
  • SCB_DisableICache();

Declaring static objects non cachable

Non cacheable objects only live in On Chip FlexRAM which is SRAM. PSRAM is all cached.

To declare a variable as non-cached, use the variable tag DO_NOT_CACHE, akin to FAST_USER_VAR: uint32_t foo DO_NOT_CACHE;

Note
You cannot assign a static value to non-cached objects.

Cleaning Cache

(Making sure all cache -> memory transactions are complete)

  • For whole cache:
    asm("dsb");
    SCB_CleanDCache();
  • For a defined region of memory:
    asm("dsb");
    SCB_CleanDCache_by_Addr(<start address>, <buffer size>);

Invalidating Cache

(Making sure memory changes make it to cache)

  • For whole cache.
    asm("dsb");
    SCB_InvalidateDCache();
  • For a defined region of memory:
    asm("dsb");
    SCB_InvalidateDCache_by_Addr(<start address>, <buffer size>);