udp - 在 lwip ARP 中创建 RAW UDP 连接

标签 udp lwip microblaze

我目前正在努力创建一个简单的以太网传输协议(protocol)。我有一 block SP605 Xilinx 评估板,用于调试项目的以太网部分。我试图蚕食这个例子,但到目前为止还没有成功。目前,通信只需要一种方式。目前,我正在尝试查看使用 netcat 发送的数据。我还打开了wireshark,发现系统卡住了,反复询问:

2217 1323.697811000 Xilinx_00:01:02 广播
ARP 60 谁有192.168.1.11?告诉192.168.1.10

我可以看到主机回复:

2217 1323.697811000 Xilinx_00:01:02 广播
ARP 60 谁有192.168.1.11?告诉192.168.1.10

我觉得我的配置有一些问题,但无法弄清楚它是什么。我认为这可能与没有设置接收处理程序有关,但我不确定。

下面是我正在使用的代码。 lwip_init() 正在模仿 Xilinx 提供的示例中的调用。

    /*
 * main.c
 *
 *  Created on: Sep 24, 2013
 *      Author: Ian
 */
#include <stdio.h>
#include <string.h>

#include <stdio.h>
#include "lwip/init.h"
#include "xparameters.h"
#include "netif/xadapter.h"
#include "xenv_standalone.h"
#include "platform_config.h"
#include "xparameters.h"
#include "xintc.h"
#include "xil_exception.h"
#include "mb_interface.h"
#include "xtmrctr_l.h"
#include "lwip/udp.h"
#include "lwipopts.h"

#include "xil_printf.h"

struct ip_addr ipaddr, ipaddr_remote, netmask, gw;
void udp_test(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);


void print_ip(char *msg, struct ip_addr *ip)
{
    print(msg);
    xil_printf("%d.%d.%d.%d\r\n", 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 main()
{

    err_t error;
    struct netif *netif, server_netif;
    struct udp_pcb *udp_1;
    struct pbuf  *p;
    char data[8] = "01234567";
    u16_t  Port;
    Port = 69;
    int count = 0;
    int n = 0;
    int buflen = 8;

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

    netif = &server_netif;

    xil_printf("\r\n\r\n");
    xil_printf("-----lwIP RAW Application ------\r\n");
    /* initliaze IP addresses to be used */

    IP4_ADDR(&ipaddr_remote,  192, 168,   1, 11);
    IP4_ADDR(&ipaddr,  192, 168,   1, 10);
    IP4_ADDR(&netmask, 255, 255, 255,  0);
    IP4_ADDR(&gw,      192, 168,   1,  1);
    print_ip_settings(&ipaddr, &netmask, &gw);

    lwip_init();

    if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, PLATFORM_EMAC_BASEADDR)) {
        xil_printf("Error adding N/W interface\r\n");
        return -1;
    }
    netif_set_default(netif);

    netif_set_up(netif);

    Xil_ExceptionEnable(); //Setup complete start interrupts


    udp_1 = udp_new();

    error = udp_bind(udp_1, IP_ADDR_ANY, Port);

    if (error != 0)
    {
        xil_printf("Failed %d\r\n", error);
    }
    else if (error == 0)
    {
        xil_printf("Success\r\n");
    }
    error = udp_connect(udp_1, &ipaddr_remote, Port);
    if (error != 0)
    {
        xil_printf("Failed %d\r\n", error);
    }
    else if (error == 0)
    {
        xil_printf("Success\r\n");
    }


while(1)
    {
    count++;
    xemacif_input(netif);
    if (count == 100000)
    {
        p = pbuf_alloc(PBUF_TRANSPORT, buflen, PBUF_POOL);
        if (!p) {
            xil_printf("error allocating pbuf\r\n");
            return ERR_MEM;
        }
        memcpy(p->payload, data, buflen);
        udp_send(udp_1, p);
        xil_printf("SEND\r\n");
        count = 0;
        pbuf_free(p);
    }
    }
    data[1] = '2';
}

最佳答案

好的,基本上这就是我发现的。

我使用 Xilinx xapp1026 时,sp605_AxiEth_32kb_Cache 项目存在问题。它在开始中断时挂起。我无法诊断该项目,但我切换到了 sp605_EthernetLite_32kb_Cache 示例项目。我只能假设 MicroBlaze 中断初始化失败导致 ARP 无法添加并迫使系统重复进入循环。目前尚不清楚为什么 AxiEth 示例中中断无法初始化。

到达这里后,我能够通过剥离提供的系统并使用以下代码来让程序运行:

/*
 * Copyright (c) 2007 Xilinx, Inc.  All rights reserved.
 *
 * Xilinx, Inc.
 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
 * COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
 * ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
 * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
 * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
 * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
 * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
 * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
 * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
 * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

#include <stdio.h>
#include <string.h>
#include "lwip/udp.h"
#include "xparameters.h"
#include "netif/xadapter.h"
#include "platform.h"
#include "platform_config.h"
#include "lwipopts.h"
#ifndef __PPC__
#include "xil_printf.h"
#endif

void print_headers();
int start_applications();
int transfer_data();
void platform_enable_interrupts();
void lwip_init(void);
void tcp_fasttmr(void);
void tcp_slowtmr(void);

#if LWIP_DHCP==1
extern volatile int dhcp_timoutcntr;
err_t dhcp_start(struct netif *netif);
#endif
extern volatile int TxPerfConnMonCntr;
extern volatile int TcpFastTmrFlag;
extern volatile int TcpSlowTmrFlag;

void print_ip(char *msg, struct ip_addr *ip)
{
    print(msg);
    xil_printf("%d.%d.%d.%d\r\n", 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 main()
{
    struct netif *netif, server_netif;
    struct ip_addr ipaddr, netmask, gw;

    // Added stuff for the creation of a basic UDP
    err_t error;
    struct ip_addr ip_remote;
    struct udp_pcb *udp_1;
    struct pbuf  *p;
    char data[8] = "01234567";
    u16_t  Port = 12;
    int buflen = 8;
    int count = 0;

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

    netif = &server_netif;

    if (init_platform() < 0) {
        xil_printf("ERROR initializing platform.\r\n");
        return -1;
    }

    xil_printf("\r\n\r\n");
    xil_printf("-----lwIP RAW Mode Demo Application ------\r\n");
    /* initliaze IP addresses to be used */
#if (LWIP_DHCP==0)
    IP4_ADDR(&ipaddr,  192, 168,   1, 10);
    IP4_ADDR(&netmask, 255, 255, 255,  0);
    IP4_ADDR(&gw,      192, 168,   1,  1);
    print_ip_settings(&ipaddr, &netmask, &gw);
#endif
    lwip_init();

#if (LWIP_DHCP==1)
    ipaddr.addr = 0;
    gw.addr = 0;
    netmask.addr = 0;
#endif

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

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

    /* now enable interrupts */
    platform_enable_interrupts();

#if (LWIP_DHCP==1)
    /* Create a new DHCP client for this interface.
     * Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at
     * the predefined regular intervals after starting the client.
     */
    dhcp_start(netif);
    dhcp_timoutcntr = 24;
    TxPerfConnMonCntr = 0;
    while(((netif->ip_addr.addr) == 0) && (dhcp_timoutcntr > 0)) {
        xemacif_input(netif);
        if (TcpFastTmrFlag) {
            tcp_fasttmr();
            TcpFastTmrFlag = 0;
        }
        if (TcpSlowTmrFlag) {
            tcp_slowtmr();
            TcpSlowTmrFlag = 0;
        }
    }
    if (dhcp_timoutcntr <= 0) {
        if ((netif->ip_addr.addr) == 0) {
            xil_printf("DHCP Timeout\r\n");
            xil_printf("Configuring default IP of 192.168.1.10\r\n");
            IP4_ADDR(&(netif->ip_addr),  192, 168,   1, 10);
            IP4_ADDR(&(netif->netmask), 255, 255, 255,  0);
            IP4_ADDR(&(netif->gw),      192, 168,   1,  1);
        }
    }
    /* receive and process packets */
    print_ip_settings(&(netif->ip_addr), &(netif->netmask), &(netif->gw));
#endif

    /* start the application (web server, rxtest, txtest, etc..) */
   xil_printf("Setup Done");
    IP4_ADDR(&ip_remote,  192, 168,   1, 11);

    udp_1 = udp_new();

    error = udp_bind(udp_1, IP_ADDR_ANY, Port);

    if (error != 0)
    {
        xil_printf("Failed %d\r\n", error);
    }
    else if (error == 0)
    {
        xil_printf("Success\r\n");
    }
    error = udp_connect(udp_1, &ip_remote, Port);
    if (error != 0)
    {
        xil_printf("Failed %d\r\n", error);
    }
    else if (error == 0)
    {
        xil_printf("Success\r\n");
    }


   while (1)
   {
        xemacif_input(netif);
        count++;
        if (count == 80000)
        {
            p = pbuf_alloc(PBUF_TRANSPORT, buflen, PBUF_POOL);
            if (!p) {
                xil_printf("error allocating pbuf\r\n");
                return ERR_MEM;
            }
            memcpy(p->payload, data, buflen);
            udp_send(udp_1, p);
            xil_printf("SEND\r\n");
            count = 0;
            pbuf_free(p);
        }

    }

    /* never reached */
    cleanup_platform();

    return 0;
}

----编辑----

所以你知道人们是如何解决这个问题的,那就不要留下答案。好吧,这是我的原始代码问题(我认为..)代码行 xemacif_input(netif);使以太网能够处理 arp 调用,如果没有它,FPGA 将发送 ARP,然后如果没有接收到它,则会重复询问。

前面的代码似乎确实包含正确的代码行。因此,中断配置方式可能存在错误。

我让这个示例正常工作并在我的项目中实现了它。如果您对此有疑问,请询问,我会尽力给出最好的答案。

关于udp - 在 lwip ARP 中创建 RAW UDP 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19016284/

相关文章:

linux - 什么linux内核代码创建了/sys/devices/system/cpu/cpuX?

c - c中的字符串比较

c - lwIP echo 服务器发送数据时出错

c - lwIP 远程登录示例?

ssl - mbedTLS API 需要进行哪些更改才能与 LWIP 一起使用

c - microblaze 和 vhdl 之间如何通信?

tcp - 数据包丢失和数据包复制

java - 在 UDP 上发送和接收序列化对象

linux - 内核模块中的可靠 UDP

.net - 对象未被垃圾收集