开发环境介绍:
MCU:STM32F407ZET6
网卡:LAN8720A
LWIP版本:V1.1.0
FreeRTOS 版本:V10.2.1
LAN8720A硬件原理图:
硬件连接说明:
MII_RX_CLK/RMII_REF_CLK ------>PA1 MII_TXD0 ------>PB12MII_MDIO ------>PA2 MII_TXD1 ------>PB13MII_RESET ------>PA3 MII_MDC ------>PC1MII_RX_DV/RMII_CRSDV ------>PA7 MII_RXD0 ------>PC4MII_RX_ER ------>PB10 MII_RXD1 ------>PC5MII_TX_EN ------>PB11
Lwip组播配置:
上图中创建了一个10ms的循环定时器,定时器回调函数为: LwipTimCallBack
void LwipTimCallBack(TimerHandle_t xTimer)
{
uint32_t LocaTime = xTaskGetTickCount();
LwIP_Periodic_Handle(LocaTime);
}
netconf.c--->void LwIP_Periodic_Handle(volatile uint32_t localtime)内添加igmp计时器调用算法
ethernetif.c--->static void low_level_init(struct netif *netif)添加
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
在stm32f429_phy.c---->static void ETH_MACDMA_Config(void)方法中进行以下设置:
组播接收消息设置:
接收消息使用的是8081端口,发送消息使用的是8080端口。组播地址239.0.0.1。客户端设置可参考另一篇文章:QT学习笔记_UDP组播通信(加入组播)_qt 实现udp通信工程文件添加什么-CSDN博客
static void MulticastRxTask(void *pcParameter)
{uint32_t NotifyValue = 0;UBaseType_t uxHighWaterMark;struct netconn *udpconn;udpconn = netconn_new(NETCONN_UDP);ip_addr_t destipaddr;IP4_ADDR(&destipaddr,239,0,0,1);netconn_bind(udpconn,IP_ADDR_ANY,8081);netconn_join_leave_group(udpconn,&destipaddr,IP_ADDR_ANY,NETCONN_JOIN);uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);while(1){struct netbuf *recebuf;if(netconn_recv(udpconn,&recebuf) == ERR_OK)//会自己阻塞{uint16_t ReceByteCount = recebuf->p->len;uint8_t *pData = recebuf->p->payload;if((pData[0] == 0xAA &&pData[1] == 0xBB))memcpy((void *)MulticastBuf,(void *)pData,ReceByteCount);netbuf_delete(recebuf);}uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );}
}
组播发送消息:
void MulticastTxTask(void *pvParameter)
{struct netconn *udpconn;udpconn = netconn_new(NETCONN_UDP);netconn_bind(udpconn, IP_ADDR_ANY, 8080);ip_addr_t ipMultiCast;IP4_ADDR(&ipMultiCast, 239, 0, 0, 1);netconn_connect(udpconn,&ipMultiCast,8080);for(;;){uint32_t NotifyValue = 0;struct netbuf *sendbuf = netbuf_new();xTaskNotifyWait(ULONG_MAX,ULONG_MAX,&NotifyValue,portMAX_DELAY);switch(NotifyValue){//组桢MulticastRxStruct.ReceLen =MakeUpInfoBack(0x3031,MulticastRxStruct.Data);break;default:break;}netbuf_alloc(sendbuf,MulticastRxStruct.ReceLen);netbuf_ref(sendbuf,MulticastRxStruct.Data,MulticastRxStruct.ReceLen);//发送指定长度字符串netconn_send(udpconn,sendbuf);//发送报文netbuf_delete(sendbuf);}
}