Disable Cache for Shared Data

Last modified by Microchip on 2023/11/10 11:08

The default cache policy is write-back with write allocation. This policy is the easiest for the hardware to implement and consumes the least system bus resources and power. It is also the least useful for keeping shared (CPU and DMA) data coherent. Combining this cache policy with uncached memory for shared data is the simplest cache management approach. 

kseg1 cache management diagram

You can force specific variables or buffers to be uncached by allocating shared data to the uncached memory segment (KSEG1).

The core uses virtual addresses to access main memory. The virtual KSEG memory segments share the same physical addresses. DMA always uses physical addresses.

Back to top

Static Variables

Static variables can be created using the coherent attribute. This assigns a variable or array to the un-cached KSEG1 memory segment.

unsigned int __attribute__((coherent)) buffer[1024];

The coherent variable attribute causes the compiler/linker to place the variable into a unique section that is allocated to the KSEG1 region, rather than the KSEG0 region (which is the default on L1 cached devices). This means that the variable is accessed through the uncached address.

Back to top

Automatic Variables

The stack is implemented in cachable memory (KSEG0) by default. If you don’t want to cache automatic (local) variables, use the
_ _pic32_alloc_coherent() and _ _pic32_free_coherent() functions as shown in this example.

#include <xc.h>
void myFunction(void)
{
   char* buffer = __pic32_alloc_coherent(1024);
   if (buffer)
    {
       /* do something */
    }
   else
    {
       /* handle error */
    }
   if (buffer)
    {
        __pic32_free_coherent(buffer);
    }
}

The pic32_alloc_coherent(size_t) and pic32_free_coherent(void*) functions are XC32 C compiler utility functions that can be used to allocate and free memory from the uncached kseg1_data_mem region. You can use these functions to allocate an uncached buffer for local variables shared with DMA. These functions call the standard malloc()/free() functions, but the pointers that they use are translated from kseg0 to kseg1.

Back to top