I'm working on a Zynq Ultrascale+ MPSoC and trying to play around with the on and off chip memories. In the following program, I'm trying to place only variable 'x' into OCM (on-chip-memory) where everything else is loaded into external DDR.
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
volatile u32 x __attribute__ ((section ("psu_ocm_ram_0_MEM_0"))) = 10;
volatile u32 *p = &x;
int main()
{
init_platform();
xil_printf("x = %u\r\n", x);
xil_printf("p = %p\r\n", p);
cleanup_platform();
return 0;
}
The output is:
x = 10
p = 2AB0
So it doesn't look like p is pointing to a variable in OCM memory according to the memory map below.
If I change to linker script to put the entire .data section into OCM (and get rid of the gcc attribute), then the output becomes as I expected:
x = 10
p = FFFC0130
The weird thing is that the .map file for the original program does show that the linker is trying to do something with the variable, I'm just not sure what:
0x0000000000002ab0 __data_end = .
.tm_clone_table
0x0000000000002ab0 0x0
.tm_clone_table
0x0000000000002ab0 0x0
.tm_clone_table
0x0000000000002ab0 0x0
.igot.plt 0x0000000000002ab0 0x0
.igot.plt 0x0000000000002ab0 0x0
psu_ocm_ram_0_MEM_0
0x0000000000002ab0 0x4
psu_ocm_ram_0_MEM_0
0x0000000000002ab0 0x4 ./src/helloworld.o
0x0000000000002ab0 x
So it looks like the variable is being placed at the end of the .data section, which is in DDR (for the original code), but I want the variable in OCM. Anybody know what's going on here?
Best Answer
It turns out I wasn't using the gcc attribute correctly. I was trying to place the variable directly into OCM using:
as if the compiler is able to put individual variables into specific memory locations. Rather, it's the linker that's responsible for assigning all executable code (data and instructions) to physical memory. It order to make this work, I had to create a custom section in the linker script and assign this section to OCM:
Then in my code:
The output was then:
as expected.