Hello,
Would you please help me ?
I am trying to run the LWIP Multicast Receiver application on MicroZed board in Bare Metal mode.
Previously, I tested TCP-IP and UDP-IP cases with success.
Below is the entire code of the multicast application, followed by a screen capture.
Sorry, it's a little bit long.
Please, tell me what's wrong ?
#include <stdio.h>
#include "xscugic.h"
#include <xil_io.h>
#include "netif/xadapter.h"
#include "lwip/udp.h"
#include "xstatus.h"
#include "lwip/err.h"
#include "lwip/igmp.h"
/* missing declaration in lwIP */
extern "C"
{
void lwip_init();
}
/* The instance of the netif Server based on Eth_0 */
static struct netif gs_netifUdpIpMulticastEth_0;
/* The Instance of the Interrupt Controller Driver */
static XScuGic gs_xScuGic;
/* PORT NUMBER */
unsigned int gsc_uiPortNumber(45454);
/* The instance of the udp pcb for multicast */
struct udp_pcb * g_aUdpPcb(0);
// Callback for UDP multicast receiving datagrams
static void UdpReceiverRoutine(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
{
tstruct pbuf * qbuf(p);
tu8 u8NumBufInQueue(1);
printf("Receive datagram
r");
tif (p)
t{
tt// Here, payload is a "C string" with 0 sized
ttprintf("Received datagram frag : 001
r");
tt//printf("Received datagram n: 001 :
r%s
r", (char*) qbuf->payload);
ttfflush(stdout);
ttwhile (qbuf->next != NULL)
tt{
tttprintf("Received datagram frag : %03u
r", (unsigned int)u8NumBufInQueue);
ttt//printf("Received datagram n: %03u :
r%s
r", (unsigned int)u8NumBufInQueue, (char*) qbuf->payload);
tttfflush(stdout);
tttu8NumBufInQueue++;
tt}
ttpbuf_free(p);
t}
}
/****************************************************************************/
/**
* This function sets up the interrupt system. The processing
* contained in this function assumes the hardware system was built with
* and interrupt controller.
*
* @paramtNone.
*
* @returntA status indicating XST_SUCCESS or a value that is contained in
*ttxstatus.h.
*
* @notettNone.
*
*****************************************************************************/
int SetupInterruptSystem(XScuGic * const aXScuGic)
{
t/* Initialize the interrupt controller driver so that it is ready to use.
t */
tXScuGic_Config * const aXScuGic_Config(XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID));
tif (aXScuGic_Config == NULL)
ttreturn XST_FAILURE;
tif (XScuGic_CfgInitialize(aXScuGic, aXScuGic_Config, aXScuGic_Config->CpuBaseAddress) != XST_SUCCESS)
ttreturn XST_FAILURE;
t/* Connect the interrupt controller handler to the hardware
t * interrupt handling logic in the ARM processor
t */
tXil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, aXScuGic);
t/* Initialize the exception table and register the interrupt
t * controller handler with the exception table
t */
tXil_ExceptionInit();
t/* Enable non-critical exceptions in the ARM
t */
tXil_ExceptionEnable();
treturn XST_SUCCESS;
}
/*****************************************************************************/
/**
* Setup multicast configuration
*
* Group addr : 234.6.6.6
* Port : 45454
* MAC software coded but fixed for MicroZed Evaluation Board :
* 00:0a:35:00:01:02
*****************************************************************************/
int SetupUdpIpMulticastEth_0(struct netif * const aNetif)
{
tstruct ip_addr ipaddr, netmask, gw;
tstruct ip_addr ipgroup; // for multicast
terr_t err;
t/*
t * The mac address of the board.
t * !!! Take care with MicroZed board. This should be unique per board
t * */
tunsigned char s_ucMac_EthernetArray[] = {
t 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
t/*
t * Initialize IP addresses to be used
t */
tIP4_ADDR(&ipaddr, 192, 168, 1, 10);
tIP4_ADDR(&netmask, 255, 255, 255, 0);
tIP4_ADDR(&gw, 192, 168, 1, 1);
tIP4_ADDR(&ipgroup, 234, 6, 6, 6);
t/*
t * Initialize the Light Weight Internet Protocol library
t */
t/////////////////////////////////////////////////////////////////////////////
tlwip_init(); // Also calls igmp_init() function
t/////////////////////////////////////////////////////////////////////////////
t/*
t * Add network interface to the netif_list, and set it as default
t *
t * Also calls igmp_start(...) function
t **/
tif (!xemac_add(aNetif, &ipaddr, &netmask, &gw, s_ucMac_EthernetArray,
tXPAR_XEMACPS_0_BASEADDR))
t{
ttprintf("Error adding N/W interface
r");
ttreturn -1;
t}
t//////////////////////////////////////////////////////////////
tnetif_set_default(aNetif);
t//////////////////////////////////////////////////////////////
t/*
t * Set the network up
t */
t//////////////////////////////////////////////////////////////
tnetif_set_up(aNetif);
t//////////////////////////////////////////////////////////////
t/*
t * Create new UDP PCB structure
t */
t//////////////////////////////////////////////////////////////
tg_aUdpPcb = udp_new();
t//////////////////////////////////////////////////////////////
tif (!g_aUdpPcb)
t{
ttprintf("Error creating UDP PCB. Out of Memory
r");
ttreturn -1;
t}
t/*
t * Bind to specified port
t */
t////////////////////////////////////////////////////////////////////////////
terr = udp_bind(g_aUdpPcb, IP_ADDR_ANY, gsc_uiPortNumber);
t////////////////////////////////////////////////////////////////////////////
tif (XST_SUCCESS != err)
t{
ttprintf("Unable to bind to port %d: err = %d
r", gsc_uiPortNumber, err);
ttreturn err;
t}
t////////////////////////////////////////////////////////////////////////////
terr = igmp_joingroup(IP_ADDR_ANY, &ipgroup);
t////////////////////////////////////////////////////////////////////////////
tif (XST_SUCCESS != err)
t{
ttprintf("
rXST_SUCCESS != igmp_joingroup(IP_ADDR_ANY, &ipgroup) : %d
r", err);
ttreturn err;
t}
t/*
t * Start UDP Receiver
t */
t////////////////////////////////////////////////////////////////////////////
tudp_recv(g_aUdpPcb, UdpReceiverRoutine, NULL);
t////////////////////////////////////////////////////////////////////////////
treturn XST_SUCCESS;
}
/******************************************************************************/
/**
* main
*
*******************************************************************************/
//volatile CmsVideoSs::Sap sap;
int main()
{
tint iStatus;
txil_printf("Hello world
r");
t/* Setup the interrupts such that interrupt processing can occur.
t * If an error then exit
t */
txil_printf("SetupInterruptSystem(&gs_xScuGic) : ");
tif (XST_SUCCESS != (iStatus = SetupInterruptSystem(&gs_xScuGic)))
t{
ttxil_printf("FAILED
r");
ttreturn iStatus;
t}
telse
t{
ttxil_printf("PASSED
r");
t}
t/* Setup the UDP Multicast.
t * If an error then exit
t */
txil_printf("SetupUdpIpMulticastEth_0(&gs_netifUdpIpMulticastServerEth_0) : ");
tif (XST_SUCCESS
ttt!= (iStatus = SetupUdpIpMulticastEth_0(&gs_netifUdpIpMulticastEth_0)))
t{
ttxil_printf("FAILED
r");
ttreturn iStatus;
t}
telse
t{
ttxil_printf("PASSED
r");
t}
t// Main loop
twhile (1)
t{
ttxemacif_input(&gs_netifUdpIpMulticastEth_0);
t}
treturn XST_SUCCESS;
}
// SCREEN CAPTURE
Hello world
SetupInterruptSystem(&gs_xScuGic) : PASSED
SetupUdpIpMulticastEth_0(&gs_netifUdpIpMulticastServerEth_0) : igmp_init: initializing
Start PHY autonegotiation
Waiting for PHY to complete autonegotiation.
autonegotiation complete
link speed: 100
pbuf_alloc(length=1518)
pbuf_alloc: allocated pbuf 0x1bc868
pbuf_alloc(length=1518) == 0x1bc868
pbuf_alloc(length=1518)
...
pbuf_alloc: allocated pbuf 0x1a1668
pbuf_alloc(length=1518) == 0x1a1668
pbuf_alloc(length=1518)
pbuf_alloc: allocated pbuf 0x1a0f68
pbuf_alloc(length=1518) == 0x1a0f68
igmp_start: starting IGMP processing on if 0x128238
igmp_lookup_group: allocated a new group with address 224.0.0.1 on if 0x128238
igmp_start: igmp_mac_filter(ADD 224.0.0.1) on if 0x128238
pbuf_alloc(length=42)
pbuf_alloc(length=42) == 0x128840
pbuf_free(0x128840)
pbuf_free: 0x128840 has ref 1, ending here.
pbuf_free: 0x128840 pbuf_free: deallocating 0x128840
igmp_report_groups: sending IGMP reports on if 0x128238
udp_bind(ipaddr = 0.0.0.0, port = 45454)
udp_bind: bound to 0.0.0.0, port 45454
igmp_lookup_group: allocated a new group with address 234.6.6.6 on if 0x128238
igmp_joingroup: join to new group: 234.6.6.6
igmp_joingroup: igmp_mac_filter(ADD 234.6.6.6) on if 0x128238
pbuf_alloc(length=8)
pbuf_alloc(length=8) == 0x128840
pbuf_header: old 0x1288c0 new 0x1288bc (4)
pbuf_header: old 0x1288bc new 0x1288a8 (20)
ip_output_if: te0
IP header:
+-------------------------------+
| 4 | 6 | 0x00 | 32 | (v, hl, tos, len)
+-------------------------------+
| 0 |000| 0 | (id, flags, offset)
+-------------------------------+
| 1 | 2 | 0x0000 | (ttl, proto, chksum)
+-------------------------------+
| 192 | 168 | 1 | 10 | (src)
+-------------------------------+
| 234 | 6 | 6 | 6 | (dest)
+-------------------------------+
netif->output()pbuf_header: old 0x1288a8 new 0x12889a (14)
pbuf_free(0x128840)
pbuf_free: 0x128840 has ref 1, ending here.
pbuf_free: 0x128840 pbuf_free: deallocating 0x128840
PASSED
pbuf_alloc(length=1518)
pbuf_alloc: allocated pbuf 0x1a0868
pbuf_alloc(length=1518) == 0x1a0868
pbuf_alloc(length=1518)
pbuf_alloc: allocated pbuf 0x1a0168
pbuf_alloc(length=1518) == 0x1a0168
pbuf_header: old 0x1bc8c0 new 0x1bc8ce (-14)
ip_input: iphdr->dest 0xff01a8c0 netif->ip_addr 0xa01a8c0 (0x1a8c0, 0x1a8c0, 0xff000000)
ip_input: packet accepted on interface te
ip_input:
IP header:
+-------------------------------+
| 4 | 5 | 0x00 | 36 | (v, hl, tos, len)
+-------------------------------+
| 27014 |000| 0 | (id, flags, offset)
+-------------------------------+
| 128 | 17 | 0x4c8f | (ttl, proto, chksum)
+-------------------------------+
| 192 | 168 | 1 | 100 | (src)
+-------------------------------+
| 192 | 168 | 1 | 255 | (dest)
+-------------------------------+