Porting FreeRTOS+TCP to Infineon XMC4500 using Tasking compiler

smarklaw wrote on Monday, March 26, 2018:

I am trying to port the FreeRTOS 10.1 latest code to Infineon XMC4500 processor using the Tasking compiler. I used the demo project to start the FreeRTOS succesfully and than added the TCP stack and compiled succesfully. When the task starts its sends out the ARP request with corrupted ARP packets. The IP address is 192.168.0.200. But when the proceesor sends a ARP request in wireshark its shows as 0.209.192.168. If i ping from the PC its not generating the reply and I set the ipconfigREPLY_TO_INCOMING_PINGS in config file. I am using the Infineon Hexagon application kit and the hardware is working fine with DAVE and lwip. I ported the working driver from lwip and using with XMClib, Heap_5 and BufferAllocation_2. The Ethernet packets looks fine but the ARP packets looks corrupted.

I tried the FreeRTOS9 with same setup and the packets are not corrupted but its not responding to the ICMP ping request from the PC. The connection between the PC and the Hexagon kit is direct ethrnet cable. Captured the Wireshark pcapng files and attached to this post. Please let me know how to resolve this problem.

heinbali01 wrote on Monday, March 26, 2018:

Hi Mark,

When the task starts its sends out the ARP request with
corrupted ARP packets.

The IP address is 192.168.0.200. But when the processor sends an
ARP request in wireshark its shows as 0.209.192.168.

It looks to me like the PACKED attribute doesn’t work correctly for your compiler.
Have a look at FreeRTOS_IP_Private.h :

    #include "pack_struct_start.h"
    struct xARP_PACKET
    {
        EthernetHeader_t xEthernetHeader;  /*  0 + 14 = 14 */
        ARPHeader_t xARPHeader;            /* 14 + 28 = 42 */
    }
    #include "pack_struct_end.h"
    typedef struct xARP_PACKET ARPPacket_t;

The above declaration should result in a struct that is 42 bytes long. It is being verified in FreeRTOS_IP.c, in case you have configASSERT() defined.
It looks to me like the compiler has increased the size of xEthernetHeader to 16 bytes.
Can you check that please?

rtel wrote on Monday, March 26, 2018:

Additional info related to Hein’s email:
https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html

smarklaw wrote on Tuesday, March 27, 2018:

Hi Hein’s and Richard,

Thanks for the reply. I was thinking same and veryfied it befroe and the compiler packes to correct size:

FreeRTOS_IPInit
FreeRTOS_IPInit: EthernetHeader_t size: 14
FreeRTOS_IPInit: ARPHeader_t size: 28
FreeRTOS_IPInit: IPHeader_t size: 20

One more think I noticed that in 10.1 the
struct xARP_HEADER
{


uint8_t ucSenderProtocolAddress[ 4 ];


}

is changed from uint32_t to above data type. I think this may be making the compiler behave bad while doing the memcpy. Can you help me on the FreeRTOS 9 not sending reply to the ping command please.

smarklaw wrote on Tuesday, March 27, 2018:

The data type changed from uint32_t to uint8_t array is the problem. After changing back and fixing the packing now it works as version 9 like replying to the incoming ping request with a ICMP packet. But its adding 2 bytes extra in the last. Insted of replying with 74 bytes it sends out 76 bytes now. Need to figure out from where this 2 extra bytes are coming from.

smarklaw wrote on Tuesday, March 27, 2018:

Its look like the low level driver working correct and gets the correct byte but the pxGetNetworkBufferWithDescriptor adds extra bytes. Some time 2 or 4 or 8.

heinbali01 wrote on Wednesday, March 28, 2018:

PS. Have you read this post already? It talks about the +2 byte offset (ipconfigPACKET_FILLER_SIZE) of all Ethernet packets.

The data type changed from uint32_t to uint8_t array is the problem.

We did that because SenderProtocolAddress was positioned at an unaligned address.

After changing back and fixing the packing now it works

I think that many people are curious about the details: what did you change back and how did you fix the packing attribute for the Tasking compiler?

But its adding 2 bytes extra in the last. Instead of replying
with 74 bytes it sends out 76 bytes now.

And is the contents correct, or do you see a 2 bytes inserted at the beginning?

Do you have ipconfigETHERNET_MINIMUM_PACKET_BYTES defined?

Ethernet packets must be at least 60 bytes long. It would surprise me that the minimum in your CPU is set at 76 bytes.

heinbali01 wrote on Thursday, March 29, 2018:

I was thinking same and verified it before and the compiler packs to correct size:

FreeRTOS_IPInit
FreeRTOS_IPInit: EthernetHeader_t size: 14
FreeRTOS_IPInit: ARPHeader_t size: 28
FreeRTOS_IPInit: IPHeader_t size: 20

And does ARPPacket_t get a correct size of 42 bytes?

Do you have configASSERT() defined?

Do you have logging enabled, using the following in FreeRTOSIPConfig.h:

#define ipconfigHAS_PRINTF          1
#define FreeRTOS_printf(X)			serialPrintf X

#define ipconfigHAS_DEBUG_PRINTF    1
#define FreeRTOS_debug_printf(X)	serialPrintf X

Where serialPrintf() is just an example and could look like this:

	extern void serialPrintf( const char *pcFormat, ... );

One more think I noticed that in 10.1 the
struct xARP_HEADER
{

uint8_t ucSenderProtocolAddress[ 4 ];

}

is changed from uint32_t to above data type. I think this may
be making the compiler behave bad while doing the memcpy.

We did see unexpected behaviour with the GCC compiler which were ‘solved’ by either using the -fno-builtin-memcpy or the -mno-unaligned-access compiler option.

In what way is your compiler behaving ‘badly’?

Can you help me on the FreeRTOS 9 not sending reply to the ping
command please.

Try to follow what is happening. Does the PING arrive well? Without a 2-byte offset?
Is it analysed well in FreeRTPS_IP.c ? Does prvProcessICMPPacket() get called? Is an answer being sent?
Are the CRC’s calculated for outgoing packets, either in the library, or by the MAC peripheral?
Please check ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM

smarklaw wrote on Monday, April 02, 2018:

Thanks for your reply and I fixed the problem and its working fine now. I have to disable the Checksum Insertion control in the low level driver. When the stack inserts correct check sum the hardware set it to 0. After disableing this it worked fine but same driver worked fine with lwip with DAVE tools and same hardware.