8.11.5 Coherent Variable Attribute
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 an uncached
address.
For devices featuring an L1 data cache, data variables are allocated to the kseg0
data-memory region (kseg0_data_mem), making it accessible
through the L1 cache. Likewise, the linker-allocated heap and stack are
allocated to the kseg0 region.
coherent variable attribute that allows you to create a DMA
buffer allocated to the kseg1_data_mem
region:unsigned int __attribute__((coherent)) buffer [1024];coherent attribute with the
address attribute, be sure to use the default
data-memory region address for the device. On devices featuring an L1 data
cache, the default data-memory region is
kseg0_data_mem:unsigned int __attribute__((coherent,address(0x80001000))) buffer[1024]__pic32_alloc_coherent(size_t) and
__pic32_free_coherent(void *) functions allocate
and free memory from the uncached kseg1_data_mem region. The default stack
is allocated to the cached kseg0_data_mem region, but you may want to create
an uncached DMA buffer, so you can use these functions to allocate an
uncached buffer. These functions call the standard
malloc()/free() functions, but the pointers that
they use are translated from kseg0 to kseg1. For
example:#include<xc.h>
void jak(void) {
char * buffer = __pic32_alloc_coherent(1024);
if (buffer) {
/* do somehing */
} else {
/* handle error */
}
if (buffer) {
__pic32_free_coherent(buffer);
}
}mytype *p1, *p2;
p1 = __pic32_calloc_coherent (sizeof(mytype) + 16);
uintptr_t addr = (uintptr_t)p1;
uintptr_t aligned_addr = (addr + 15) & ~((uintptr_t)15);
p2 = (mytype *)aligned_addr;