Author Topic: Receiving UDP packets at a rate of 10ms  (Read 21824 times)

Offline martinh

  • Newbie
  • *
  • Posts: 25
    • View Profile
Receiving UDP packets at a rate of 10ms
« on: November 05, 2014, 02:26:01 PM »
Hi Mark,

I am facing a problem regarding the UDP reception.

So far I have been sending UDP data blocks periodically (from within the main loop) and have been receiving nonperiodic commands per UDP. That is all ok. Nothing to complain.

Now I created an additional socket to receive UDP data periodically from a sensor. The data is sent every 10ms, I could check that with WireShark. The problem is that the listener function is not called at the same interval. Instead it is called for instance 5 times every 100...200µs (1 data packet per call), but the next five data packets are delivered 50ms later. So 5 packets per 50ms is ok if one only looks at the amount of data. It seems that no data gets lost.
Obviously µTasker is optimizing how often the listener function is called.

This is how the socket is obtained:
  scUdpMotionSocket = fnGetUDP_socket(TOS_MINIMISE_DELAY,
    fnUdpMotionListener,
    0                     
    | UDP_OPT_CHECK_CS); 

I thought that the parameter TOS_MINIMISE_DELAY might have something to do with the problem, but the function description says that this parameter is not used. (I am using µTasker V1.4.)

The problem is that I need actual data.
Is there a way to "persuade" µTasker to call that special listener function immediately when data is received, i.e. every 10ms?
Or even better, to call the listener on request. I only need the most recent data package. In that  case it would not matter if 5 packets were sent as a group.


Kind regards,
Martin H.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3240
    • View Profile
    • uTasker
Re: Receiving UDP packets at a rate of 10ms
« Reply #1 on: November 05, 2014, 05:51:45 PM »
Hi Martin

The reception of a UDP packet follows the following path:
1. Rx frame reception causes an interrupt which causes the Ethernet task to be scheduled
2. The Ethernet task runs and handles the IP frame, detecting that it is carring UDP and calls the UDP handling subroutine
3. The UDP handler matches the UDP frame to a port and thus the handling listener, which it calls
4. Your listener function operates
5. On return form the listener handling teh Ethernet task checks whether there are further receptions waiting - either it quits of moves to 2 again.

I would expect the delay between 1 and 4 to be in the tens of us range for your processor family - see http://www.utasker.com/docs/uTasker/uTaskerBenchmarks.PDF showing that a 120MHz K70F120 can receive and echo a 1024 byte UDP payload in less than 100us.

Of course there are possible explanations for slowness, which are as follows:
A) There is a delay between 1 and 2 due to the fact that the processor is performing other task execution and can't yet execute the Ethernet task. The scheduler is co-operative and so if there is a task that runs for a long time it will cause a delay here.
B) Your listener function takes a long time to complete

In both cases, when further receptions arrive they will be queued for the Ethernet task and so it will handle multiple waiting receptions the next time that it can run.

As a simple test I would use the UDP listener to simply signal the frame reception (like toggle an output/LED) but nothing more and (temporarily) remove other tasks that could be slowing the Ethernet scheduling down. You should then be able to prove that essentially the lister can handle each reception individually and with a fast reaction time. Then check how long your listener takes to operate to see whether it is a cause of the slowness. Finally add the other tasks back until you can identify one that is blocking other task scheduling (running for > 10ms for example).

Once identified it is usally quite easy to make an adjustement to optimise the overall behaviour.

Hope you can identify the cause.

Regards

Mark

P.S. Check that your project is using
#define ETHERNET_RELEASE_AFTER_EVERY_FRAME                           // handle only one Ethernet reception frame at a time and allow other tasks to be scheduled in between
since this is the preferred method since 2011 (avoids needing to signal each reception frame with a queue entry). Also there is an optional define to limit the number of frames processed in one go by the Ethernet task:
#define ETHERNET_RELEASE_LIMIT  3                                // allow a maximum of three reception frames to be handled
Neither of they should however cause the behaviour that you are seeing.

Offline martinh

  • Newbie
  • *
  • Posts: 25
    • View Profile
Re: Receiving UDP packets at a rate of 10ms
« Reply #2 on: November 06, 2014, 03:27:30 PM »
Hi Mark,

thanks to your explanation I could solve the problem.
The reason was that I use µTasker in a bit a different way. I manually activate a task and than call uTaskerSchedule() at a time when it cannot interfere with the sampling process for instance.
Now I call uTaskerSchedule() in the mainloop exactly when I need the data and the listener callback function provides the most recent results.

ETHERNET_RELEASE_AFTER_EVERY_FRAME  and ETHERNET_RELEASE_LIMIT do not exist in my version of µTasker.

Thank you very much for your immediate response. That was very helpful!

Kind regards,

Martin

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3240
    • View Profile
    • uTasker
Re: Receiving UDP packets at a rate of 10ms
« Reply #3 on: November 06, 2014, 04:14:27 PM »
Hi Martin

The configuration option is in V1.4.1: http://www.utasker.com/forum/index.php?topic=1285.0

Regards

Mark