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 using uncached memory for shared data is the simplest cache management approach.
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.
Click for more detail on virtual vs physical addresses
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];
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.