在STM32F7 + FreeRTOS上实现LWIP多播? [英] implementing LWIP multicast on STM32F7 + FreeRTOS?

查看:1042
本文介绍了在STM32F7 + FreeRTOS上实现LWIP多播?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个客户端/服务器LWIP程序,可以与单播通信正常工作,但是我想使用多播功能,所以我使用IGMP库执行以下操作:

I have a client/server LWIP program that works correctly with unicast communication however I want to use multicast features so I used IGMP library did the following:

1-在lwipopts.h中:

1- in lwipopts.h:

#define LWIP_IGMP 1 //allowed IGMP

2-在ethernetif.c中:

2- in ethernetif.c:

netif->flags |= NETIF_FLAG_IGMP; //in low_level_init function

3-在我的源文件中(对于客户端和服务器项目):

3-in my source file (for both client and server projects):

实现了以下代码:

void recCallBack (void)
{
      printf("connected");  //BREAK_POINT
}
static void UDP_Multicast_init(void *arg)
{
   struct ip4_addr ipgroup, localIP;
   struct udp_pcb *g_udppcb;
   char msg[] = "hello";
   struct pbuf* p;
   p = pbuf_alloc(PBUF_TRANSPORT,sizeof(msg),PBUF_RAM);
   memcpy (p->payload, msg, sizeof(msg));

   IP4_ADDR(&ipgroup, 224, 0, 1, 129 ); //Multicast IP address.
   IP4_ADDR(&localIP, 192, 168, 1, 2); //Interface IP address
   #if LWIP_IGMP
      s8_t iret = igmp_joingroup((ip4_addr_t *)(&localIP),(ip4_addr_t *)(&ipgroup));
   #endif
   g_udppcb =( struct udp_pcb*) udp_new();
   udp_bind(g_udppcb, &localIP, 319); //to allow receiving multicast
   udp_recv(g_udppcb, recCallBack,NULL); //recCallBack is the callback function that will be called every time you    receive multicast
   udp_sendto(g_udppcb,p,&ipgroup,319); //send a multicast packet
}

void telnet_shell_init(void)
{
   sys_thread_new("TELNET", UDP_Multicast_init, NULL, DEFAULT_THREAD_STACKSIZE, osPriorityAboveNormal);
}

结果:所有提到的代码步骤都在两个项目(客户端和服务器)中成功执行,但是我没有收到任何多播消息(甚至可能没有发送)!

The result: all the mentioned code steps are executed successfully in both projects (client and server) but I'm not receiving any multicast messages (or maybe not even sending)!

我在回调函数中添加了一个"BREAK_POINT",但从未达到.你能帮助我吗?通过建议一种解决方案或至少一种跟踪问题的方式...我正在使用带有LWIP的STM32F746 Nucleo板,cubeMX生成的FreeRTOS库.

I added a "BREAK_POINT" in the callback function but I never reached it. Can you help me? either by suggesting a solution or at least a way to track the problem... I'm using STM32F746 Nucleo board with LWIP, FreeRTOS libraries generated by cubeMX.

谢谢.

<<<编辑>>> 经过更多调查,我发现问题出在应该在MAC初始化期间启用的多播帧的接收中.尽管以下代码对我不起作用,但对其他人有帮助,因此这里是:

<<< Edit >>> After more investigations I found out that the problem is in the reception of the multi-cast frames which should be enabled during the MAC initialization. Although the following code did not work for me, it was helpful to others so here it is:

stm32f7xx_hal_eth.c中的4-(ETH_MACDMAConfig函数):

4- in the stm32f7xx_hal_eth.c (ETH_MACDMAConfig function):

macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_ENABLE;
macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_NONE;

推荐答案

我的多播测试已使用STM32F407和CubeMX 4.25.0版成功完成. Kalkhouri的问题很有帮助. 我在这里分享我的工作代码.

My multicast testing was finished successfully with STM32F407 and CubeMX version 4.25.0.
The Kalkhouri's question was helpful. I share my working code here.

以下代码必须与Kalkhouri一样包含.

Following code must be included same as Kalkhouri did.

#define LWIP_IGMP 1

macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_NONE;

netif->flags |= NETIF_FLAG_IGMP;

我使用LWIP的套接字API,而不是底层函数.

I used socket API of LWIP rather than low level function.

#include "lwip/opt.h"
#include "lwip/dhcp.h"
#include "lwip/netif.h"
#include "lwip/tcpip.h"
#include "lwip/sockets.h"

int Bind(int sock, uint16_t port)
{
  struct sockaddr_in serv_addr;
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(port);
  if (bind(sock, (struct sockaddr *) &serv_addr, (socklen_t)sizeof(serv_addr)) < 0)
    return -1;
  return 0;
}

int JoinGroup(int sock, const char* join_ip, const char* local_ip)
{
  ip_mreq mreq;
  mreq.imr_multiaddr.s_addr = inet_addr(join_ip);
  mreq.imr_interface.s_addr = inet_addr(local_ip);
  if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0)
    return -1;
  return 0;
}

void  MulticastStart()
{
  int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  Bind(sock, 5000);
  JoinGroup(sock, "224.1.1.1", "192.168.10.123");

  // Now you can do recvfrom() in RTOS task.
  ........
}

注意:您应在RTOS支持下使用此代码.

这篇关于在STM32F7 + FreeRTOS上实现LWIP多播?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆