风岸臻寂 2021-05-03 16:23 采纳率: 0%
浏览 310

ZYNQ7000用AXI DMA向PL传数据,模式判断两次结果不同

在ZYNQ上用AXI DMA从DDR中的数组向PL端发送数据,AXI DMA工作在Simple模式下,初始化正常,DMA没有工作在SG模式下,

    if (XAxiDma_HasSg(DMAPtr)) {
        xil_printf("Device configured as SG mode \r\n");
        return XST_FAILURE;
    }

程序工作到

status = XAxiDma_SimpleTransfer(&DMAPtr, (UINTPTR) rxbuffer,
    	MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);

传输失败,失败原因是:在该函数中判断DMA工作在SG模式下,

	/* If Scatter Gather is included then, cannot submit
	 */
	if (XAxiDma_HasSg(InstancePtr)) {
		xdbg_printf(XDBG_DEBUG_ERROR, "Simple DMA mode is not"
							" supported\r\n");
xil_printf("1");
		return XST_FAILURE;
	}

想请教一下可能的错误原因

完整代码如下:

/******************************************************************************
****************主程序
*
******************************************************************************/
#include "DMA.h"
#include <stdio.h>
#include "sys_intr.h"
#include "xparameters.h"

#include "netif/xadapter.h"

#include "platform.h"
#include "platform_config.h"
#if defined (__arm__) || defined(__aarch64__)
#include "xil_printf.h"
#endif

#include "lwip/tcp.h"
#include "xil_cache.h"

/* defined by each RAW mode application */
void print_app_header();
int start_application();
int transfer_data();
void tcp_fasttmr(void);
void tcp_slowtmr(void);

/* missing declaration in lwIP */				
void lwip_init();

XAxiDma axidma;     //XAxiDma实例
XScuGic intc;       //中断生成控制器实例
extern volatile int TcpFastTmrFlag;
extern volatile int TcpSlowTmrFlag;

static struct netif server_netif;
struct netif *echo_netif;



int transfer_data(XAxiDma *DMAPtr) {
	int status;
	if(start_update_flag){
		xil_printf("\r\nStart Waveform Output\r\n");
		xil_printf("waveform size is %lu Bytes\r\n",total_bytes);

		Xil_DCacheFlushRange((UINTPTR) rxbuffer, MAX_PKT_LEN);   //刷锟斤拷Data Cache
		status = XAxiDma_SimpleTransfer(&DMAPtr, (UINTPTR) rxbuffer,
    	MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);
    if (status != XST_SUCCESS) {
        return XST_FAILURE;
    }
		// 	xil_printf("Update DMA Error!\r\n");
		// else
		// 	total_bytes = 0;

	}
	start_update_flag = 0;
	return 0;
}

void
print_ip(char *msg, struct ip_addr *ip) 
{
	print(msg);
	xil_printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip), 
			ip4_addr3(ip), ip4_addr4(ip));
}

void
print_ip_settings(struct ip_addr *ip, struct ip_addr *mask, struct ip_addr *gw)
{

	print_ip("Board IP: ", ip);
	print_ip("Netmask : ", mask);
	print_ip("Gateway : ", gw);
}

int init_intr_sys(){
	DMA_Intr_Init(&axidma,0);						//将ID为0的DMA和DMA实例绑定,并进行初始化
	Init_Intr_System(&intc);
	Setup_Intr_Exception(&intc);
	DMA_Setup_Intr_System(&intc,&axidma,TX_INTR_ID);//setup dma interrpt system
	DMA_Intr_Enable(&intc,&axidma);
}





int main()
{
	struct ip_addr ipaddr, netmask, gw;

	/* the mac address of the board. this should be unique per board */
	unsigned char mac_ethernet_address[] =
	{ 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };

	echo_netif = &server_netif;

	init_platform();
	init_intr_sys();								//系统初始化

	/* initliaze IP addresses to be used */
	IP4_ADDR(&ipaddr,  192, 168,   1, 10);
	IP4_ADDR(&netmask, 255, 255, 255,  0);
	IP4_ADDR(&gw,      192, 168,   1,  1);

	print_app_header();

	lwip_init();

  	/* Add network interface to the netif_list, and set it as default */
	if (!xemac_add(echo_netif, &ipaddr, &netmask,
						&gw, mac_ethernet_address,
						PLATFORM_EMAC_BASEADDR)) {
		xil_printf("Error adding N/W interface\n\r");
		return -1;
	}
	netif_set_default(echo_netif);

	/* now enable interrupts */
	platform_enable_interrupts();

	/* specify that the network if is up */
	netif_set_up(echo_netif);

	ipaddr.addr = echo_netif->ip_addr.addr;
	gw.addr = echo_netif->gw.addr;
	netmask.addr = echo_netif->netmask.addr;

	print_ip_settings(&ipaddr, &netmask, &gw);

	/* start the application (web server, rxtest, txtest, etc..) */
	start_application();

	/* receive and process packets */
	while (1) {
		if (TcpFastTmrFlag) {
			tcp_fasttmr();
			TcpFastTmrFlag = 0;
		}
		if (TcpSlowTmrFlag) {
			tcp_slowtmr();
			TcpSlowTmrFlag = 0;
		}
		xemacif_input(echo_netif);	//将网口的数据送到lwip中
		transfer_data(&axidma);
	}
  
	/* never reached */
	cleanup_platform();

	return 0;
}
/***************************** Include Files与DMA 相关的函数*****************************/
#include "DMA.h"


volatile int tx_done;      //DMA传输中断完成标志位
volatile int error;        //DMA发送出错


void tx_intr_handler(void *callback)
{
    int timeout;
    u32 irq_status;
    XAxiDma *axidma_inst = (XAxiDma *) callback;


    irq_status = XAxiDma_IntrGetIrq(axidma_inst, XAXIDMA_DMA_TO_DEVICE);

    XAxiDma_IntrAckIrq(axidma_inst, irq_status, XAXIDMA_DMA_TO_DEVICE);


    if ((irq_status & XAXIDMA_IRQ_ERROR_MASK)) {
        error = 1;
        XAxiDma_Reset(axidma_inst);
        timeout = RESET_TIMEOUT_COUNTER;
        while (timeout) {
            if (XAxiDma_ResetIsDone(axidma_inst))
                break;
            timeout -= 1;
        }
        return;
    }


    if ((irq_status & XAXIDMA_IRQ_IOC_MASK))
        tx_done = 1;
}

/*****************************************************************************/
/*
*
* This function setups the interrupt system so interrupts can occur for the
* DMA, it assumes INTC component exists in the hardware system.
*
* @param	IntcInstancePtr is a pointer to the instance of the INTC.
* @param	AxiDmaPtr is a pointer to the instance of the DMA engine
* @param	TxIntrId is the TX channel Interrupt ID.
* @param	RxIntrId is the RX channel Interrupt ID.
*
* @return
*		- XST_SUCCESS if successful,
*		- XST_FAILURE.if not succesful
*
* @note		None.
*
******************************************************************************/
int DMA_Setup_Intr_System(XScuGic * int_ins_ptr,XAxiDma * axidma_ptr, u16 tx_intr_id)
{
    int status;
    XScuGic_Config *intc_config;

    //设置DMA发送中断优先级和触发方式
    XScuGic_SetPriorityTriggerType(int_ins_ptr, tx_intr_id, 0xA0, 0x3);

    //设置DMA发送中断服务函数
    status = XScuGic_Connect(int_ins_ptr, tx_intr_id,
            (Xil_InterruptHandler) tx_intr_handler, axidma_ptr);
    if (status != XST_SUCCESS) {
        return status;
    }

    XScuGic_Enable(int_ins_ptr, tx_intr_id);
    return XST_SUCCESS;
}


void disable_intr_system(XScuGic * int_ins_ptr, u16 tx_intr_id,
        u16 rx_intr_id)
{
    XScuGic_Disconnect(int_ins_ptr, tx_intr_id);
}


int DMA_Intr_Init(XAxiDma *DMAPtr,u32 DeviceId)
{
    int status;
    XAxiDma_Config *config=NULL;

    config = XAxiDma_LookupConfig(DeviceId);				//查看该ID对应的硬件设备的硬件信息
    if (!config) {
        xil_printf("No config found for %d\r\n", DMA_DEV_ID);
        return XST_FAILURE;
    }

    //将DMA实例和DMA的硬件信息绑定
    status = XAxiDma_CfgInitialize(DMAPtr, config);
    if (status != XST_SUCCESS) {
        xil_printf("Initialization failed %d\r\n", status);
        return XST_FAILURE;
    }

    if (XAxiDma_HasSg(DMAPtr)) {
        xil_printf("Device configured as SG mode \r\n");
        return XST_FAILURE;
    }

    return XST_SUCCESS;
}

int DMA_Intr_Enable(XScuGic * IntcInstancePtr,XAxiDma *DMAPtr)
{

	/* Disable all interrupts before setup */

	XAxiDma_IntrDisable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,
						XAXIDMA_DMA_TO_DEVICE);
/*
	XAxiDma_IntrDisable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,
				XAXIDMA_DEVICE_TO_DMA);
*/
	/* Enable all interrupts */

	XAxiDma_IntrEnable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,
							XAXIDMA_DMA_TO_DEVICE);
/*
	XAxiDma_IntrEnable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,
							XAXIDMA_DEVICE_TO_DMA);
*/
	return XST_SUCCESS;

}
/************************程序的其他源文件*********************************/

#include <stdio.h>
#include <string.h>
#include "xil_printf.h"
#include "echo.h"
#include "DMA.h"

#include "xaxidma.h"
#include "lwip/err.h"
#include "lwip/tcp.h"
#if defined (__arm__) || defined (__aarch64__)
#include "xil_printf.h"
#endif

int i;

u8 start_update_flag = 0;
//u8 rxbuffer[MAX_FLASH_LEN];		//锟斤拷DMA锟斤拷锟斤拷锟斤拷锟捷碉拷fifo锟侥碉拷址锟斤拷TX_BUFFER_BASE
u8 rxbuffer[MAX_FLASH_LEN];
//u8 *tx_buffer_ptr = (u8 *)TX_BUFFER_BASE;
u32 total_bytes = 0;
struct tcp_pcb *c_pcb;


void print_app_header()
{
	xil_printf("\n\r\n\r-----lwIP TCP wave transfer ------\n\r");
	xil_printf("TCP packets sent to port 7 generate wave through ZYNQ\n\r");
}


err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
                               struct pbuf *p, err_t err)
{
	struct pbuf *q;
//	xil_printf("rxbuffer address:%p\n\r",&tx_buffer_ptr[total_bytes]);
	/* do not read the packet if we are not in ESTABLISHED state */
	if (!p) {
		tcp_close(tpcb);
		tcp_recv(tpcb, NULL);
		return ERR_OK;
	}
	q = p;

	if (q->tot_len == 6 && !(memcmp("update", p->payload, 6))) {
        start_update_flag = 1;
    } else if (q->tot_len == 5 && !(memcmp("clear", p->payload, 5))) {
        start_update_flag = 0;
        total_bytes = 0;
        xil_printf("Clear received data\r\n");
    } else {	
		while (q->tot_len != q->len) {
            memcpy(&rxbuffer[total_bytes], q->payload, q->len);
            total_bytes += q->len;
            q = q->next;
        }
		memcpy(&rxbuffer[total_bytes], q->payload, q->len);
        total_bytes += q->len;
    }
	/* indicate that the packet has been received */
	tcp_recved(tpcb, p->len);

	/* free the received pbuf */
	pbuf_free(p);

	return ERR_OK;
}

err_t accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err)
{
	xil_printf("tcp_server: Connection Accepted\r\n");
	c_pcb = newpcb;
	/* set the receive callback for this connection */
	tcp_recv(c_pcb, recv_callback);

	tcp_arg(c_pcb, NULL);

	return ERR_OK;
}


int start_application()
{
    int status;
	struct tcp_pcb *pcb;
	err_t err;
    XAxiDma_Config *config;

	//tx_buffer_ptr = (u8 *) rxbuffer;		//DMA锟斤拷锟斤拷指锟斤拷指锟斤拷锟轿伙拷锟斤拷锟斤拷

	/* create new TCP PCB structure */
	pcb = tcp_new();
	if (!pcb) {
		xil_printf("Error creating PCB. Out of Memory\n\r");
		return -1;
	}

	/* bind to specified @port */
	err = tcp_bind(pcb, IP_ADDR_ANY, portsever);
	if (err != ERR_OK) {
		xil_printf("Unable to bind to port %d: err = %d\n\r", portsever, err);
		return -2;
	}

	/* we do not need any arguments to callback functions */
	tcp_arg(pcb, NULL);

	/* listen for connections */
	pcb = tcp_listen(pcb);
	if (!pcb) {
		xil_printf("Out of memory while tcp_listen\n\r");
		return -3;
	}

	/* specify callback to use for incoming connections */
	tcp_accept(pcb, accept_callback);

	xil_printf("TCP server started @ port %d\n\r", portsever);

	return 0;
}
  • 写回答

3条回答 默认 最新

  • CSDN专家-黄老师 2021-05-03 18:14
    关注

    将代码做个增减法,先从最小的代码量开始执行,然后再增加,直到出现异常就知道那里出错了

    评论

报告相同问题?

悬赏问题

  • ¥20 limma多组间分析最终p值只有一个
  • ¥15 nopCommerce开发问题
  • ¥15 torch.multiprocessing.spawn.ProcessExitedException: process 1 terminated with signal SIGKILL
  • ¥15 QuartusⅡ15.0编译项目后,output_files中的.jdi、.sld、.sof不更新怎么解决
  • ¥15 pycharm输出和导师的一样,但是标红
  • ¥15 想问问富文本拿到的html怎么转成docx的
  • ¥15 我看了您的文章,遇到了个问题。
  • ¥15 GitHubssh虚拟机连接不上
  • ¥15 装完kali之后下载Google输入法 重启电脑后出现以下状况 且退不出去 桌面消失 反复重启没用
  • ¥15 ESP-IDP-BLE配网连接wifi