Trouble porting TCP project to 202104.00

I have a TCP project that works fine under V10.2.0, but won’t build under 202104.00. (I have successfully ported non-TCP projects for my board.)

Based on the messages gelow, it seems to be a problem with FreeRTOS_TCP_IP.h and/or FreeRTOS_IP_Private.h.

Any thoughts would be greatly appreciated!

[...]

"C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-gcc.exe" -g -x c -c -mprocessor=32MX795F512L -D_SUPPRESS_PLIB_WARNING -I../ -I../../../FreeRTOS/Source -I../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP -I../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement -I../../../FreeRTOS/Source/portable/MemMang -I../../../FreeRTOS/Source/portable/MPLAB/PIC32MX -I../../../FreeRTOS/Source/include -I../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include -I../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC -I../../../FreeRTOS/Source/portable/MPLAB/PIC32MX -I../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include -MMD -MF build/default/production/_ext/1472/chipKIT_PRO_MX7.o.d -o build/default/production/_ext/1472/chipKIT_PRO_MX7.o ../chipKIT_PRO_MX7.c -DXPRJ_default=default 
"C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-gcc.exe" -g -x c -c -mprocessor=32MX795F512L -D_SUPPRESS_PLIB_WARNING -I../ -I../../../FreeRTOS/Source -I../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP -I../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement -I../../../FreeRTOS/Source/portable/MemMang -I../../../FreeRTOS/Source/portable/MPLAB/PIC32MX -I../../../FreeRTOS/Source/include -I../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include -I../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC -I../../../FreeRTOS/Source/portable/MPLAB/PIC32MX -I../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include -MMD -MF build/default/production/_ext/1472/main.o.d -o build/default/production/_ext/1472/main.o ../main.c -DXPRJ_default=default 
nbproject/Makefile-default.mk:423: recipe for target 'build/default/production/_ext/1472/main.o' failed
make[2]: Leaving directory 'D:/443/tmp/FreeRTOSv202104.00/FreeRTOSv202104.00/Projects/tcp_adc - Copy/tcp_adc.X'
nbproject/Makefile-default.mk:90: recipe for target '.build-conf' failed
make[1]: Leaving directory 'D:/443/tmp/FreeRTOSv202104.00/FreeRTOSv202104.00/Projects/tcp_adc - Copy/tcp_adc.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
In file included from ../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h:41:0,
                 from ../main.c:46:
../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h:33:69: error: expected ')' before '*' token
In file included from ../main.c:46:0:
../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h:84:9: error: expected specifier-qualifier-list before 'MACAddress_t'
In file included from ../main.c:46:0:
../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h:110:9: error: expected specifier-qualifier-list before 'MACAddress_t'
In file included from ../main.c:46:0:
../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h:424:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'xBroadcastMACAddress'
../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h:577:69: error: expected ')' before '*' token
../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h:831:64: error: expected ')' before '*' token
../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h:848:58: error: expected ')' before '*' token
../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h:931:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h:940:35: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
../main.c:204:6: error: conflicting types for 'vApplicationStackOverflowHook'
../../../FreeRTOS/Source/include/task.h:1616:11: note: previous declaration of 'vApplicationStackOverflowHook' was here
../main.c: In function 'prvServerConnectionInstance':
../main.c:369:27: error: 'ipSIZE_OF_IPv4_HEADER' undeclared (first use in this function)
../main.c:369:27: note: each undeclared identifier is reported only once for each function it appears in
../main.c:369:27: error: 'ipSIZE_OF_TCP_HEADER' undeclared (first use in this function)
../main.c: In function 'prvServerConnectionInstance2':
../main.c:440:27: error: 'ipSIZE_OF_IPv4_HEADER' undeclared (first use in this function)
../main.c:440:27: error: 'ipSIZE_OF_TCP_HEADER' undeclared (first use in this function)
make[2]: *** [build/default/production/_ext/1472/main.o] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2

BUILD FAILED (exit value 2, total time: 7s)

Seems like you are including FreeRTOS_IP_Private.h from main.c. Can you try including FreeRTOS_IP.h before FreeRTOS_IP_Private.h which defines ipSIZE_OF_IPv4_HEADER: FreeRTOS-Plus-TCP/FreeRTOS_IP.h at main · FreeRTOS/FreeRTOS-Plus-TCP · GitHub

For the second error, what is the definition of vApplicationStackOverflowHook in main.c?

Thanks.

Many thanks Gaurav! Including FreeRTOS_IP.h before FreeRTOS_IP_Private.h in main.c indeed eliminated the first error.

As for the second error, I have this as the implementation of the stack overflow hook in main.c

void vApplicationStackOverflowHook( void )

{

for( ;; );

} /* End of vApplicationStackOver */

which obviously conflicts with the declaration in task.h.

I modified the argument list in main.c and that solved the second error. Sadly – as is often the issue with compilers – I now have a new set of messages to tackle, but I’ll work on those for a while and post the outcome. (Being a hardware engineer by training, build issues are not my strong suit.)

Thanks again!

Jim

Looking at the new error messages, there are undefined references to xApplicationGetRandomNumber() in FreeRTOS_DHCP.c that apparently weren’t in version 2.0.11 of FreeRTOS+TCP.

[...]

"C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-gcc.exe"   -mprocessor=32MX795F512L  -o dist/default/production/tcp_adc.X.production.elf build/default/production/_ext/1599763551/port.o build/default/production/_ext/1599763551/port_asm.o build/default/production/_ext/190470153/event_groups.o build/default/production/_ext/190470153/list.o build/default/production/_ext/190470153/queue.o build/default/production/_ext/190470153/tasks.o build/default/production/_ext/636803636/heap_4.o build/default/production/_ext/1365677990/BufferAllocation_2.o build/default/production/_ext/801913726/FreeRTOS_ARP.o build/default/production/_ext/801913726/FreeRTOS_DHCP.o build/default/production/_ext/801913726/FreeRTOS_DNS.o build/default/production/_ext/801913726/FreeRTOS_IP.o build/default/production/_ext/801913726/FreeRTOS_Sockets.o build/default/production/_ext/801913726/FreeRTOS_Stream_Buffer.o build/default/production/_ext/801913726/FreeRTOS_TCP_IP.o build/default/production/_ext/801913726/FreeRTOS_TCP_WIN.o build/default/production/_ext/801913726/FreeRTOS_UDP_IP.o build/default/production/_ext/1472/Ethernet_ISR.o build/default/production/_ext/1472/NetworkInterface.o build/default/production/_ext/1472/PHYGeneric.o build/default/production/_ext/1472/PHY_isr.o build/default/production/_ext/1472/ETHPIC32ExtPhy.o build/default/production/_ext/1472/ETHPIC32ExtPhySMSC8720.o build/default/production/_ext/1472/LAN8720A.o build/default/production/_ext/1472/chipKIT_PRO_MX7.o build/default/production/_ext/1472/main.o          -DXPRJ_default=default      -Wl,--defsym=__MPLAB_BUILD=1,--defsym=_min_heap_size=32768,-Map="dist/default/production/tcp_adc.X.production.map"
nbproject/Makefile-default.mk:445: recipe for target 'dist/default/production/tcp_adc.X.production.hex' failed
make[2]: Leaving directory 'D:/443/tmp/FreeRTOSv202104.00/FreeRTOSv202104.00/Projects/tcp_adc - Copy/tcp_adc.X'
nbproject/Makefile-default.mk:90: recipe for target '.build-conf' failed
make[1]: Leaving directory 'D:/443/tmp/FreeRTOSv202104.00/FreeRTOSv202104.00/Projects/tcp_adc - Copy/tcp_adc.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
build/default/production/_ext/801913726/FreeRTOS_DHCP.o: In function `vDHCPProcess':
d:/443/tmp/freertosv202104.00/freertosv202104.00/freertos-plus/source/freertos-plus-tcp/freertos_dhcp.c:454: undefined reference to `xApplicationGetRandomNumber'
d:/443/tmp/freertosv202104.00/freertosv202104.00/freertos-plus/source/freertos-plus-tcp/freertos_dhcp.c:632: undefined reference to `xApplicationGetRandomNumber'
build/default/production/_ext/801913726/FreeRTOS_DHCP.o: In function `prvInitialiseDHCP':
d:/443/tmp/freertosv202104.00/freertosv202104.00/freertos-plus/source/freertos-plus-tcp/freertos_dhcp.c:770: undefined reference to `xApplicationGetRandomNumber'
build/default/production/_ext/801913726/FreeRTOS_DNS.o: In function `prvPrepareLookup':
d:/443/tmp/freertosv202104.00/freertosv202104.00/freertos-plus/source/freertos-plus-tcp/freertos_dns.c:750: undefined reference to `xApplicationGetRandomNumber'
build/default/production/_ext/801913726/FreeRTOS_Sockets.o: In function `prvGetPrivatePortNumber':
d:/443/tmp/freertosv202104.00/freertosv202104.00/freertos-plus/source/freertos-plus-tcp/freertos_sockets.c:2096: undefined reference to `xApplicationGetRandomNumber'
collect2: ld returned 1 exit status
make[2]: *** [dist/default/production/tcp_adc.X.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2

BUILD FAILED (exit value 2, total time: 7s)

Functions prefixed with Application are intended to be provided by the application writer, so a function you have to write. In this case it enables the code to use a random number generated by whatever means the hardware provides.

Thanks Richard. I knew the ‘x’ probably meant something and I should have spent more time looking.

x just denotes return type as you can see in our coding guide: FreeRTOS - Free RTOS Coding Standard and Style Guide

As Richard mentioned, you need to provide an implementation of xApplicationGetRandomNumber which returns a random number.

Thanks.

Thank you Gaurav. I have it working, but some of the code references a function uxRand(). Is xApplicationGeRandomNumber() a replacement for that function? (They have different return types.)

It is not a replacement. It is provided so that the application writer can provide an implementation of their choice (an example would be to use the hardware TRNG).

Yes, that part I understand. My question is if I should replace all uses of uxRand() with xApplicationGetRandomNumber(). I suspect uxRand() was developed by someone not affiliated with FreeRTOS development.

Depends on your implementation of uxRand where you are using it. If the implementation of uxRand is same as xApplicationGetRandomNumber, then it does not matter. On the other hand, if xApplicationGetRandomNumber is more secure, then you should replace the usage of uxRand.

Thanks.

Thank you Gaurav, for helping @jim-frenzel, to get his project compiled.

Last week i prepared a text that describes some of the application hooks mentioned here. This text will be added to the documentation on freertos.org

About randomness:

The TCP protocol needs a reliable source of randomness, in order to be unpredictable.
When a device uses the same initial sequence numbers (ISN) again and again, it is an easy target for TCP spoofing.
Also other protocols like to use random numbers, like e.g. the request ID in a DNS or a DHCP request.

Some hardware generators need to be initialised. It is important to do this before FreeRTOS_IPInit() is called. Please make sure that each time the devices starts, it comes with different random numbers.

The FreeRTOS+TCP leaves it to the application to provide a reliable randomiser. These two functions should provided:

/* Create a random 32-bit random number and store it into *pulNumber
 * and return pdPASS.
 * In case the random number generator (RNG) is broken, return pdFAIL. */
BaseType_t xApplicationGetRandomNumber( uint32_t * pulNumber );

/* Create an initial sequence number (ISN), to be used for a TCP connection
 * between two IP-addresses / port numbers.
 * In most cases it will be sufficient to call xApplicationGetRandomNumber.
 */
uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
                                             uint16_t usSourcePort,
                                             uint32_t ulDestinationAddress,
                                             uint16_t usDestinationPort );

History:

In earlier versions of the library there was a macro ipconfigRAND32(), which had to be defined in the FreeRTOSIPConfig.h file:

extern UBaseType_t uxRand( void );

#define ipconfigRAND32()	uxRand()

These are now deprecated, not used anymore.

The problem with the function uxRand() was that it had no way to tell if the RNG is working properly. although the value 0 is a proper random value, it was used to indicate that the generator is broken. This often lead to confusion.

The function ulApplicationGetNextSequenceNumber() still has this ambiguity: when it returns zero, it means that the RNG is broken, and the TCP connection will be cancelled. We didn’t want to change this and break existing applications again.

Thanks Hein – that was very helpful!