1,vivado搭建
勾选PS网口或者PL网口的配置,并导入SDK,新建lwip例程库,能ping通。
2,sdk环境配置
新建lwip echo server例程,在bsp环境中加入system.mss->modify BSP’s Settings

lwip202->iggmp_options->true
3,main.c
#include
#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\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);
}
#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 // 本地端口
#define UDP_MULTICAST_REMOTE_PORT 8000// 目标端口
#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 1printf( "\nlen : %d , data: %s \n", data_len,udp_recvbuf);
#endif/*记录远程主机地址*/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]);elseprintf("%d \n",(int)remote[i]);}/* 记录远程端口 */printf("remote Port : %d \n ", port);pbuf_free(p);udp_revflag = 1;}else{udp_disconnect(pcb);udp_revflag = 0;}
}
/*
* 组播发送函数 *
*/
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 0err = udp_send(g_udppcb, p );remote_addr[0] = g_udppcb‐>remote_ip.addr && 0xff ;remote_addr[1] = (g_udppcb‐>remote_ip.addr >> 8) &&
0xff ;remote_addr[2] = (g_udppcb‐>remote_ip.addr >> 16) &&
0xff ;remote_addr[3] = (g_udppcb‐>remote_ip.addr >> 24) &&
0xff ;printf("remote_addr : ");for (i = 0 ; i < 4; i++){if (i < 3)printf("%d.",(int)remote_addr[i]);elseprintf("%d \n",(int)remote_addr[i]);}if (err != ERR_OK){printf("udp_send error \n");return ;}
#endifpbuf_free(p);}
}
/* 组播初始化*/
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_IGMPerr = igmp_joingroup(IP_ADDR_ANY , (struct ip_addr*)(&ipgroup));
// 只需要将接收地址放入 igmp 组, 发送的不需要if (ERR_OK != err){printf("LWIP_IGMP err = %d \n", err);return ;}
#endifg_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\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);
print_ip_settings(&ipaddr, &netmask, &gw);
UDP_Multicast();
while (1)
{/* 定时器 定时发送*/if (udp_Flag){printf("start send to 20480 \n");udp_send_hy(data ,6 ,UDP_MULTICAST_REMOTE_PORT);sleep(2);printf("start send to 8000 \n");udp_send_hy(data ,6 , 8000);udp_Flag = 0;}xemacif_input(echo_netif);transfer_data();
}/* never reached */cleanup_platform();return 0;
}
4,关闭 MAC 滤波功能:打开 SDK 工程目录下文件 xemacps.c
在函数 XEmacPs_Reset 中修改:
XEmacPs_SetOptions 函数中添加选项‐——“ XEMACPS_PROMISC_OPTION”至此,组播功能应该可以实现了。
5,配置多端口的组播接收或发送,最多可以开启16路不同的端口号接收和16路不同的端口号发送

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);//6006udp_bind(g_Send_pcb_send2, IP_ADDR_ANY, 6007);//6007udp_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);//8003udp_bind(g_Receive_pcb_4, IP_ADDR_ANY, 8004);//8004udp_bind(g_Receive_pcb_5, IP_ADDR_ANY, 8005);//8005udp_bind(g_Receive_pcb_6, IP_ADDR_ANY, 8006);//8006udp_bind(g_Receive_pcb_7, IP_ADDR_ANY, 8007);//8007udp_bind(g_Receive_pcb_7, IP_ADDR_ANY, 8008);//8008udp_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);
}