本帖最后由 KcMeterCEC 于 2016-10-24 15:57 编辑
大家好,
我尝试把PL的数据传送至DDR中,发现官方提供了一个AXI_DMA回环测试的例程。
然后我使用了最简单的轮询模式代码,验证发送的数据是否被正确接收。当然测试程序也通过了。
然后我做了一些改动:
官方例程中发送和接收缓存都是以1字节对齐的,一共发送了32字节。
1、我将缓存改为4字节对齐:
u32 *TxBufferPtr;
u32 *RxBufferPtr;
u32 Value;
TxBufferPtr = (u32 *)TX_BUFFER_BASE;
RxBufferPtr = (u32 *)RX_BUFFER_BASE;
2、同时发送以及接收函数修改为:
Status = XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR) RxBufferPtr,MAX_PKT_LEN * sizeof(Value), XAXIDMA_DEVICE_TO_DMA);
Status = XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR) TxBufferPtr,MAX_PKT_LEN * sizeof(Value) , XAXIDMA_DMA_TO_DEVICE);
此时 MAX_PKT_LEN 的值依然为32,也就是说我一共会发送和接收128字节的数据。
3、同理验证函数(CheckData)也作以下修改
static int CheckData(void)
{
u32 *RxPacket;
int Index = 0;
u32 Value;
RxPacket = (u32 *) RX_BUFFER_BASE;
Value = TEST_START_VALUE;
/* Invalidate the DestBuffer before receiving the data, in case the
* Data Cache is enabled
*/
#ifndef __aarch64__
Xil_DCacheInvalidateRange((UINTPTR)RxPacket, MAX_PKT_LEN);
#endif
for(Index = 0; Index < MAX_PKT_LEN; Index++) {
xil_printf("rx ->%d = 0x%x\r\n",Index,RxPacket[Index]);
if (RxPacket[Index] != Value) {
xil_printf("Data error %d: %x/%x\r\n",
Index, (unsigned int)RxPacket[Index],
(unsigned int)Value);
return XST_FAILURE;
}
Value = Value + 1;
}
return XST_SUCCESS;
}
4、出现问题:
接收缓存依然只能接收到正确的32字节数据,其余数据都是乱的!
我尝试过将MAX_PKT_LEN改为 小于或等于8,也就是传送的数据小于或等于32。整个过程就正常了。
5、尝试解决方案
5.1我反复看过AXI_DMA的手册,IP核设置中,与传送数据大小有直接关系的只有"Width of Buffer Length Register"这个位有关,
计算公式为2的N次方。比如现在IP核默认的是14bit,则DMA控制器可以传送的最大字节数为16K字节。远远超过128字节
5.2查看例程中的MAX_PKT_LEN也并没有给DMA的哪个寄存器赋值,进入调试模式查看接收缓存在超过32字节的位置也确实为随机数。
6、以下为一些实际截图
当设置MAX_PKT_LEN 为9,也就是发送数据为36字节时的串口输出:

当设置MAX_PKT_LEN 为5,也就是发送数据为20字节时的串口输出:

vivado 框图

axi_dma设置

|