Despite the successful DMA transfer, the serial output of the application shows that there is an unexpected result, because the destination buffer does not match with the source buffer.
Launch the debug session and place a breakpoint in the return XST_FAILURE
line for the DMA transfer, so that the execution is halted when the transfer failure is detected and the memory is inspected for further analysis.
The Vitis IDE provides the following main methods of inspecting the memory content:
Memory tab: Displays the memory content based on memory addresses.
Variables tab: Displays all the variables in the context of a function.
Expressions tab: Displays any valid symbol in the context of the application.
These tabs are all context aware, meaning that they display content based on the context target selected in the Debug session window (APU, R5#0, or A53#0). The Variables and Expressions tabs are therefore only valid for the targets where the application is running. Additionally, processor targets display the cache value rather than the content in the physical memory.
The index variable value indicates that the first element of the destination array does not match with the first element on the source buffer. Because both the ZDmaSrcBuf and ZDmaDstBuf variables are static, they are not displayed in the Variable window, so you can use the Expressions window to inspect them. Select the Expressions tab and add both buffers to the list. The displayed expressions confirm that the destination buffer is populated with the default values.
When a processor core accesses cacheable memory, the read value may not be the value in the physical memory. You can use the Vitis IDE to access the same memory address from a different target not subject to the cache. Targets such as the APU cluster or PSU are not subject to the cache, but they do not have an associated symbol file either, so the Variables and Expressions tables do not apply.
Use the memory window and add the address of both ZDmaSrcBuf (0xB180) and ZDmaDstBuf (0xB1C0). Check the values on ZDmaDstBuf to verify that the DMA transfer is performed properly and the destination buffer is identical to the source buffer.
The process of accessing the memory from the APU generates cache maintenance operations, so the A53#0 core is able to get the correct values from the destination buffer moving forward. Select the A53#0 core again, and right-click in the Expressions tab to refresh the values. The values in the destination buffer now match the sources.
The debugging effort detailed above confirms that there is a cache maintenance operation missing in the application; specifically, cache invalidation prior to reading back the destination buffer after the DMA operation is performed. This operation would ensure that the physical memory is read instead of whatever the cache might have.
Open main.c
in the file editor and add Xil_DCacheInvalidateRange((INTPTR)ZDmaDstBuf, SIZE);
after the DMA transfer is performed and prior to reading the destination buffer.
Build the application and launch the initially created debug session again. This time the execution does not end at the exit point, but serial output confirms that the DMA transfer is successful.