FreeRTOSを動かしてみる(7)

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

# qemuを改造してホストのプロセスとやり取りする

## 枠を作る

<details>
<summary>適当にこんな感じで</summary>


```diff
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
index 292a180ad2..53198d73af 100644
--- a/hw/arm/mps2.c
+++ b/hw/arm/mps2.c
@@ -111,6 +111,17 @@ OBJECT_DECLARE_TYPE(MPS2MachineState, MPS2MachineClass, MPS2_MACHINE)
  */
 #define REFCLK_FRQ (1 * 1000 * 1000)
 
+static void add_extra_mmio_an385(MPS2MachineState* mms, MemoryRegion *sysmem);
+static uint64_t an385_ex_mmio_read(void *opaque, hwaddr, unsigned size);
+static void an385_ex_mmio_write(void *opaque, hwaddr addr, uint64_t value, unsigned size);
+
+
+static MemoryRegionOps ex_mmio_op = {
+    .read  = an385_ex_mmio_read,
+    .write = an385_ex_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN
+};
+
 /* Initialize the auxiliary RAM region @mr and map it into
  * the memory map at @base.
  */
@@ -207,6 +218,8 @@ static void mps2_common_init(MachineState *machine)
 
     switch (mmc->fpga_type) {
     case FPGA_AN385:
+        add_extra_mmio_an385(mms, system_memory);
+        /* fall through. */
     case FPGA_AN386:
     case FPGA_AN500:
         make_ram(&mms->ssram1, "mps.ssram1", 0x0, 0x400000);
@@ -579,3 +592,38 @@ static void mps2_machine_init(void)
 }
 
 type_init(mps2_machine_init);
+
+#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
+#define ERRRET(c,s,...) \
+    do { \
+        if (c) { \
+            g_print("%s(%d) %s " s "\n", __FILENAME__, __LINE__, __func__, ##__VA_ARGS__); \
+            goto error_return; \
+        } \
+    } while(0)
+
+#define d(s,...) \
+    do { \
+        g_print("%s(%d) %s " s "\n", __FILENAME__, __LINE__, __func__, ##__VA_ARGS__); \
+    } while(0)
+
+static void add_extra_mmio_an385(MPS2MachineState* mms, MemoryRegion *sysmem) {
+    MemoryRegion *ex_mmio;
+    ex_mmio = g_new(MemoryRegion, 1);
+    ERRRET(!ex_mmio, "g_new failed.");
+
+    memory_region_init_io(ex_mmio, OBJECT(mms), &ex_mmio_op, mms, "an385.ex_mmio", 0x08000000);
+    memory_region_add_subregion(sysmem, 0x28000000, ex_mmio);
+    
+    d("added to 0x28000000");
+error_return:
+    return;
+}
+
+static uint64_t an385_ex_mmio_read(void *opaque, hwaddr addr, unsigned size) {
+    d("");
+    return 0;
+}
+static void an385_ex_mmio_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) {
+    d("");
+}

```

</details>

FreeRTOS側にも変更を入れる
これはアドレス指定して読み書きするだけ

<details>
<summary>どこでも良いけどとりあえずタスクの頭に入れてみた</summary>

```diff
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 fd3172b3..3a642e7d 100644
--- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_client.c
+++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/app_client.c
@@ -25,7 +25,9 @@ void client_task(void *param)
 {
     (void)param;
     size_t len;
-    d("");
+    uint32_t val = *(uint32_t*)0x28000000;
+    d("val:%lu", val);
+    *(uint32_t*)0x28000000 = 1;
 
     len = snlen(msg, BUF_SIZE - 1);
     memcpy(buf, msg, len + 1);

```

</details>

```
CORTEX_M3_MPS2_QEMU_GCC$ sudo /home/voyager/workspace/oss/build_qemu/qemu-system-arm -machine mps2-an385 -m 16 -monitor null -semihosting --semihosting-config enable=on,target=native -kernel ./build/RTOSDemo.axf -serial stdio -nographic 
mps2.c(618) add_extra_mmio_an385 added to 0x28000000
[0000] NetworkInterface.c(132) pxFillInterfaceDescriptor mac:0 fr:0x53a7 
[1cd8] NetworkInterface.c(192) ether_task  fr:0x281 
[67ac] FreeRTOS_IP.c(1397) xSendEventStructToIPTask et:0 fr:0x56c1 
[2510] app_server.c(14) server_task  fr:0x281 
[2510] app_server.c(31) vCreateTCPServerSocket sock:536948136 fr:0xd919 
[2510] FreeRTOS_IP.c(1397) xSendEventStructToIPTask et:9 fr:0x98e1 
mps2.c(624) an385_ex_mmio_read 
[2d48] app_client.c(29) client_task val:0 fr:0x281 
mps2.c(628) an385_ex_mmio_write 
[2d48] app_client.c(46) vTCPSend IN fr:0xd7fd 
```
ちゃんと通ってる


## ホストプロセスとの通信部分
手段は色々考えられるがUDPが一番楽で良いかな

あと、フォーマットも決めとく必要がありそう

なのでこんな感じで
1Mずつあれば良いんじゃないかな

| name | addr | size | details | remarks |
|-|-|-|-| -|
| wlock | 0x28000000 | 4 | 0:none 1:writing | FreeRTOS -> qemu |
| wsize | 0x28000004 | 4 |  | |
| wdata | 0x28000010 | 0x100000 - 16 | to 0x280fffff | |
| rlock | 0x28100000 | 4 | 0:none 1:writing | qemu -> FreeRTOS |
| rsize | 0x28100004 | 4 |  | |
| rdata |0x28100010 | 0x100000 - 16 | to 0x281fffff | |

というわけでシステム構成変更

![image](https://kroki.io/graphviz/svg/eNp9U8tuwjAQvOcrLJ_LF0TJCVWqVKmoTU-oqgxeiNXEcdc2BSH-vfEDcEjAh8jZmZ1d79hcbJGpmszJMSP9QiZ_uEBSkGqe-4iEPxcsDFrIsxDqOCx1zRQUdNXt6RPR5tD0P9hZyYHTL0_TdhXE143VBvD7VUi7j4XcatgKmoL6MM0u4VFexXALJklMkk3AmFKJgseFWkbOyyJ2dM29YGBqQAnmliHUrHS0fhjukKZOCKfLbl0jh939zrlt28N04wFS2K1Bazpg6K6Fc3-f88Vk5VGpX2jtdCWHDAtshurD4rfCzwjwXr193IgnBc4MOiLgAxPCdZswgkzJzEq848ZwLmEXvr1_ZFb6cWZXt7yv8bJ7fDOSdRmPkcR4f1W8ZfEVCLkT-jzWo39ShWYt5I6au8PkscEhyBzIpkGnn5ONw07_bCIBLQ==)

前よりちょっとスッキリした気がする。
ただ、IP通信を行うための土台をIP通信で実装するという
だんだんわけがわからなくなってきているのも確か。

dummy processの受け口は2つ必要
コマンドで条件分岐とか面倒なことはせずに
スレッドもポートも2つ用意する。


## FreeRTOSからホストのNICデバイスドライバまでの送信

片方だけつながったサンプル

- [qemu側の変更](https://github.com/tyano461/qemu_an385_ex/commit/344773b2830853854ec0aa69d81286e330b2f444)
- [FreeRTOSアプリ(ドライバ内ではなく、アプリから直接疎通確認)](https://github.com/tyano461/freertos_cm3/commit/d0fbdeeccf2da64b6c51b1bf2f963b6eec2855fa)
- [ホストのスタブ](https://github.com/tyano461/virtether/commit/835fe5356682805111db06d09109c06ac36ca704)

スタブを起動させて
```
./run.sh 1
```
qemuを起動させると
```
sudo /path/to/build_qemu/qemu-system-arm -machine mps2-an385 -m 16 -monitor null -semihosting --semihosting-config enable=on,target=native -kernel ./build/RTOSDemo.axf -serial stdio -nographic
```

ホストの/var/log/messagesに以下が表示されるので
```
Dec 15 16:02:41 fedora kernel: virtether.c(581) veth_cdev_open 
Dec 15 16:02:41 fedora kernel: virtether.c(575) veth_cdev_write 
Dec 15 16:02:41 fedora kernel: virtether.c(588) veth_cdev_release written:5
Dec 15 16:02:41 fedora kernel: virtether.c(388) veth_netdev_rx called netif_receive_skb
```

こんな感じで赤字部分がつながっていることが確認出来る。
(FreeRTOSのドライバは今はすっ飛ばしてるし、dummyの受け口も１個しか作ってない)

![image](https://kroki.io/graphviz/svg/eNp9U0FuwyAQvPsVyOfkBZZziipVqtSoTU9RVRGziVFsQxdIE0X5ew3Yjo1pOVhmZ3Zm2QXGj0hlSdbklpB2IW1OjCPJyXaduUgDPzaYazSQJT4kGOxUSSXk6V5c0gVR-lq1GxSmYcDST0dTZu_Fi8ooDfj1whtz6Yzsqugeqjx14TQZwrO8LcUj6FHiKFl7jEo5UnA4l7uO87zpKnrkDhjoErABHTK4XK4srW2GPaQuR4T78FeUyOD8d-XM1PU1XriHJIoClEonDCVq6Ov7WG-izjOrb6hN3MkiU4PDVH1qHgo_IcDb9vU9EB8Z9Ix0RsB_huCvW2QQJCazXFluISrRzgOHOxZl-ZnR4hSQ7kEf_bedMlmuXNOTx0z99Gd-6MmHf5DQ3Qp7JNw_mIuZXM_y1czt3AV1F6V7e7w5c9UP8-Yecq5oDZmlZrY5WXfgKUgtSOOg1c_IwWL3X3fKIxQ=)


----

今回はちょっとだけFreeRTOS触ったのでタグをつけました