Disable cache for shared data

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.

kseg1.PNG

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];

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.


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.

© 2024 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.