FreeRTOSを動かしてみる(2)

[前回](https://qiita.com/t-yano-tryhard/items/721f413b489a08300356)の続き

----

# サーバ/クライアントの枠を作る

<details>
<summary>こんな感じで(前回からの差分)</summary>

```diff
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile
index b2bc2eef..80b29a28 100644
--- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile
@@ -59,9 +59,9 @@ ifeq ($(FULL_DEMO), 1)
 
     CFLAGS := -DmainCREATE_FULL_DEMO_ONLY=1
 else
-    SOURCE_FILES += main_blinky.c
+#    SOURCE_FILES += main_blinky.c
 
-    CFLAGS := -DmainCREATE_SIMPLE_BLINKY_DEMO_ONLY=1
+#    CFLAGS := -DmainCREATE_SIMPLE_BLINKY_DEMO_ONLY=1
 endif
 
 
@@ -90,7 +90,9 @@ SOURCE_FILES += $(TCP_DIR)/source/portable/BufferManagement/BufferAllocation_2.c
 SOURCE_FILES += $(TCP_DIR)/source/portable/NetworkInterface/board_family/NetworkInterface.c
 
 ### TCP/IP APP
-#SOURCE_FILES += app_tcp.c
+SOURCE_FILES += main_tcp.c
+SOURCE_FILES += app_client.c
+SOURCE_FILES += app_server.c
 
 OBJ_FILES := $(SOURCE_FILES:%.c=$(BUILD_DIR)/%.o)
 
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_client.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_client.c
new file mode 100644
index 00000000..d44babf9
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_client.c
@@ -0,0 +1,10 @@
+#include "app_common.h"
+
+TaskHandle_t client_handle;
+void client_task(void *param)
+{
+    (void)param;
+    d("");
+    for (;;)
+        ;
+}
\ No newline at end of file
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_common.h b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_common.h
new file mode 100644
index 00000000..7effcb06
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_common.h
@@ -0,0 +1,19 @@
+#ifndef __APP_COMMON_H__
+#define __APP_COMMON_H__
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "dlog.h"
+
+#define SERVER_PRIORITY (tskIDLE_PRIORITY + 2)
+#define CLIENT_PRIORITY (tskIDLE_PRIORITY + 2)
+
+extern TaskHandle_t server_handle;
+extern TaskHandle_t client_handle;
+
+void main_tcp(void);
+void create_server_task(void);
+void create_client_task(void);
+void server_task(void *param);
+void client_task(void *param);
+#endif
\ No newline at end of file
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_server.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_server.c
new file mode 100644
index 00000000..bc20215d
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_server.c
@@ -0,0 +1,11 @@
+#include "app_common.h"
+
+TaskHandle_t server_handle;
+void server_task(void *param)
+{
+    (void)param;
+    d("");
+    vTaskDelay(0);
+    for (;;)
+        ;
+}
\ No newline at end of file
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/dlog.h b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/dlog.h
new file mode 100644
index 00000000..927df7ae
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/dlog.h
@@ -0,0 +1,10 @@
+#ifndef __APP_DLOG_H__
+#define __APP_DLOG_H__
+
+#include <stdio.h>
+#define d(s, ...)                                                                 \
+    do                                                                            \
+    {                                                                             \
+        printf("%s(%d) %s " s "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
+    } while (0)
+#endif
\ No newline at end of file
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c
index 0aea169c..f7a9f56e 100644
--- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c
@@ -32,6 +32,7 @@
 #include <string.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include "app_common.h"
 
 void vApplicationStackOverflowHook( TaskHandle_t pxTask,
                                     char * pcTaskName );
@@ -65,7 +66,7 @@ int main()
         }
     #else
         {
-            #error "Invalid Selection...\nPlease Select a Demo application from the main command"
+            main_tcp();
         }
     #endif /* if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) */
     return 0;
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_tcp.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_tcp.c
new file mode 100644
index 00000000..570985a3
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_tcp.c
@@ -0,0 +1,9 @@
+#include "app_common.h"
+#include <stdio.h>
+
+void main_tcp(void) {
+    xTaskCreate(server_task, "server_task", 500, NULL, SERVER_PRIORITY, &server_handle);
+    xTaskCreate(client_task, "client_task", 500, NULL, CLIENT_PRIORITY, &client_handle);
+    vTaskStartScheduler();
+    printf("task not work\n");
+}
\ No newline at end of file

```

</details>

通った
```
sudo qemu-system-arm -machine mps2-an385 -monitor null -semihosting --semihosting-config enable=on,target=native -kernel ./build/RTOSDemo.axf -serial stdio -nographic
app_server.c(7) server_task 
app_client.c(7) client_task 
```

# NICを実装する

IPの使用方法は以下の通りとなっている。
まずはルートを調べる。

TCP実装方法は以下にあるので読んで見る。
https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html

しばらく読んで見る、、、

こんな構造体も関数もないぞ？？？

Tutorialは4.0.0向けで一般にダウンロードできるものは3.1.0という落ちでした。

Deprecatedに3.1.0向けが残っているっぽいのでそれを参考に書いてみる。

## ソケット作成

<details>
<summary>前回からの差分</summary>

```
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/FreeRTOSIPConfig.h b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/FreeRTOSIPConfig.h
index 54c715f5..a26ef6b5 100644
--- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/FreeRTOSIPConfig.h
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/FreeRTOSIPConfig.h
@@ -1,4 +1,8 @@
 #ifndef FREERTOS_IP_CONFIG_H
 #define FREERTOS_IP_CONFIG_H
+
 #define ipconfigBYTE_ORDER  pdFREERTOS_LITTLE_ENDIAN
+#define ipconfigUSE_IPv4    1
+#define ipconfigUSE_TCP     1
+
 #endif
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile
index 80b29a28..4b8f6d45 100644
--- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile
@@ -87,7 +87,7 @@ INCLUDE_DIRS += -I$(TCP_DIR)/source/include
 INCLUDE_DIRS += -I$(TCP_DIR)/source/portable/Compiler/GCC
 SOURCE_FILES += $(wildcard $(TCP_DIR)/source/*.c)
 SOURCE_FILES += $(TCP_DIR)/source/portable/BufferManagement/BufferAllocation_2.c
-SOURCE_FILES += $(TCP_DIR)/source/portable/NetworkInterface/board_family/NetworkInterface.c
+SOURCE_FILES += $(TCP_DIR)/source/portable/NetworkInterface/virtether/NetworkInterface.c
 
 ### TCP/IP APP
 SOURCE_FILES += main_tcp.c
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/NetworkInterface.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/NetworkInterface.c
new file mode 120000
index 00000000..0a846b9b
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/NetworkInterface.c
@@ -0,0 +1 @@
+../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/source/portable/NetworkInterface/virtether/NetworkInterface.c
\ No newline at end of file
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_client.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_client.c
index d44babf9..296d8a16 100644
--- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_client.c
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_client.c
@@ -1,10 +1,43 @@
 #include "app_common.h"
+#include "FreeRTOS_Sockets.h"
+
+/* functions */
+static void vCreateTCPClientSocket(void);
 
 TaskHandle_t client_handle;
 void client_task(void *param)
 {
     (void)param;
     d("");
+    vCreateTCPClientSocket();
     for (;;)
         ;
+}
+
+static void vCreateTCPClientSocket(void)
+{
+    Socket_t xClientSocket;
+    socklen_t xSize = sizeof(struct freertos_sockaddr);
+    static const TickType_t xTimeOut = pdMS_TO_TICKS(2000);
+
+    xClientSocket = FreeRTOS_socket(FREERTOS_AF_INET,
+                                    FREERTOS_SOCK_STREAM,
+                                    FREERTOS_IPPROTO_TCP);
+    d("sock:%ld", (int32_t)xClientSocket);
+    configASSERT(xClientSocket != FREERTOS_INVALID_SOCKET);
+
+    FreeRTOS_setsockopt(xClientSocket,
+                        0,
+                        FREERTOS_SO_RCVTIMEO, &xTimeOut,
+                        sizeof(xTimeOut));
+
+    FreeRTOS_setsockopt(xClientSocket,
+                        0,
+                        FREERTOS_SO_SNDTIMEO,
+                        &xTimeOut,
+                        sizeof(xTimeOut));
+    d("sockopt");
+
+    FreeRTOS_bind(xClientSocket, NULL, xSize);
+    d("bind");
 }
\ No newline at end of file
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_server.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_server.c
index bc20215d..ef271e81 100644
--- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_server.c
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_server.c
@@ -1,11 +1,54 @@
 #include "app_common.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+
+static void vCreateTCPServerSocket(void);
 
 TaskHandle_t server_handle;
 void server_task(void *param)
 {
     (void)param;
     d("");
+
+    vCreateTCPServerSocket();
     vTaskDelay(0);
     for (;;)
         ;
+}
+
+static void vCreateTCPServerSocket(void)
+{
+    struct freertos_sockaddr xClient, xBindAddress;
+    Socket_t xListeningSocket, xConnectedSocket;
+    socklen_t xSize = sizeof(xClient);
+    static const TickType_t xReceiveTimeOut = portMAX_DELAY;
+    const BaseType_t xBacklog = 20;
+
+    xListeningSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);
+    d("sock:%ld", (int32_t)xListeningSocket);
+
+    configASSERT(xListeningSocket != FREERTOS_INVALID_SOCKET);
+
+    FreeRTOS_setsockopt(xListeningSocket,
+                        0,
+                        FREERTOS_SO_RCVTIMEO,
+                        &xReceiveTimeOut,
+                        sizeof(xReceiveTimeOut));
+
+    xBindAddress.sin_port = (uint16_t)10000;
+    xBindAddress.sin_port = FreeRTOS_htons(xBindAddress.sin_port);
+
+    FreeRTOS_bind(xListeningSocket, &xBindAddress, sizeof(xBindAddress));
+    d("bind");
+
+    FreeRTOS_listen(xListeningSocket, xBacklog);
+    d("listen");
+
+    for (;;)
+    {
+        xConnectedSocket = FreeRTOS_accept(xListeningSocket, &xClient, &xSize);
+        configASSERT(xConnectedSocket != FREERTOS_INVALID_SOCKET);
+
+        d("accept");
+    }
 }
\ No newline at end of file
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/dlog.h b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/dlog.h
index 927df7ae..14fe575f 100644
--- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/dlog.h
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/dlog.h
@@ -2,9 +2,13 @@
 #define __APP_DLOG_H__
 
 #include <stdio.h>
-#define d(s, ...)                                                                 \
-    do                                                                            \
-    {                                                                             \
-        printf("%s(%d) %s " s "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
+#include <string.h>
+
+#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
+
+#define d(s, ...)                                                                     \
+    do                                                                                \
+    {                                                                                 \
+        printf("%s(%d) %s " s "\n", __FILENAME__, __LINE__, __func__, ##__VA_ARGS__); \
     } while (0)
 #endif
\ No newline at end of file
diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_tcp.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_tcp.c
index 570985a3..28db7343 100644
--- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_tcp.c
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_tcp.c
@@ -1,9 +1,54 @@
 #include "app_common.h"
 #include <stdio.h>
+#include "FreeRTOS_IP.h"
+
+/* The MAC address array is not declared const as the MAC address will
+normally be read from an EEPROM and not hard coded (in real deployed
+applications).*/
+static uint8_t ucMACAddress[ 6 ] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
+
+/* Define the network addressing.  These parameters will be used if either
+ipconfigUDE_DHCP is 0 or if ipconfigUSE_DHCP is 1 but DHCP auto configuration
+failed. */
+static const uint8_t ucIPAddress[ 4 ] = { 10, 10, 10, 200 };
+static const uint8_t ucNetMask[ 4 ] = { 255, 0, 0, 0 };
+static const uint8_t ucGatewayAddress[ 4 ] = { 10, 10, 10, 1 };
+
+/* The following is the address of an OpenDNS server. */
+static const uint8_t ucDNSServerAddress[ 4 ] = { 208, 67, 222, 222 };
+
+void main_tcp(void)
+{
+
+        FreeRTOS_IPInit( ucIPAddress,
+                     ucNetMask,
+                     ucGatewayAddress,
+                     ucDNSServerAddress,
+                     ucMACAddress );
 
-void main_tcp(void) {
     xTaskCreate(server_task, "server_task", 500, NULL, SERVER_PRIORITY, &server_handle);
     xTaskCreate(client_task, "client_task", 500, NULL, CLIENT_PRIORITY, &client_handle);
     vTaskStartScheduler();
     printf("task not work\n");
-}
\ No newline at end of file
+}
+
+void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
+{
+static BaseType_t xTasksAlreadyCreated = pdFALSE;
+
+    /* Both eNetworkUp and eNetworkDown events can be processed here. */
+    if( eNetworkEvent == eNetworkUp )
+    {
+        /* Create the tasks that use the TCP/IP stack if they have not already
+        been created. */
+        if( xTasksAlreadyCreated == pdFALSE )
+        {
+            /*
+             * For convenience, tasks that use FreeRTOS-Plus-TCP can be created here
+             * to ensure they are not created before the network is usable.
+             */
+
+            xTasksAlreadyCreated = pdTRUE;
+        }
+    }
+}

```

</details>

ついでに[github](https://github.com/tyano461/freertos_cm3/commit/b48b8e7ea6c39ed2a855fdb083bdaabd858cc23c)に上げた


今こんな感じ

```
sudo qemu-system-arm -machine mps2-an385 -monitor null -semihosting --semihosting-config enable=on,target=native -kernel ./build/RTOSDemo.axf -serial stdio -nographic
NetworkInterface.c(59) xNetworkInterfaceInitialise 
NetworkInterface.c(95) xApplicationGetRandomNumber 
app_server.c(11) server_task 
app_server.c(28) vCreateTCPServerSocket sock:536945200
app_client.c(11) client_task 
app_client.c(26) vCreateTCPClientSocket sock:536945632
app_client.c(39) vCreateTCPClientSocket sockopt
NetworkInterface.c(95) xApplicationGetRandomNumber 
app_server.c(42) vCreateTCPServerSocket bind
app_server.c(45) vCreateTCPServerSocket listen
app_client.c(42) vCreateTCPClientSocket bind
NetworkInterface.c(68) xNetworkInterfaceOutput eb:0x2001259a ip:4294967295 bp:17408 p:17152 ct:0 ow:0x2001046c n:0x20010490 p:0x20010460 iv:0 len:300 aft:1
```

## パケット送ってみる

[チュートリアルをコピってログ埋め込んだだけ](https://github.com/tyano461/freertos_cm3/commit/324dc3d32fbca1c369558bb6f731659bc7c6666a)

つながるわけはないけどこんな感じになるらしい。
```
sudo qemu-system-arm -machine mps2-an385 -monitor null -semihosting --semihosting-config enable=on,target=native -kernel ./build/RTOSDemo.axf -serial stdio -nographic
NetworkInterface.c(59) xNetworkInterfaceInitialise 
NetworkInterface.c(95) xApplicationGetRandomNumber 
app_server.c(11) server_task 
app_server.c(28) vCreateTCPServerSocket sock:536945208
app_client.c(28) client_task 
app_client.c(44) vTCPSend IN
NetworkInterface.c(95) xApplicationGetRandomNumber 
app_server.c(42) vCreateTCPServerSocket bind
app_server.c(45) vCreateTCPServerSocket listen
NetworkInterface.c(68) xNetworkInterfaceOutput eb:0x200125a2 ip:3355486400 bp:0 p:0 ct:0 ow:0x2001046c n:0x20010490 p:0x20010460 iv:0 len:42 aft:1
NetworkInterface.c(68) xNetworkInterfaceOutput eb:0x200125fa ip:4294967295 bp:17408 p:17152 ct:0 ow:0x20010490 n:0x200104b4 p:0x20010460 iv:0 len:300 aft:1
NetworkInterface.c(68) xNetworkInterfaceOutput eb:0x20012742 ip:3355486400 bp:0 p:0 ct:0 ow:0x200104b4 n:0x200104d8 p:0x20010460 iv:0 len:42 aft:1
NetworkInterface.c(68) xNetworkInterfaceOutput eb:0x200127a2 ip:3355486400 bp:0 p:0 ct:0 ow:0x200104d8 n:0x200104fc p:0x20010460 iv:0 len:42 aft:1
app_client.c(87) vTCPSend not connected
app_client.c(108) vTCPSend OUT
```

# FreeRTOS-Plus-TCP(V4.0.0)
ドキュメントはv4ぽいが公式からダウンロードできるものについているFreeRTOS-Plus-TCPは3.1.0でもなさそう。(ファイルヘッダに3.1.0って書いてあるけど `pxFillInterfaceDescriptor`呼んでるとこどこにもないし）

答え合わせが面倒なのでv4.0.0に変更してみる。

FreeRTOS_IPInit_Multiで止まるようになった

```
(gdb) bt 
#0  vAssertCalled () at main.c:139
#1  0x00005db2 in FreeRTOS_IPInit_Multi () at /home/voyager/workspace/freertos/FreeRTOS-Plus-TCP/source/FreeRTOS_IP.c:954
#2  0x00005e40 in FreeRTOS_IPInit (ucIPAddress=ucIPAddress@entry=0x112c8 <ucIPAddress> "\n\n\n\310app_client.c", ucNetMask=ucNetMask@entry=0x112c4 <ucNetMask> "\377", ucGatewayAddress=ucGatewayAddress@entry=0x112c0 <ucGatewayAddress> "\n\n\n\001\377", ucDNSServerAddress=ucDNSServerAddress@entry=0x112bc <ucDNSServerAddress> "\320C\336\336\n\n\n\001\377", ucMACAddress=ucMACAddress@entry=0x20000128 <ucMACAddress> "") at /home/voyager/workspace/freertos/FreeRTOS-Plus-TCP/source/FreeRTOS_IP.c:939
#3  0x0000dd8c in main_tcp () at main_tcp.c:23
#4  0x000001c6 in main () at main.c:69

```

pxNetworkInterfacesがNULLだとだめらしい
```
(gdb) l FreeRTOS_FirstNetworkInterface
206	 *
207	 * @return The first interface, or NULL if none has been added
208	 */
209	    NetworkInterface_t * FreeRTOS_FirstNetworkInterface( void )
210	    {
211	        return pxNetworkInterfaces;
212	    }
```

```
grep pxNetworkInterfaces ../FreeRTOS-Plus-TCP/ -wnrI |grep -v test | grep " = "
../FreeRTOS-Plus-TCP/source/FreeRTOS_IP.c:506:    for( pxInterface = pxNetworkInterfaces; pxInterface != NULL; pxInterface = pxInterface->pxNext )
../FreeRTOS-Plus-TCP/source/FreeRTOS_IP_Timers.c:322:            for( pxInterface = pxNetworkInterfaces; pxInterface != NULL; pxInterface = pxInterface->pxNext )
../FreeRTOS-Plus-TCP/source/FreeRTOS_Routing.c:56:struct xNetworkInterface * pxNetworkInterfaces = NULL;
../FreeRTOS-Plus-TCP/source/FreeRTOS_Routing.c:169:                pxNetworkInterfaces = pxInterface;
../FreeRTOS-Plus-TCP/source/FreeRTOS_Routing.c:179:                pxIterator = pxNetworkInterfaces;
../FreeRTOS-Plus-TCP/source/FreeRTOS_Routing.c:1169:        pxNetworkInterfaces = pxInterface;
```

(169)と(1169)はどちらも同じ関数名だった`FreeRTOS_AddNetworkInterface`
どこかのタイミングで `FreeRTOS_AddNetworkInterface` が呼ばれていないとだめらしい

[これ](https://intereactive.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_AddNetworkInterface.html)みると `px${port_name}_FillInterfaceDescriptor()` を呼ばないとだめらしい。

追加したけどまた止まった
```
(gdb) bt 
#0  vAssertCalled () at main.c:139
#1  0x00006be2 in prvProcessNetworkDownEvent (pxInterface=0x2000680c <xInterfaces.5>) at /home/voyager/workspace/freertos/FreeRTOS-Plus-TCP/source/FreeRTOS_IP_Utils.c:824
#2  0x000065b2 in prvProcessIPEventsAndTimers () at /home/voyager/workspace/freertos/FreeRTOS-Plus-TCP/source/FreeRTOS_IP.c:301
#3  0x000066a6 in prvIPTask (pvParameters=<optimized out>) at /home/voyager/workspace/freertos/FreeRTOS-Plus-TCP/source/FreeRTOS_IP.c:247
#4  0x00000280 in prvPortStartFirstTask () at /home/voyager/workspace/freertos/FreeRTOSv202212.01/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c:247
```

コールバックが設定されてないとだめ
```
(gdb) l /home/voyager/workspace/freertos/FreeRTOS-Plus-TCP/source/FreeRTOS_IP_Utils.c:824
819	void prvProcessNetworkDownEvent( struct xNetworkInterface * pxInterface )
820	{
821	    NetworkEndPoint_t * pxEndPoint;
822	
823	    configASSERT( pxInterface != NULL );
824	    configASSERT( pxInterface->pfInitialise != NULL );
825	    /* Stop the ARP timer while there is no network. */
826	    vIPSetARPTimerEnableState( pdFALSE );
```

ちょっと進んだけどconnectはエラーが返ってるらしい
```
sudo qemu-system-arm -machine mps2-an385 -monitor null -semihosting --semihosting-config enable=on,target=native -kernel ./build/RTOSDemo.axf -serial stdio -nographic -gdb tcp::12345 -S
[0] NetworkInterface.c(118) pxFillInterfaceDescriptor mac:0 fr:0x5e19 
[67b4] NetworkInterface.c(96) xApplicationGetRandomNumber  fr:0x4a93 
[2280] app_server.c(11) server_task  fr:0x281 
[2280] app_server.c(28) vCreateTCPServerSocket sock:536947616 fr:0xe08d 
[2ab8] app_client.c(28) client_task  fr:0x281 
[2ab8] app_client.c(44) vTCPSend IN fr:0xdf71 
[2ab8] app_client.c(54) vTCPSend socket fr:0xdf71 
[67b4] NetworkInterface.c(96) xApplicationGetRandomNumber  fr:0x937b 
[2280] app_server.c(42) vCreateTCPServerSocket bind fr:0xe08d 
[2280] app_server.c(45) vCreateTCPServerSocket listen fr:0xe08d 
[2ab8] app_client.c(84) vTCPSend not connected fr:0xdf71 
[2ab8] app_client.c(105) vTCPSend OUT fr:0xdf71 
[67b4] NetworkInterface.c(96) xApplicationGetRandomNumber  fr:0x498f 

```

[ここまでのコード](https://github.com/tyano461/freertos_cm3/commit/7e4bdbd3596921b1bd0e99d90fe00884635aad1e)

----

# 参考
https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html