Ethernet connection becomes unstable if other parts use Timeout

17 Apr 2018

Hi there,

I have a STM32F746 Nucleo-144 board which is connected to another device using the ethernet port. This works well as long as there are no other interrupts used outside of the network code. But it becomes unstable (device connected to the Nucleo stops sending data) as soon as I am using Timeout interrupts.

Best example I came up with

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

EthernetInterface net;
TCPSocket socket;
uint8_t buffer[2048];
Timeout timeout;
Serial serial(USBTX, USBRX);

void connection_setup(const char* ip, const char* subnetMask) {
    net.set_network(ip, subnetMask, "0.0.0.0");
    net.connect();
    socket.set_blocking(false);
}

bool connect(const char* urIp) {
    if(socket.open(&net) != 0) {
        return false;
    }
    if(socket.connect(urIp, 30003) != 0) {
        return false;
    }
    return true;
}

void foo() {
    timeout.attach_us(&foo, 1000);
}

int main() {
    serial.baud(500000);
    wait_ms(100);
    
    serial.printf("Connecting...\n");
    connection_setup("124.100.100.4", "255.255.255.0");
    if(connect("124.100.100.3")) {
        serial.printf("Connected\n");
    }
    else {
        serial.printf("Failed to connect\n");
        return -1;
    }
    
    foo();
    
    int recvCounter = 0;
    while(true) {
        if(socket.recv(buffer, 2048) > 0) {
            serial.printf("Counter: %u\n", recvCounter++);
        }
    }
}

So the function foo() creates an interrupt loop (reattaching if the timeout is triggered. The code works for 30 seconds before the connected device stops its data stream. The data stream is contains 1108 byte packages sent with 125Hz. I have experienced the same issue if the receive buffer runs full - But this should not happen here because the interrupts don't do much and the data should be received fast enough.

I am completely out of ideas - Would appreciate any help. Thanks

21 Apr 2018

Hello Daniel,

When you reattach foo to itself in Timeout ISR you basically mimic a Ticker. So you can achieve the same, but with less overhead, using a Ticker as follows:

...

//Timeout timeout;
Ticker ticker;

...

//void foo() {
//    timeout.attach_us(&foo, 1000);
//}
void foo() {}

...

int main()
{
    ...

    //foo();
    ticker.attach_us(callback(foo), 1000); 
    ...

    while(1)  // this loop is going to be interrupted and foo called 1000 times per second
    {
        ...
    }
}

Does such code stop to run after a while too?