前回の続き
qemuを改造してホストのプロセスとやり取りする
枠を作る
適当にこんな感じで
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("");
+}
FreeRTOS側にも変更を入れる
これはアドレス指定して読み書きするだけ
どこでも良いけどとりあえずタスクの頭に入れてみた
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);
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 |
というわけでシステム構成変更
前よりちょっとスッキリした気がする。
ただ、IP通信を行うための土台をIP通信で実装するという
だんだんわけがわからなくなってきているのも確か。
dummy processの受け口は2つ必要
コマンドで条件分岐とか面倒なことはせずに
スレッドもポートも2つ用意する。
FreeRTOSからホストのNICデバイスドライバまでの送信
片方だけつながったサンプル
スタブを起動させて
./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の受け口も1個しか作ってない)
今回はちょっとだけFreeRTOS触ったのでタグをつけました