簡體   English   中英

如何使用 LWIP 和 FreeRTOS 讓多播在 stm32f7 上工作

[英]How to get multicast to work on stm32f7 with LWIP and FreeRTOS

嗨,我正在嘗試使用 LWIP 和 FreeRTOS 在 STM32f7(NucleoF767zi 板)上啟動並運行 UDP 多播套接字。

我已經實現了 LWIP 和 FreeRTOS 中間件,它似乎工作正常。 我還設置了一個 windows 程序,它將多播消息發送到 239.192.0.4 端口 60003,並在我的網絡上的其他設備上測試了消息可以正常接收。 但是當我使用 STM32f7 處理器時,一切似乎都工作正常,但它沒有收到任何東西。

我使用從類似指南中找到的這段代碼加入多播組,並且在調試代碼時沒有出錯:

int Bind(int sock, uint16_t port) {
    //struct sockaddr_in serv_addr;
    memset((char*) &serv_addr, 0, sizeof(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) {
    ip_mreq mreq;
    mreq.imr_multiaddr.s_addr = inet_addr(join_ip);
    ip4_addr_t localAddress = MX_LWIP_Get_IP();//Gets the local IP interface address
    mreq.imr_interface.s_addr = localAddress.addr;
    ;
    if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mreq,
            sizeof(mreq)) < 0)
        return -1;
    return 0;
}

int MulticastStart() {
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    int reuse = 1;
/* Dont know if SO_REUSEADDER is nenecessary doesn't seem to make a difference*/
    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse,
            sizeof(reuse)) < 0) {
        perror("Setting SO_REUSEADDR error");
    } else
        printf("Setting SO_REUSEADDR...OK.\n");

    Bind(sock, 60003);
    JoinGroup(sock, "239.192.0.4");
    return sock;
    // Now you can do recvfrom() in RTOS task.
}

然后我有一個 FreeRTOS 任務,我嘗試打印從 recvfrom() 接收到的數據,但 recvfrom() 仍然被阻止,就像它從未收到任何東西一樣。 此外,當我可以看到我的其他設備接收到來自多播組的消息時,就好了。

void StartLWIPReceiverTask(void const *argument) {
    osSemaphoreWait(LWIPsemaphore, osWaitForever); // Wait indefinitely for a free semaphore
    int sock = MulticastStart();
    char test[256];
    memset(&test, 0, sizeof(test));
    int addrlen = sizeof(serv_addr);
    /* Infinite loop */
    for (;;) {
        int nbytes = recvfrom(sock, test, 255, 0,
                (struct sockaddr* ) &serv_addr, (socklen_t* )&addrlen);
        if (nbytes > 0) {
            HAL_UART_Transmit(&huart3, (uint8_t*) test, (uint16_t) strlen(test),
                    1000);
            memset(&test, 0, sizeof(test));
        }
        osDelay(1);
    }
}

我設置了以下標志:在 lwipopts.h 中:

#define LWIP_IGMP 1

#define LWIP_IPV4 1

#define LWIP_SOCKET 1

#define LWIP_UDP 1

#define SO_REUSE 1 

在 ethernetif.c 中:

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

在 stm32f7xx_hal_eth.c 中:

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

我沒有收到任何錯誤,所以我很迷茫,在這一點上會很感激任何提示。

如果其他人遇到這個問題,我通過創建一個新項目並復制代碼並在相同的文件中設置相同的標志來解決它。 不知道為什么它現在有效,但如果有效,它就有效:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM