FreeRTOS+TCP: udp communication

xterra wrote on Friday, September 06, 2019:

Hello,

i have the following configuration:

a) linux system, fix ip adress, opens a socket
b) embedded system with renesas cpu, fix ip adress, opens a socket

goal is to have direct connection of linux system and embedded system (no hub / no switch), but for tests I have a switch to see what is going on in wireshark.

If I use switch, everything is okay!

If I use direct connection (cable), system is not working!
To see, what is going on, I check with a hub…

With hub, I see, that first data after reset of embedded system is not going out (on wireshark), but sendto-function says everything okay, bytes sent!
If I repeat first data, then they will be on wire! After that, following sendtos are on wire!

Why could it be that first sendto doesn´t go out? There is no arp request instead, there is simply nothing!
What does the switch do, that in this case everything is okay?

Do you have any ideas?
Thanks a lot!

Best regards
Wolfgang

heinbali01 wrote on Friday, September 06, 2019:

Hello Wolfgang, could it be that the very first UDP packet will be turned in an ARP request?
You can see that happening in the function vProcessGeneratedUDPPacket(), around the macro iptracePACKET_DROPPED_TO_GENERATE_ARP().

There is a function FreeRTOS_OutputARPRequest() that lets you send an ARP request. It can only be used by the IP-task. I was just about to make that function available to the other tasks as well. I will send you that change by email, so you can use it quickly.

xterra wrote on Friday, September 06, 2019:

Hello Hein,

it seems not to work!

I call FreeRTOS_OutputARPRequest() in IPNetworkEventHook() on Event eNetworkUp
and wait for 250ms:

void IPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
{
if( eNetworkEvent == eNetworkUp )
{
uint32_t ulIPAddress;
ulIPAddress = FreeRTOS_inet_addr_quick(GX_IP_ADR1, GX_IP_ADR2, GX_IP_ADR3, GX_IP_ADR4);
// Arp-Request at once
FreeRTOS_OutputARPRequest(ulIPAddress);
vTaskDelay(pdMS_TO_TICKS(250));
nop();
}

if put a breakpoint after the wait at the nop line and put another breakpoint in prvIPTask(), I come to the nop-line without action in prvIPTask?

heinbali01 wrote on Saturday, September 07, 2019:

Wolfgang, when you call vTaskDelay() within the hook, you bring the IP-task to sleep, so it can not handle any ARP replies.

It would be better to call FreeRTOS_OutputARPRequest() from a normal task. I often make this application hook:

static BaseType_t xHasStarted = pdFALSE;

void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
{
    /* If the network has just come up. */
    if( eNetworkEvent == eNetworkUp )
    {
		/* And this is the first time. */
        if( xHasStarted == pdFALSE )
        {
            xHasStarted = pdTRUE;
            /* Wake up the task, communication can begin. */
            xTaskNotifyGive( xTaskHandle );
        }
    }
}

When the task wakes up, it can issue the ARP request.

heinbali01 wrote on Saturday, September 07, 2019:

I just submitted PR #1197.
With that change, the function FreeRTOS_OutputARPRequest() can be called by the application code as well.

xterra wrote on Monday, September 09, 2019:

I call FreeRTOS_OutputARPRequest() from another task and in direct connection (cable) everything is fine! ARP request is sent out and I get answers!

If I have an hub or switch in between, then it seems, that although eNetworkTxEvent is called in prvIPTask the ARP request is not sent out immediatley?
Do you have any ideas what happens here? Could it be, that hub or switch is delaying arp request or dismissing it?

Thanks a lot!

xterra wrote on Tuesday, September 10, 2019:

I faced another problem where I would like to know how this could be handled:

if we have a direct connection between embedded system and linux system and both devices are powered on at the same time, then freertos/tcp will start-up and call xNetworkInterfaceInitialise().
there will be an autonegotiation and if linux is slower in boot-up there will be a problem…

how does freertos/tcp handle a link-up oder link-down? or a change in negotiation of 100/10mbit, half / duplex?
which function of NetworkInterface driver is freertos/tcp calling to check if link is okay?

xterra wrote on Tuesday, September 10, 2019:

I think our main problem is, that when linux system and embedded system boots up, first the autonegotiated link is 10Mbit/full, embedded system starts with this setting.
Afterwards linux system changes to 100Mbit/full, but freertos/tcp on embedded system is not informed about that and stays on 10Mbit!
The two of them can´t talk to each other…

Do you have any idea who to handle that?

heinbali01 wrote on Wednesday, September 11, 2019:

Wolfgang, the +TCP drivers are always a bit outside the software distribution. They depend heavily on the drivers provided by the chip manufacturers.

First one question: when one party believes it’s 10 Mbps, and the other assumes 100 Mbps, is the Link Status still high?

first the autonegotiated link is 10Mbit/full

Would it be an option to tell you PHY that it may not accept 10 Mbps?

Are you using this generic PHY driver already ?

  • source/portable/NetworkInterface/Common/phyHandling.c
  • source/portable/NetworkInterface/include/phyHandling.h

The PHY Link Status must be monitored regularly. Communication with the PHY can heavily disturb normal data exchange. So what I did is: “as long as data is being received, assume that the PHY status is high”.
Only when no data is received for N seconds, the PHY status shall be polled ( done by xPhyCheckLinkStatus() ).

In the STM32Fx driver you will see:

    if( xPhyCheckLinkStatus( &xPhyObject, xResult ) != 0 )
    {
        /* Something has changed to a Link Status, need re-check. */
        prvEthernetUpdateConfig( pdFALSE );
    }

Meaning: when the Link Status comes up, a new auto-negotiation will be started.
Could you trigger this auto-negotiation in case there is a long data silence?