Skip to content

Ticker causes big delays in TCPSocket::recv #5823

Closed
@martinnov71

Description

@martinnov71

Description

  • Type: Bug | Question
  • Priority: Major

Bug

Target
NUCLEOF429ZI

Toolchain:
GCC_ARM

mbed-os
5.6.2, 5.7.1

Expected behavior

  • TCPSocket::recv is consistent in time
  • detaching Ticker should return system to correct function

Actual behavior

  • when Ticker is attached with function that blocks for few us (20 us and more every 1 ms) socket is slowed down
  • this happens after few minutes of function (not more than 2 minutes); until this critical time system works as expected
  • unexpected behavior - reading segments of packet by TCPSocket::recv returns NSAPI_ERROR_WOULD_BLOCK (between segments there are 300 ms and more delays - up to seconds)
  • once critical time is reached, detaching, deleting or attaching Ticker with different options (for example blocks for 1 us every 1 s) doesn't restore system to original state (only way is to restart MCU)

Steps to reproduce

  1. run some TCP server on PC (i.e. SocketTest) on port 61112
  2. compile and run code (IP address should be replaced with your PC IP address)
#include "mbed.h"
#include "EthernetInterface.h"

TCPSocket socket;
EthernetInterface eth;

#define WITH_TICKER 1

void tick_func(){
	wait_us(90);
	return;
}



int main()
{
	eth.connect();
#if WITH_TICKER
	Ticker tick;
	tick.attach(&tick_func,0.001);
#endif
	socket.open(&eth);
	socket.connect("192.168.67.38", 61112);
    char sbuffer[] = "hello!\r\n";
    int scount = socket.send(sbuffer, sizeof sbuffer);
    printf("sent %d [%.*s]\r\n", scount, strstr(sbuffer, "\r\n")-sbuffer, sbuffer);

   	char rbuffer[2048];
	Timer tim;
	bool first=true;

	while(true){

	    int rcount = socket.recv(rbuffer, sizeof rbuffer);
	    if(rcount>0){
	    	if(first){
	    		tim.reset();
	    		tim.start();
	    		first=false;
	    	}
	    	if(rcount != 536){
	    		first=true;
	    		tim.stop();
	    	}
#if WITH_TICKER
	    	if(tim.read_ms() > 300){
	    		printf("detaching\n");
	    		tick.detach();
	    	}
#endif
	    	printf("recv %d in %d\r\n", rcount,tim.read_ms());
	    }else{
	    	Thread::wait(10);
	    }

    }

}
  1. after NUCLEO connects to your TCP server, send some packets (1100 B so there are three segments of data)
  2. after output should be something like this:
sent 9 [hello!]
recv 536 in 0
recv 536 in 1
recv 230 in 2
  1. wait for a while and send the same packet again, now response is following (reading whole packet took more then 300 ms so Ticker was detached):
recv 536 in 0
recv 536 in 9
detaching
recv 230 in 539
  1. send the same packet again to see if detaching helped
  2. you can compile the whole code again with #define WITH_TICKER 0 to see that problem is caused by attached ticker (should not be reproduced)

Note:
Code just simulates real situation (some pin actions in Ticker), I dont want to use any waits in Ticker.


Question

Am I doing something wrong? I can agree that 10% of CPU usage by Ticker function is a little much, but in my opinion deteching Ticker should bring system back to correct state. Next thing I don't understand is that packet read delay starts after 2 mins and not immediately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions