取消
显示结果 
搜索替代 
您的意思是: 
Highlighted
Visitor
Visitor
787 次查看
注册日期: ‎11-02-2018

AXI-DMA初始化失败

最近做一个AXI-DMA工程测试,在之前的AXI-DMA环路中的AXI-DMA和FIFO核之间加入自己的user IP。然后生成bit流,导入到SDK中,调用库函数,进行简单的DMA传输测试。但是程序一直卡在

Status = XAxiDma_CfgInitialize(DMAPtr, Config);这个函数中。

进行单步调试,汇编语言一直在下面几行代码中循环。

0010f98c:  str lr, [r12, #-16]
0010f990:  add r12, r12, #16
0010f994:  str lr, [r12, #-28]
0010f998:  str lr, [r12, #-24]
0010f99c:  str lr, [r12, #-20]
0010f9a0:  cmp r12, r4
0010f9a4: bne -32 ; addr=0x0010f98c: memset + 0x0000006c。

VIVADO下的工程图如下所示:VIVADO下工程VIVADO下工程

SDK下代码:

主函数
#include "dma_intr.h"
#include "sys_intr.h"
#include <stdio.h>
#include "xparameters.h"
#include "xil_cache.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "scugic_header.h"
#include "xdevcfg.h"
#include "devcfg_header.h"
#include "xdmaps.h"
#include "dmaps_header.h"
#include "xemacps.h"
#include "xemacps_example.h"
#include "emacps_header.h"
#include "xqspips.h"
#include "qspips_header.h"
#include "axidma_header.h"
#include "xscutimer.h"
#include "scutimer_header.h"
#include "xscuwdt.h"
#include "scuwdt_header.h"
#include "xttcps.h"
#include "ttcps_header.h"
static XScuGic Intc; //GIC中断控制器
static XAxiDma AxiDma;

int Tries = 6;
int i;
int Index;
u8 *TxBufferPtr= (u8 *)TX_BUFFER_BASE;
u8 *RxBufferPtr= (u8 *)RX_BUFFER_BASE;
u8 Value;

int axi_dma_test()
{
int Status;
TxDone = 0;
RxDone = 0;
Error = 0;

xil_printf("\r\n----DMA Test----\r\n");
xil_printf("PKT_LEN=%d\r\n",MAX_PKT_LEN);

for(i = 0; i < Tries; i ++)
{
Value = 0x55 + (i & 0xFF);
for(Index = 0; Index < MAX_PKT_LEN; Index ++) {
TxBufferPtr[Index] = Value;

Value = (Value + 1) & 0xFF;
}

Xil_DCacheFlushRange((u32)TxBufferPtr, MAX_PKT_LEN);//数据刷新到DDR中

Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) RxBufferPtr,//配置接收通道
MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);
if (Status != XST_SUCCESS) {return XST_FAILURE;}

Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) TxBufferPtr,//配置发送通道
MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);
if (Status != XST_SUCCESS) {return XST_FAILURE;}

//while (!TxDone || !RxDone) { }//等待收发中断都到达

TxDone = 0;
RxDone = 0;
if (Error) {return XST_FAILURE;}

Xil_DCacheInvalidateRange((u32)RxBufferPtr, MAX_PKT_LEN);//刷新cache,观察DDR的最新数据
}

DMA_DisableIntrSystem(&Intc, TX_INTR_ID, RX_INTR_ID);//失能DMA中断
xil_printf("--- Exiting Test --- \r\n");
return XST_SUCCESS;
}

int main(void)
{
DMA_Intr_Init(&AxiDma,0);//DMA初始化
Init_Intr_System(&Intc); //系统初始化
Setup_Intr_Exception(&Intc);//使能硬件中断
DMA_Setup_Intr_System(&Intc,&AxiDma,TX_INTR_ID,RX_INTR_ID);//注册DMA收发中断
DMA_Intr_Enable(&Intc,&AxiDma);//使能系统中断
axi_dma_test();
}

XAxiDma_CfgInitialize() 函数:

int XAxiDma_CfgInitialize(XAxiDma * InstancePtr, XAxiDma_Config *Config)
{
UINTPTR BaseAddr;
int TimeOut;
int Index;
u32 MaxTransferLen;

InstancePtr->Initialized = 0;

if(!Config) {
return XST_INVALID_PARAM;
}

BaseAddr = Config->BaseAddr;

/* Setup the instance */
memset(InstancePtr, 0, sizeof(XAxiDma));
InstancePtr->RegBase = BaseAddr;

/* Get hardware setting information from the configuration structure
*/
InstancePtr->HasMm2S = Config->HasMm2S;
InstancePtr->HasS2Mm = Config->HasS2Mm;

InstancePtr->HasSg = Config->HasSg;

InstancePtr->MicroDmaMode = Config->MicroDmaMode;
InstancePtr->AddrWidth = Config->AddrWidth;

/* Get the number of channels */
InstancePtr->TxNumChannels = Config->Mm2sNumChannels;
InstancePtr->RxNumChannels = Config->S2MmNumChannels;

/* This condition is for IP version < 6.
*
* 00a */
if (!InstancePtr->TxNumChannels)
InstancePtr->TxNumChannels = 1;
if (!InstancePtr->RxNumChannels)
InstancePtr->RxNumChannels = 1;

if ((InstancePtr->RxNumChannels > 1) ||
(InstancePtr->TxNumChannels > 1)) {
MaxTransferLen =
XAXIDMA_MCHAN_MAX_TRANSFER_LEN;
}
else {
MaxTransferLen =
XAXIDMA_MAX_TRANSFER_LEN;
}

/* Initialize the ring structures */
InstancePtr->TxBdRing.RunState = AXIDMA_CHANNEL_HALTED;
InstancePtr->TxBdRing.IsRxChannel = 0;
if (!InstancePtr->MicroDmaMode) {
InstancePtr->TxBdRing.MaxTransferLen = MaxTransferLen;
}
else {
/* In MicroDMA mode, Maximum length that can be transferred
* is '(Memory Data Width / 4) * Burst Size'
*/
InstancePtr->TxBdRing.MaxTransferLen =
((Config->Mm2SDataWidth / 4) *
Config->Mm2SBurstSize);
}
InstancePtr->TxBdRing.RingIndex = 0;

for (Index = 0; Index < InstancePtr->RxNumChannels; Index++) {
InstancePtr->RxBdRing[Index].RunState
= AXIDMA_CHANNEL_HALTED;
InstancePtr->RxBdRing[Index].IsRxChannel = 1;
InstancePtr->RxBdRing[Index].RingIndex = Index;
}

if (InstancePtr->HasMm2S) {
InstancePtr->TxBdRing.ChanBase =
BaseAddr + XAXIDMA_TX_OFFSET;
InstancePtr->TxBdRing.HasStsCntrlStrm =
Config->HasStsCntrlStrm;
if (InstancePtr->AddrWidth > 32)
InstancePtr->TxBdRing.Addr_ext = 1;
else
InstancePtr->TxBdRing.Addr_ext = 0;

InstancePtr->TxBdRing.HasDRE = Config->HasMm2SDRE;
InstancePtr->TxBdRing.DataWidth =
((unsigned int)Config->Mm2SDataWidth >> 3);
}

if (InstancePtr->HasS2Mm) {
for (Index = 0;
Index < InstancePtr->RxNumChannels; Index++) {
InstancePtr->RxBdRing[Index].ChanBase =
BaseAddr + XAXIDMA_RX_OFFSET;
InstancePtr->RxBdRing[Index].HasStsCntrlStrm =
Config->HasStsCntrlStrm;
InstancePtr->RxBdRing[Index].HasDRE =
Config->HasS2MmDRE;
InstancePtr->RxBdRing[Index].DataWidth =
((unsigned int)Config->S2MmDataWidth >> 3);

if (!InstancePtr->MicroDmaMode) {
InstancePtr->RxBdRing[Index].MaxTransferLen =
MaxTransferLen;
}
else {
/* In MicroDMA mode, Maximum length that can be transferred
* is '(Memory Data Width / 4) * Burst Size'
*/
InstancePtr->RxBdRing[Index].MaxTransferLen =
((Config->S2MmDataWidth / 4) *
Config->S2MmBurstSize);
}
if (InstancePtr->AddrWidth > 32)
InstancePtr->RxBdRing[Index].Addr_ext = 1;
else
InstancePtr->RxBdRing[Index].Addr_ext = 0;
}
}

/* Reset the engine so the hardware starts from a known state
*/
XAxiDma_Reset(InstancePtr);

/* At the initialization time, hardware should finish reset quickly
*/
TimeOut = XAXIDMA_RESET_TIMEOUT;

while (TimeOut) {

if(XAxiDma_ResetIsDone(InstancePtr)) {
break;
}

TimeOut -= 1;

}

if (!TimeOut) {
xdbg_printf(XDBG_DEBUG_ERROR, "Failed reset in"
"initialize\r\n");

/* Need system hard reset to recover
*/
InstancePtr->Initialized = 0;
return XST_DMA_ERROR;
}

/* Initialization is successful
*/
InstancePtr->Initialized = 1;

return XST_SUCCESS;
}

这是什么原因

 

 

0 项奖励
2 条回复2
Highlighted
Moderator
Moderator
751 次查看
注册日期: ‎05-23-2018

回复: AXI-DMA初始化失败

Hi, @alexscl 

XAxiDma_CfgInitialize函数是在哪里调用的?前后代码是什么样的?另外,建议把代码以附件的形式附上,不要直接贴出来。

-------------------------------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------------------------------
如果提供的信息能解决您的问题,请标记为“接受为解决方案”。
如果您认为帖子有帮助,请点击“奖励”。谢谢!
-------------------------------------------------------------------------------------------------
0 项奖励
Highlighted
Contributor
Contributor
441 次查看
注册日期: ‎05-17-2014

回复: AXI-DMA初始化失败

Hi, 你好,问题解决了嘛? 怎么解决的,我现在碰到了和你一样的问题
0 项奖励