FreeRTOS+TCP how to use loopback interface on STM32H723 board

Hi everyone,

I’m working on a project that need loopback interface to work properly, but I don’t succeed to use it and I haven’t seen information on the documentation to do so.

My purpose is to configure a socket listening on loopback interface and to connect another socket on this one. When I launch that code, debug output show that it succeeds to set socket in listening mode but ARP failed to find the loopback endpoint, and finally failed to establish a TCP connection.

Calling FreeRTOS_IPInit...
FreeRTOS_AddEndPoint: MAC: 44-46 IPv4: 192.168.2.114
FreeRTOS_AddEndPoint: MAC: 44-46 IPv4: 127.0.0.1
prvIPTask started
PHY ID 7C130
xPhyReset: phyBMCR_RESET 0 ready
+TCP: advertise: 01E1 config 3100
prvEthernetUpdateConfig: LS mask 00 Force 1
Autonego ready: 00000004: full duplex 100 mbit high status
Network buffers: 60 lowest 60
Queue space: lowest 68
Link Status is high
IP-address : 192.168.2.114
End-point  : up = yes method static
Net mask   : 255.255.255.0
GW         : 192.168.2.5
DNS-0      : 118.98.44.100
DNS-1      : 0.0.0.0
Broadcast  : 192.168.2.255
MAC address: 00-11-22-33-44-46
 
IP-address : 127.0.0.1
End-point  : up = yes method static
Net mask   : 255.0.0.0
GW         : 0.0.0.0
DNS-0      : 0.0.0.0
DNS-1      : 0.0.0.0
Broadcast  : 127.255.255.255
MAC address: 00-11-22-33-44-46
 
FreeRTOS_bind: Undefined sin_family 
Socket 5000 -> [0.0.0.0]:0 State eCLOSED->eTCP_LISTEN
FreeRTOS_connect: Undefined sin_family 
Socket 41379 -> [0.0.0.0]:5000 State eCLOSED->eCONNECT_SYN
FreeRTOS_FindEndPointOnNetMask[4]: No match for 0.0.0.0
ARP for 0.0.0.0 (using 0.0.0.0): rc=2 00-00-00-00-00-00
FreeRTOS_FindEndPointOnNetMask[12]: No match for 0.0.0.0
Connect[0.0.0.0:5000]: next timeout 1: 500 ms
FreeRTOS_FindEndPointOnNetMask[4]: No match for 0.0.0.0
ARP for 0.0.0.0 (using 0.0.0.0): rc=2 00-00-00-00-00-00
FreeRTOS_FindEndPointOnNetMask[12]: No match for 0.0.0.0
Connect[0.0.0.0:5000]: next timeout 2: 500 ms
Network buffers: 60 lowest 59
FreeRTOS_FindEndPointOnNetMask[4]: No match for 0.0.0.0
ARP for 0.0.0.0 (using 0.0.0.0): rc=2 00-00-00-00-00-00
FreeRTOS_FindEndPointOnNetMask[12]: No match for 0.0.0.0
Connect[0.0.0.0:5000]: next timeout 3: 500 ms
Connect: giving up 0.0.0.0:5000
Move from eCONNECT_SYN to eCLOSE_WAIT
Socket 41379 -> [0.0.0.0]:5000 State eCONNECT_SYN->eCLOSE_WAIT
FreeRTOS_connect() stopped due to an error
Failed to connect to local Address 

I succeed to establish a TCP connection with the external network using a PC but not to use the loopback interface.

To be sure I have a well configured project I started my project from this example (I can’t put the link to the github project, here is the name STM32_Nucleo_H723ZG_FreeRTOS_TCP.git) and I applied the following patch (I can’t upload the patch so I copy/paste it at the end)

I’m working with following version of libraries :

  • FreeRTOS+TCP commit 7a4957d15aeac0e1da4237f8059b66c35b2de41c

  • FreeRTOS commit 18e293723929da31c0395fb4c7f9187474058a6a

I’m not sure about the procedure to follow and I would greatly appreciate some help.

Thanks in advance for your answers !

From 488efa9e1e3f4f6aa046ac8cf19868aac403f391 Mon Sep 17 00:00:00 2001
From: Raphal <gael.raphal@systerel.fr>
Date: Tue, 10 Sep 2024 10:14:35 +0200
Subject: [PATCH] Test to trigger loopback interface with socket API

---
 .cproject                              |  5 +-
 .project                               | 88 +++---------------------
 Libraries/Config/FreeRTOSIPConfig.h    |  8 ++-
 Libraries/FreeRTOS-Plus-CLI/app_main.c | 92 ++++++++++++++++++++++----
 4 files changed, 96 insertions(+), 97 deletions(-)

diff --git a/.cproject b/.cproject
index 0f83845..bb0384a 100644
--- a/.cproject
+++ b/.cproject
@@ -96,7 +96,6 @@
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="FreeRTOS-Kernel"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="FreeRTOS-Plus-CLI"/>
 						<entry excluding="tools/tcp_utilities/NTPDemo.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="FreeRTOS-Plus-TCP"/>
-						<entry excluding="FreeRTOS-Plus-CLI|FreeRTOS-Plus-TCP|FreeRTOS-Kernel" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Libraries"/>
 					</sourceEntries>
 				</configuration>
 			</storageModule>
@@ -170,8 +169,7 @@
 						</toolChain>
 					</folderInfo>
 					<sourceEntries>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
 					</sourceEntries>
 				</configuration>
 			</storageModule>
@@ -201,4 +199,5 @@
 			<resource resourceType="PROJECT" workspacePath="/STM32_Nucleo_H723ZG_FreeRTOS_TCP"/>
 		</configuration>
 	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
 </cproject>
\ No newline at end of file
diff --git a/.project b/.project
index b44685f..773e943 100644
--- a/.project
+++ b/.project
@@ -57,7 +57,7 @@
 			</matcher>
 		</filter>
 		<filter>
-			<id>1689237943972</id>
+			<id>1725897023013</id>
 			<name>FreeRTOS-Plus-TCP</name>
 			<type>5</type>
 			<matcher>
@@ -66,7 +66,7 @@
 			</matcher>
 		</filter>
 		<filter>
-			<id>1689237943999</id>
+			<id>1725897023014</id>
 			<name>FreeRTOS-Plus-TCP</name>
 			<type>9</type>
 			<matcher>
@@ -75,7 +75,7 @@
 			</matcher>
 		</filter>
 		<filter>
-			<id>1689237944006</id>
+			<id>1725897023015</id>
 			<name>FreeRTOS-Plus-TCP</name>
 			<type>9</type>
 			<matcher>
@@ -83,42 +83,6 @@
 				<arguments>1.0-name-matches-false-false-tools</arguments>
 			</matcher>
 		</filter>
-		<filter>
-			<id>1689237631613</id>
-			<name>Libraries</name>
-			<type>9</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-FreeRTOS-Kernel</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1689237631621</id>
-			<name>Libraries</name>
-			<type>9</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-Config</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1689237631628</id>
-			<name>Libraries</name>
-			<type>9</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-FreeRTOS-Plus-TCP</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1689237631633</id>
-			<name>Libraries</name>
-			<type>9</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-FreeRTOS-Plus-CLI</arguments>
-			</matcher>
-		</filter>
 		<filter>
 			<id>1689229655055</id>
 			<name>FreeRTOS-Kernel/portable</name>
@@ -146,15 +110,6 @@
 				<arguments>1.0-name-matches-false-false-tcp_utilities</arguments>
 			</matcher>
 		</filter>
-		<filter>
-			<id>1689225805239</id>
-			<name>Libraries/FreeRTOS-Kernel</name>
-			<type>5</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-*.c</arguments>
-			</matcher>
-		</filter>
 		<filter>
 			<id>1689229674781</id>
 			<name>FreeRTOS-Kernel/portable/GCC</name>
@@ -173,24 +128,6 @@
 				<arguments>1.0-name-matches-false-false-heap_4.c</arguments>
 			</matcher>
 		</filter>
-		<filter>
-			<id>1689225845131</id>
-			<name>Libraries/FreeRTOS-Kernel/portable</name>
-			<type>9</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-GCC</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1689225845134</id>
-			<name>Libraries/FreeRTOS-Kernel/portable</name>
-			<type>9</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-MemMang</arguments>
-			</matcher>
-		</filter>
 		<filter>
 			<id>1689232848768</id>
 			<name>FreeRTOS-Plus-TCP/source/portable/BufferManagement</name>
@@ -210,7 +147,7 @@
 			</matcher>
 		</filter>
 		<filter>
-			<id>1689232907601</id>
+			<id>1725897057021</id>
 			<name>FreeRTOS-Plus-TCP/source/portable/NetworkInterface</name>
 			<type>9</type>
 			<matcher>
@@ -219,7 +156,7 @@
 			</matcher>
 		</filter>
 		<filter>
-			<id>1689232907604</id>
+			<id>1725897057024</id>
 			<name>FreeRTOS-Plus-TCP/source/portable/NetworkInterface</name>
 			<type>9</type>
 			<matcher>
@@ -228,21 +165,12 @@
 			</matcher>
 		</filter>
 		<filter>
-			<id>1689229384197</id>
-			<name>Libraries/FreeRTOS-Kernel/portable/GCC</name>
+			<id>1725897057027</id>
+			<name>FreeRTOS-Plus-TCP/source/portable/NetworkInterface</name>
 			<type>9</type>
 			<matcher>
 				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-ARM_CM4F</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1689229403476</id>
-			<name>Libraries/FreeRTOS-Kernel/portable/MemMang</name>
-			<type>5</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-heap_4.c</arguments>
+				<arguments>1.0-name-matches-false-false-loopback</arguments>
 			</matcher>
 		</filter>
 	</filteredResources>
diff --git a/Libraries/Config/FreeRTOSIPConfig.h b/Libraries/Config/FreeRTOSIPConfig.h
index c53ed14..21b3e26 100644
--- a/Libraries/Config/FreeRTOSIPConfig.h
+++ b/Libraries/Config/FreeRTOSIPConfig.h
@@ -135,7 +135,7 @@ stack will revert to using the static IP address even when ipconfigUSE_DHCP is
 set to 1 if a valid configuration cannot be obtained from a DHCP server for any
 reason.  The static configuration used is that passed into the stack by the
 FreeRTOS_IPInit() function call. */
-#define ipconfigUSE_DHCP                            1
+#define ipconfigUSE_DHCP                            0
 #define ipconfigDHCP_REGISTER_HOSTNAME              1
 #define ipconfigDHCP_USES_UNICAST                   1
 
@@ -315,7 +315,7 @@ extern void vLoggingPrintf( const char * pcFormat, ... );
 1 then FreeRTOS_debug_printf should be defined to the function used to print
 out the debugging messages. */
 #ifndef ipconfigHAS_DEBUG_PRINTF
-    #define ipconfigHAS_DEBUG_PRINTF                    0
+    #define ipconfigHAS_DEBUG_PRINTF                    1
 #endif
 
 #if( ipconfigHAS_DEBUG_PRINTF == 1 )
@@ -376,6 +376,10 @@ messages. */
 
 #define ipconfigTCP_MEM_STATS_MAX_ALLOCATION            64
 
+#define ipconfigUSE_LOOPBACK							1
+
+#define ipconfigUSE_IPv6                                0
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/Libraries/FreeRTOS-Plus-CLI/app_main.c b/Libraries/FreeRTOS-Plus-CLI/app_main.c
index d297a79..b965bfc 100644
--- a/Libraries/FreeRTOS-Plus-CLI/app_main.c
+++ b/Libraries/FreeRTOS-Plus-CLI/app_main.c
@@ -30,14 +30,14 @@
 /* Set the USE_IPv6_END_POINTS macro to 1 or 0 to enable IPv6
  * endpoints.
  */
-#define USE_IPv6_END_POINTS                 1
+#define USE_IPv6_END_POINTS                 0
 
 #if ( ipconfigUSE_IPv6 != 0 && USE_IPv6_END_POINTS != 0 && ipconfigUSE_IPv4 != 0 )
-    #define TOTAL_ENDPOINTS                 3
+    #define TOTAL_ENDPOINTS                 (3 + 1)
 #elif ( ipconfigUSE_IPv4 == 0 && ipconfigUSE_IPv6 != 0 )
-    #define TOTAL_ENDPOINTS                 2
+    #define TOTAL_ENDPOINTS                 (2 + 1)
 #else
-    #define TOTAL_ENDPOINTS                 1
+    #define TOTAL_ENDPOINTS                 (1 + 1)
 #endif /* ( ipconfigUSE_IPv6 != 0 && USE_IPv6_END_POINTS != 0 ) */
 
 
@@ -52,12 +52,12 @@
  * configTCP_ECHO_SERVER_ADDR macro
  *
  * mainCREATE_UDP_ECHO_TASKS_SINGLE:  When set to 1 a task is created that sends data
- * to the address configECHO_SERVER_ADDR_STRING (IPv4/Ipv6) and port (configECHO_SERVER_PORT) 
+ * to the address configECHO_SERVER_ADDR_STRING (IPv4/Ipv6) and port (configECHO_SERVER_PORT)
  * where it is expected to echo back the data, which, the created tasks receives.
  *
  */
-#define mainCREATE_TCP_ECHO_TASKS_SINGLE              1 /* 1 */
-#define mainCREATE_UDP_ECHO_TASKS_SINGLE              1
+#define mainCREATE_TCP_ECHO_TASKS_SINGLE              0 /* 1 */
+#define mainCREATE_UDP_ECHO_TASKS_SINGLE              0
 
 /*-----------------------------------------------------------*/
 /*-----------------------------------------------------------*/
@@ -92,6 +92,11 @@ void app_main( void )
     const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 };
     const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };
 
+    const uint8_t ucLoopbackIPAddress[ 4 ] = { 127, 0 , 0 , 1 };
+    const uint8_t ucLoopbackNetMask[ 4 ] = { 255, 0, 0, 0 };
+    const uint8_t ucLoopbackGatewayAddress[ 4 ] = { 0, 0, 0, 0 };
+    const uint8_t ucLoopbackDNSServerAddress[ 4 ] = { 0, 0, 0, 0 };
+
     xRet = xLoggingTaskInitialize( mainLOGGING_TASK_STACK_SIZE,
                                    mainLOGGING_TASK_PRIORITY,
                                    mainLOGGING_QUEUE_LENGTH );
@@ -100,7 +105,7 @@ void app_main( void )
     configPRINTF( ( "Calling FreeRTOS_IPInit...\n" ) );
 
 
-  	static NetworkInterface_t xInterfaces[1];
+  	static NetworkInterface_t xInterfaces[2];
    	static NetworkEndPoint_t xEndPoints[4];
 	//memcpy(ipLOCAL_MAC_ADDRESS, ucMACAddress, sizeof ucMACAddress);
 
@@ -126,6 +131,15 @@ void app_main( void )
             }
         #endif /* ( ipconfigUSE_IPv4 != 0 ) */
 
+        extern NetworkInterface_t * pxLoopback_FillInterfaceDescriptor(BaseType_t xEMACIndex,
+                                                         NetworkInterface_t * pxInterface );
+
+        pxLoopback_FillInterfaceDescriptor(0, &(xInterfaces[1]));
+
+        FreeRTOS_FillEndPoint(&(xInterfaces[1]), &(xEndPoints[xEndPointCount]), ucLoopbackIPAddress, ucLoopbackNetMask, ucLoopbackGatewayAddress, ucLoopbackDNSServerAddress, ucMACAddress);
+
+        xEndPointCount += 1;
+
         /*
         *     End-point-1 : public
         *     Network: 2001:470:ed44::/64
@@ -214,10 +228,63 @@ void app_main( void )
     /* Infinite loop */
     for(;;)
     {
-        
+
+    }
+}
+
+static void prvLoopbackTestTask( void *pvParameters )
+{
+    struct freertos_sockaddr localAddress;
+    struct freertos_sockaddr connectedAddress;
+    uint32_t lenConn;
+	Socket_t sockListening = NULL;
+	Socket_t sockConnecting = NULL;
+
+
+    localAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr("127.0.0.1");
+    localAddress.sin_port = FreeRTOS_htons(5000);
+
+	sockListening = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);
+    sockConnecting = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);
+    if (sockConnecting != FREERTOS_INVALID_SOCKET && sockConnecting != FREERTOS_INVALID_SOCKET)
+    {
+        int res = FreeRTOS_bind(sockListening, &localAddress, sizeof(&localAddress));
+        if (!res)
+        {
+            res = FreeRTOS_listen(sockListening, 2);
+            if (!res)
+            {
+                res = FreeRTOS_connect(sockConnecting, &localAddress, sizeof(&localAddress));
+                if (!res)
+                {
+                    FreeRTOS_accept(sockListening, &connectedAddress, &lenConn);
+                }
+                else
+                {
+                	vLoggingPrintf("Failed to connect to local Address \n");
+                }
+            }
+            else
+            {
+            	vLoggingPrintf("Failed to listen on local Address \n");
+            }
+        }
+        else
+        {
+        	vLoggingPrintf("Failed to bind local Address \n");
+        }
     }
 }
 
+static void vStartLoopbackTestTask( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority)
+{
+    xTaskCreate( 	prvLoopbackTestTask,	/* The function that implements the task. */
+                    "loopbackConnect",			/* Just a text name for the task to aid debugging. */
+                    usTaskStackSize,	/* The stack size is defined in FreeRTOSIPConfig.h. */
+                    NULL,		/* The task parameter, not used in this case. */
+                    uxTaskPriority,		/* The priority assigned to the task is defined in FreeRTOSConfig.h. */
+                    NULL );
+}
 
 #if defined(ipconfigIPv4_BACKWARD_COMPATIBLE) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 )
 	void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, struct xNetworkEndPoint* pxEndPoint )
@@ -243,6 +310,7 @@ void app_main( void )
 
                 #if ( ipconfigUSE_IPv4 != 0 )
 
+                    vStartLoopbackTestTask(mainCLI_TASK_STACK_SIZE, mainCLI_TASK_PRIORITY);
                     #if mainCREATE_TCP_ECHO_TASKS_SINGLE
 
                         void vStartTCPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority );
@@ -267,12 +335,12 @@ void app_main( void )
 
         	extern void showEndPoint( NetworkEndPoint_t * pxEndPoint );
             showEndPoint( pxEndPoint );
-        
+
         #else
 
             char cBuffer[ 16 ];
             uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;
-        
+
             /* Print out the network configuration, which may have come from a DHCP
             * server. */
             #if defined(ipconfigIPv4_BACKWARD_COMPATIBLE) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 )
@@ -292,7 +360,7 @@ void app_main( void )
 
             FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );
             configPRINTF( ( "DNS Server Address: %s\n", cBuffer ) );
-        
+
         #endif /* defined(ipconfigIPv4_BACKWARD_COMPATIBLE) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */
 
     }
-- 
2.25.1

FreeRTOS_bind: Undefined sin_family

You will have to solve that. Look from where bind() was called and make sure that

    sin_family = FREERTOS_AF_INET4;

I see so many strange things in the logging… can you post the code that creates sockets , binds them and call connect()?

Recently I tested the loopback interface and I found a few problems.
Please have a look at this issue on github. I created this patch: patch_and_testing_program.zip

EDIT
Sorry, I found the necessary code in the patch that you included.

1 Like
     localAddress.sin_address.ulIP_IPv4 =
         FreeRTOS_inet_addr("127.0.0.1");
     localAddress.sin_port = FreeRTOS_htons(5000);
+    localAddress.sin_family = FREERTOS_AF_INET4;

How far do you get with the above change?

Hi,

Thanks for you answer and the pointer to the issue and patch.

Specifying IP v4 family and applying the patch to the last main branch allow me to connect on loopback interface.

Thanks for your help !

applying the patch to the last main branch allow me to connect on loopback interface.

Glad it works for you, and thanks for testing.

I hardly have the time to create a pull request for this patch. I will ask a colleague.

Here is a pull request with the changes: Fix ARP failure with loopback addresses by tony-josi-aws · Pull Request #1185 · FreeRTOS/FreeRTOS-Plus-TCP · GitHub