FreeRTOS+TCP (Labs)

rtel wrote on Tuesday, February 24, 2015:

We have it running on several microcontrollers but the core code is the same on all targets, only the port layer is different.

Tested with 3 different dhcp servers.

Is it possible your MTU is set to small to hold the DHCP packet?

Regards.

heinbali01 wrote on Tuesday, February 24, 2015:

In Pascal’s case, the DHCP reply has around 590 bytes. Could that have been too many?

If there is enough RAM, I would set MTU at 1500:

`#define ipconfigNETWORK_MTU ( 1500 )`

The largest message will then be 1514 bytes (14 bytes of ethernet header).
The Maximum Segment Size will then be 1460.

Remember that if a message is supposed to travel through the Internet, the size must be smaller, use for instance MSS = 1400. This value can be set per socket, by calling FreeRTOS_setsockopt(). There is no need to change ipconfigNETWORK_MTU for this.

This week I’m also working with the STM32F407 and +TCP.

Regards.

heinbali01 wrote on Wednesday, February 25, 2015:

… I am a bit stuck with getting the Zero-Copy method going
While experimenting with the more advanced Zero-Copy mechanism

A note about TCP, UDP and Zero-Copy:

The idea of Zero-Copy is simply said: “Avoid the use of MEMCPY”. The advantage is an increased speed, lower memory use and less power consumption.
Disadvantages of Zero-Copy may be an increased complexity and less portability of the source code (non BSD-compatible extensions).

When +TCP was being developed (and also earlier while developing +UDP), all possibilities were studied to avoid the use of MEMCPY.

These optimisations have been realised:

  • For UDP recv: call FreeRTOS_recvfrom() with the FREERTOS_ZERO_COPY flag and receive a pointer to a network buffer. It must be freed after reception.

  • For UDP send: create a network buffer, fill it, call FreeRTOS_sendto() with the FREERTOS_ZERO_COPY flag, and have it passed straight to the DMA descriptors for transmission.

  • For TCP recv: call FreeRTOS_recv() with the FREERTOS_ZERO_COPY flag and receive a pointer to the internal RX stream. It must be released in a separate call.

  • For TCP send: The Zero-Copy flag is ignored.

  • For NIC recv: the DMA RX descriptors can have memory pointers to (the payloads of) network buffers.

  • For NIC send: the send routine can pass the payload buffers straight to DMA (in stead of first copying their contents.

It was surprising to see how these optimisations work-out on different platforms, boards.

The efficiency of using Zero-Copy mostly depends on the type of RAM used. If RAM is on a 32-bit bus, MEMCPY can be (should be) really fast*. I was not able the demonstrate the advantages of Zero-Copy on such boards.

If RAM has 16- or 8-bit access, or if the amount of RAM is small, then it is worthwhile to think about using Zero-Copy.

  • The speed of memcpy for 32-bit access: if a CPU has a clock of 100MHz, it can memcpy() between 50 and 150 MByte per second.
    For 16- or 8-bit memory: memcpy would do 22 MB/sec or less per 100 Mhz clock speed.

On a STM32F0xx running on 168 MHz and using internal SRAM, Zero-Copy is probably not going to bring much performance gain. Copying a full-sized frame will last less than 10 uS.

Regards.

pascal-vehigy wrote on Friday, February 27, 2015:

Thank you for elaborating on the zero-copy mechanism for STM32F4 controllers. Due to my sysclock being 150MHz and the fact that portability is a factor, I have decided to not pursue this any further.

Concerning the DHCP issue, it has resolved itself by playing around with some FreeRTOSIPConfig.h settings. Unfortunately I didn’t pinpoint the exact setting which caused the problem, which leads me to suspect that several settings were off. For the record and for other people running into similar issues, my MTU is now set to 1400. DHCP is working, the device is ping-able by host-name and an HTTP server is running as well.

I cannot thank you enough for your great support!

Regards,
Pascal

cca1234 wrote on Thursday, July 30, 2015:

Maybe i just haven’t found it yet, but is there any leaning one way or the other as to how this will eventually be resolved? before we saw this post we played with the “_packed” with our keil compiler for a little while but then just used the attribute((packed)) in the end file since keil is happy enough with that and pre- processor list file looked like the attribute was being implemented OK. i just didn’t want to modify a bunch of code if the next release will be handled differently or if the attribute _((packed)); in the end file is the final solution.

thanks

rtel wrote on Friday, July 31, 2015:

Sorry - this is quite a long thread, so I’m not 100% sure which issue you are wanting resolved. If it is something to do with DHCP then we have done quite a lot of development there (and those developments should have been released some weeks ago, but will be soon!) so we can let you know what has changed.