ZYNQ sdk lwip configures UDP multicast to send and receive data

1, vivado build

Check the configuration of the PS network port or PL network port, and import the SDK, create a new lwip routine library, and it can be pinged.

2. SDK environment configuration

Create a new lwip echo server routine, add system.mss->modify BSP’s Settings in the bsp environment

lwip202->iggmp_options->true

3, main.c

#include <stdio.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"
#if LWIP_DHCP==1
#include "lwip/dhcp.h"
#endif
    #if LWIP_IGMP
#include "lwip/igmp.h"
#endif
#include "sleep.h"
/* defined by each RAW mode application */
void print_app_header();
int start_application();
int transfer_data();
/* missing declaration in lwIP */
void lwip_init();
#if LWIP_DHCP==1
extern volatile int dhcp_timoutcntr;
err_t dhcp_start(struct netif *netif);
#endif
extern volatile int TcpFastTmrFlag;
extern volatile int TcpSlowTmrFlag;
extern volatile int udp_Flag;
volatile int udp_revflag = 0;
static struct netif server_netif;
struct netif *echo_netif;
void print_ip(char *msg, struct ip_addr *ip)
{
print(msg);
xil_printf("%d.%d.%d.%d\\
\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);
}
#if defined (__arm__) || defined(__aarch64__)
#if XPAR_GIGE_PCS_PMA_SGMII_CORE_PRESENT == 1 ||
XPAR_GIGE_PCS_PMA_1000BASEX_CORE_PRESENT == 1
int ProgramSi5324(void);
int ProgramSfpPhy(void);
#endif
#endif
#define UDP_MULTICAST_LOCAL_PORT 8000 // local port
#define UDP_MULTICAST_REMOTE_PORT 8000// target port
#define UDP_RX_BUFFSIZE 1000
char udp_recvbuf[UDP_RX_BUFFSIZE];
static struct ip_addr ipgroup;
static struct udp_pcb *g_udppcb;
void udp_recv_hy(void *arg, struct udp_pcb *pcb, struct pbuf *p,
struct ip_addr *addr ,u16_t port)
{
     u16 data_len = 0;
     u32 remote[4] = {0};
     int i = 0;
     if (p != NULL)
     {
      memset(udp_recvbuf, 0, UDP_RX_BUFFSIZE);
        if (p->len > UDP_RX_BUFFSIZE )
       {
          memcpy(udp_recvbuf, p->payload,UDP_RX_BUFFSIZE);
          data_len = UDP_RX_BUFFSIZE;
        }
        else
        {
          memcpy(udp_recvbuf, p->payload, p->len);
          data_len = p‐>len;
        }
#if 1
       printf( "\\
len : %d , data: %s \\
", data_len,udp_recvbuf);
#endif
      /* record the remote host address */
      remote[0] = addr->addr & 0xff;
      remote[1] = (addr‐>addr >> 8) & 0xff;
      remote[2] = ( addr‐>addr >> 16 ) & 0xff;
      remote[3] = ( addr‐>addr >> 24) & 0xff;
      printf("remote IP : ");
      for (i = 0 ; i < 4; i ++ )
      {
        if (i < 3)
          printf("%d.",(int)remote[i]);
        else
          printf("%d \\
",(int)remote[i]);
      }
      /* record the remote port */
      printf("remote Port : %d \\
 ", port);
      pbuf_free(p);
      udp_revflag = 1;
     }
     else
     {
      udp_disconnect(pcb);
      udp_revflag = 0;
     }
}
/*
* Multicast sending function *
*/
void udp_send_hy(unsigned char *data, unsigned short len, u16 port)
{
    err_t err;
    struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
    unsigned char *data2 = "hello";
      u32 remote_addr[4] = { 0 };
      int i ;
    if (p)
    {
     memcpy(p‐>payload, data, len);
    err = udp_sendto(g_udppcb, p , &ipgroup, port );
#if 0
     err = udp_send(g_udppcb, p );
     remote_addr[0] = g_udppcb->remote_ip.addr & amp; & amp; 0xff ;
     remote_addr[1] = (g_udppcb‐>remote_ip.addr >> 8) & amp; & amp;
0xff;
     remote_addr[2] = (g_udppcb‐>remote_ip.addr >> 16) & amp; & amp;
0xff;
     remote_addr[3] = (g_udppcb‐>remote_ip.addr >> 24) & amp; & amp;
0xff;
    printf("remote_addr : ");
    for (i = 0 ; i < 4; i ++ )
    {
     if (i < 3)
       printf("%d.",(int)remote_addr[i]);
     else
       printf("%d \\
",(int)remote_addr[i]);
    }
     if (err != ERR_OK)
     {
       printf("udp_send error \\
");
       return;
     }
#endif
     pbuf_free(p);
    }
}
/* Multicast initialization */
void UDP_Multicast(void)
{
       char msg[] = "gaurav";
       err_t err;
         struct pbuf *p;
          p = pbuf_alloc(PBUF_TRANSPORT, sizeof(msg),PBUF_RAM);
          memcpy(p->payload, msg, sizeof(msg));
          IP4_ADDR( &ipgroup, 239, 0, 1, 2);
#if LWIP_IGMP
      err = igmp_joingroup(IP_ADDR_ANY , (struct ip_addr*)( &ipgroup));
// Only need to put the receiving address into the igmp group, not the sending one
      if (ERR_OK != err)
      {
     printf("LWIP_IGMP err = %d \\
", err);
     return;
      }
#endif
       g_udppcb = (struct udp_pcb*)udp_new();
       udp_bind(g_udppcb, IP_ADDR_ANY, UDP_MULTICAST_LOCAL_PORT);
       udp_recv(g_udppcb, udp_recv_hy, NULL);
}
int main()
{
unsigned char str[6]="hello";
unsigned char *data=str;
#if __aarch64__
Xil_DCacheDisable();
#endif
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;
#if defined (__arm__) || defined(__aarch64__)
#if XPAR_GIGE_PCS_PMA_SGMII_CORE_PRESENT == 1 || XPAR_GIGE_PCS_PMA_1000BASEX_CORE_PRESENT == 1
ProgramSi5324();
ProgramSfpPhy();
#endif
#endif
init_platform();
/* 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);
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\\
\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);
print_ip_settings( &ipaddr, &netmask, &gw);
UDP_Multicast();
while (1)
{
    /* Timer send regularly */
    if (udp_Flag)
    {
           printf("start send to 20480 \\
");
           udp_send_hy(data,6,UDP_MULTICAST_REMOTE_PORT);
           sleep(2);
           printf("start send to 8000 \\
");
           udp_send_hy(data,6,8000);
           udp_Flag = 0;
    }
      xemacif_input(echo_netif);
      transfer_data();
}
     /* never reached */
     cleanup_platform();
     return 0;
}

4. Turn off the MAC filtering function: open the file xemacps.c in the SDK project directory
Modify in function XEmacPs_Reset:
Add options in the XEmacPs_SetOptions function–“XEMACPS_PROMISC_OPTION” So far, the multicast function should be realized.

5. Configure multi-port multicast receiving or sending, and you can open up to 16 different port numbers for receiving and 16 different port numbers for sending

 uint32_t SendAddr[4] = {226, 0, 0, 22};
g_Send_Computer.addr = (SendAddr[3]<<24) + (SendAddr[2]<<16) + (SendAddr[1]<<8) + (SendAddr[0]);
   igmp_joingroup(IP_ADDR_ANY, &g_Send_Computer);
    g_Send_pcb_send1 = udp_new();
    g_Send_pcb_send2 = udp_new();
    g_send_pcb_send3 = udp_new();
    g_send_pcb_send4 = udp_new();
    g_send_pcb_send5 = udp_new();
    g_send_pcb_send6 = udp_new();
    g_send_pcb_send7 = udp_new();

    g_Receive_pcb_1 = udp_new();
    g_Receive_pcb_2 = udp_new();
    g_Receive_pcb_3 = udp_new();
    g_Receive_pcb_4 = udp_new();
    g_Receive_pcb_5 = udp_new();
    g_Receive_pcb_6 = udp_new();
    g_Receive_pcb_7 = udp_new();
    g_Receive_pcb_8 = udp_new();
   
    udp_bind(g_Send_pcb_send1, IP_ADDR_ANY, 6006);//6006
    udp_bind(g_Send_pcb_send2, IP_ADDR_ANY, 6007);//6007
    udp_bind(g_send_pcb_send3, P_ADDR_ANY, 6008);
     udp_bind(g_send_pcb_send4, IP_ADDR_ANY, 6009);
     udp_bind(g_send_pcb_send5, IP_ADDR_ANY, 6010);
     udp_bind(g_send_pcb_send6, IP_ADDR_ANY, 6011);
     udp_bind(g_send_pcb_send7, IP_ADDR_ANY, 6012);

    udp_bind(g_Receive_pcb_1, IP_ADDR_ANY, 8001);
    udp_bind(g_Receive_pcb_2, IP_ADDR_ANY, 8002);
    udp_bind(g_Receive_pcb_3, IP_ADDR_ANY, 8003);//8003
    udp_bind(g_Receive_pcb_4, IP_ADDR_ANY, 8004);//8004
    udp_bind(g_Receive_pcb_5, IP_ADDR_ANY, 8005);//8005
    udp_bind(g_Receive_pcb_6, IP_ADDR_ANY, 8006);//8006
    udp_bind(g_Receive_pcb_7, IP_ADDR_ANY, 8007);//8007
    udp_bind(g_Receive_pcb_7, IP_ADDR_ANY, 8008);//8008
     


    udp_recv(g_Receive_pcb_1, (udp_recv_fn)udp_frame_rev_com0, NULL);
    udp_recv(g_Receive_pcb_2, (udp_recv_fn)udp_frame_rev_com1, NULL);
    udp_recv(g_Receive_pcb_3, (udp_recv_fn)udp_frame_rev_com2, NULL);
    udp_recv(g_Receive_pcb_4, (udp_recv_fn)udp_frame_rev_com3, NULL);
    udp_recv(g_Receive_pcb_5, (udp_recv_fn)udp_frame_rev_com4, NULL);
    udp_recv(g_Receive_pcb_6, (udp_recv_fn)udp_Receive_frame_com5, NULL);
    udp_recv(g_Receive_pcb_7, (udp_recv_fn)udp_Receive_frame_com6, NULL);
    udp_recv(g_Receive_pcb_8, (udp_recv_fn)udp_Receive_frame_com7, NULL);

     Send_udp_zubo(p_sendImageToPC, g_send_pcb_test4_between_missile, pp, 8001, len);

void Send_udp_zubo(struct pbuf* p_sendTopc, struct udp_pcb* pcb, unsigned char* pData, unsigned short port, unsigned int len)
{ p_sendTopc->len = len;
   p_sendTopc->tot_len = len;
   p_sendTopc->payload = pData;
   udp_sendto(pcb, p_sendTopc, &g_Send_Computer_ipAddr, port);
}

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge Network skill treeHome pageOverview 33320 people are studying systematically