7 years, 3 months ago.

UDP recfrom not working with Thread

Hello,

Encountered problem running receive messages function for UDP class in thread. Board: Nucleo767ZI Listens to broadcast messages to specified PORT

UDP receive program

#include "mbed.h"
#include "lwip-interface/EthernetInterface.h"

const int PORT = 1234;
Thread udpReceive;

void udpReceiver()
{
	UDPSocket rd_sock(&eth);
    SocketAddress rd_addr;

   char buffer[256];

    Thread::wait(1);
    //bind to specific receiving port
    int bind = rd_sock.bind(PORT);

    
    int countret = 0;

    while(true){
    	
    	int ret = rd_sock.recvfrom(&rd_addr , buffer, sizeof(buffer));
    	//if recv successful, message is saved 
    	if(ret > 0){
    		buffer[ret] = '\0';
    		if(countret == 100){
    			led1 = !led1;
    			countret = 0;
    		}
    		else{
    			countret++;
    		}
    	}    	
    	else{
    		led1 = 1;
    	}
    }
}

int main(){
	

    eth.connect();

    udpReceive.start(udpReceiver);
    
while(1)
{
}
 
}

Getting 2 erros. 1.Getting -3005 error, what means socket is not available. Sometimes restart helps. 2. Program runs, but never receives messages.

Can somebody share documentation for beginner about Threads idea and mbed Thread idea? Not API documentation.

May be somebody have same problem and know how to fix it?

Regards, Daniel

1 Answer

7 years, 2 months ago.

All Mbed code always runs in a thread (the main function just runs in it's own thread), so there is nothing special about threading... I've tried the following code and it works 100% fine on my FRDM-K64F board (I don't have your board unfortunately):

#include "mbed.h"
#include "EthernetInterface.h"

NetworkInterface* network;

void udp_listen() {
    UDPSocket socket;
    int rv;
    rv = socket.open(network);
    printf("Open was %d\n", rv);
    rv = socket.bind(1234);
    printf("Bind was %d\n", rv);

    while (1) {
        SocketAddress addr;
        uint8_t recv_buffer[129] = { 0 };

        nsapi_size_or_error_t r = socket.recvfrom(NULL, recv_buffer, sizeof(recv_buffer) - 1);
        printf("recvfrom returned %d\n", r);

        if (r > 0) {
            printf("Data:\n%s\n\n", recv_buffer);
        }
    }
}

int main()
{
    EthernetInterface eth;
    eth.connect();

    network = ð
    printf("IP address is %s\n", network->get_ip_address());

    Thread udpReceiveThread;
    udpReceiveThread.start(&udp_listen);

    wait(osWaitForever);
}

I'm sending data to the board via netcat:

$ nc -u 192.168.2.143 1234

# then just type data

Accepted Answer

Thank you for answer. I found fix for my problem with putting Thread::wait(1); if initialization is not successful, because of using interrupts. Not sure if it is fully save to use Interrupts.

Also is it going to work with Static IP or zeroconfig(autoconfig) ?

posted by Daniel Klioc 27 Sep 2017

Are you initializing the network stack in an interrupt context, or do you mean something else? Some example code around that would be useful to determine if it's safe or not.

Both DHCP and static IPs work fine. Not sure about zeroconfig support.

posted by Jan Jongboom 28 Sep 2017

I am initializing network stack in thread and using interrupts for other peripherals.

posted by Daniel Klioc 28 Sep 2017

OK, make sure to not do any network operations in the ISR, always yield back to a normal thread (using Semaphore or mbed-events).

posted by Jan Jongboom 28 Sep 2017