From 5191bd83a7a114a888eff63d6ec0521a7fbd0c1c Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Wed, 25 May 2022 12:54:57 +0200 Subject: [PATCH 01/14] work on shelly --- lib/spawn/spawn.c | 10 +++++++++ usr/init/main.c | 15 +++++++------ usr/shelly/Hakefile | 3 ++- usr/shelly/shelly.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ usr/shelly/shelly.h | 18 ++++++++++++++++ 5 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 usr/shelly/shelly.h diff --git a/lib/spawn/spawn.c b/lib/spawn/spawn.c index 8727794..4b2be44 100644 --- a/lib/spawn/spawn.c +++ b/lib/spawn/spawn.c @@ -15,6 +15,7 @@ #include #include +#include extern struct bootinfo *bi; extern coreid_t my_core_id; @@ -508,8 +509,12 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, if (strcmp(argv[0], "enet") == 0) { arg0_base = IMX8X_ENET_BASE; arg0_size = IMX8X_ENET_SIZE; + } else if (strcmp(argv[0], "shelly") == 0) { + arg0_base = IMX8X_UART3_BASE; + arg0_size = IMX8X_UART_SIZE; } + //TODO: also map GIC (interrupt controller) for shelly si->cspace_l2_cnode_argcn = NULL_CNODE; if (arg0_base != 0) { err = cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_ARGCN, &si->cspace_l2_cnode_argcn); @@ -518,6 +523,11 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, .cnode = si->cspace_l2_cnode_argcn, .slot = 0 }; + char buf[256]; + debug_print_cap_at_capref(buf, 256, cap_io); + debug_printf(buf); + printf("\n"); + debug_printf("offset=%x\n", arg0_base - IMX8X_START_DEV_RANGE); err = cap_retype(arg0_cap, cap_io, (arg0_base - IMX8X_START_DEV_RANGE), ObjType_DevFrame, arg0_size, 1); if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_RETYPE); } diff --git a/usr/init/main.c b/usr/init/main.c index ae9dd09..ab1a5d7 100644 --- a/usr/init/main.c +++ b/usr/init/main.c @@ -147,6 +147,13 @@ bsp_main(int argc, char *argv[]) { waitset_init(&urpc_to_app_ws); thread_create(urpc_client_loop, &urpc_to_app_ws); + //spawn shell + struct spawninfo shelly_si; + domainid_t shelly_pid; + err = spawn_load_by_name("shelly", &shelly_si, &shelly_pid); + if (err_is_fail(err)) { + DEBUG_ERR(err, "when spawning shelly"); + } // Grading grading_test_late(); @@ -313,14 +320,6 @@ app_main(int argc, char *argv[]) { // Grading grading_test_late(); - //spawn shell - struct spawninfo shelly_si; - domainid_t shelly_pid; - err = spawn_load_by_name("shelly", &shelly_si, &shelly_pid); - if (err_is_fail(err)) { - DEBUG_ERR(err, "when spawning shelly"); - } - debug_printf("Message handler loop\n"); // Hang around struct waitset *default_ws = get_default_waitset(); diff --git a/usr/shelly/Hakefile b/usr/shelly/Hakefile index 87f3d05..532146f 100644 --- a/usr/shelly/Hakefile +++ b/usr/shelly/Hakefile @@ -13,6 +13,7 @@ [ build application { target = "shelly", - cFiles = [ "shelly.c" ] + cFiles = [ "shelly.c" ], + addLibraries = [ "lpuart" ] } ] diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 1921974..ae77a16 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -6,9 +6,60 @@ #include #include +#include +#include +#include +#include #include +#include +#include "shelly.h" + +static void shelly_interrupt_handler(void * arg) { + struct shelly_st shelly_s = (struct shelly_st) arg; + debug_printf("[shelly_interrupt_handler]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + return; +} int main(int argc, char *argv[]) { + errval_t err; debug_printf("welcome to shelly!\n"); + + struct shelly_st shelly_s; + //afeer: map device registers + struct capref cap_arg0 = { + .cnode = cnode_arg, + .slot = 0 + }; + err = paging_map_frame_attr(get_current_paging_state(), + (void **) &shelly_s.dev_base, IMX8X_UART_SIZE, + cap_arg0, VREGION_FLAGS_READ_WRITE_NOCACHE); + if (err_is_fail(err)) return err; + + struct gic_dist_s * gic_s; + //TODO: map gic space + err = gic_dist_init(gic_s, NULL); + if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't init gic_dist interrupts"); + + struct lpuart_s * uart_s; + err = lpuart_init(&uart_s, shelly_s.dev_base); + if (err_is_fail(err)) { + USER_PANIC_ERR(err, "couldn't init lpuart"); + } + + struct capref inter_cap; + err = inthandler_alloc_dest_irq_cap(IMX8X_UART3_INT, &inter_cap); + if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't alloc dest cap"); + + struct waitset ws = get_default_waitset() + // waitset_init(&ws); + + err = inthandler_setup(inter_cap, &ws, MKCLOSURE(shelly_interrupt_handler, shelly_s)); + if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't setup interrupt handler"); + + err = gic_dist_enable_interrupt(gic_s, IMX8X_UART3_INT, 0b11111111, 0); + if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable gic interrupts"); + + err = lpuart_enable_interrupt(uart_s); + if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable lpuart interrupts"); } \ No newline at end of file diff --git a/usr/shelly/shelly.h b/usr/shelly/shelly.h new file mode 100644 index 0000000..67341eb --- /dev/null +++ b/usr/shelly/shelly.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2019, ETH Zurich. + * All rights reserved. + * + * This file is distributed under the terms in the attached LICENSE file. + * If you do not find this file, copies can be found by writing to: + * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. + */ + +#ifndef SHELLY_H_ +#define SHELLY_H_ + +struct shelly_st { + void * dev_base; + size_t dev_size; +}; + +#endif // ndef SHELLY_H_ From 1a600c24091e2038d7d0f8fe035cde23461a105d Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Wed, 25 May 2022 13:14:58 +0200 Subject: [PATCH 02/14] fix minor syntax bugs --- .vscode/tasks.json | 8 ++++---- usr/shelly/Hakefile | 2 +- usr/shelly/shelly.c | 9 +++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f92d424..88b0470 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,7 +4,7 @@ { "label": "Initialize QEMU Build Directory", "type": "shell", - "command": "mkdir -p ${BFBUILD_QEMU} && cd ${BFBUILD_QEMU} && ${BFAOS}/hake/hake.sh -s ${BFAOS} && make -j7 QEMU", + "command": "source ${HOME}/envvars.sh && mkdir -p ${BFBUILD_QEMU} && cd ${BFBUILD_QEMU} && ${BFAOS}/hake/hake.sh -s ${BFAOS} && make -j7 QEMU", "group": { "kind": "build", "isDefault": true @@ -13,7 +13,7 @@ { "label": "Build and Run QEMU", "type": "shell", - "command": "cd ${BFBUILD_QEMU} && make qemu_a57 | tee ${BFBUILD_QEMU}/full_output.log", + "command": "source ${HOME}/envvars.sh && cd ${BFBUILD_QEMU} && make qemu_a57 | tee ${BFBUILD_QEMU}/full_output.log", "group": { "kind": "build", "isDefault": true @@ -22,7 +22,7 @@ { "label": "Initialize Toradex Build Directory", "type": "shell", - "command": "mkdir -p ${BFBUILD} && cd ${BFBUILD} && ${BFAOS}/hake/hake.sh -s ${BFAOS} -a armv8 && make -j7 QEMU", + "command": "source ${HOME}/envvars.sh && mkdir -p ${BFBUILD} && cd ${BFBUILD} && ${BFAOS}/hake/hake.sh -s ${BFAOS} -a armv8 && make -j7 QEMU", "group": { "kind": "build", "isDefault": true @@ -31,7 +31,7 @@ { "label": "Build and Run Toradex", "type": "shell", - "command": "cd ${BFBUILD} && make -j7 imx8x && make usbboot_imx8x", + "command": "source ${HOME}/envvars.sh && cd ${BFBUILD} && make -j7 imx8x && make usbboot_imx8x", "group": { "kind": "build", "isDefault": true diff --git a/usr/shelly/Hakefile b/usr/shelly/Hakefile index 532146f..562fc05 100644 --- a/usr/shelly/Hakefile +++ b/usr/shelly/Hakefile @@ -14,6 +14,6 @@ { target = "shelly", cFiles = [ "shelly.c" ], - addLibraries = [ "lpuart" ] + addLibraries = [ "lpuart", "gic_dist" ] } ] diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index ae77a16..9469dfe 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -14,8 +14,9 @@ #include #include "shelly.h" +__attribute__((__used__)) static void shelly_interrupt_handler(void * arg) { - struct shelly_st shelly_s = (struct shelly_st) arg; + // struct shelly_st * shelly_s = (struct shelly_st *) arg; debug_printf("[shelly_interrupt_handler]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); return; } @@ -38,7 +39,7 @@ int main(int argc, char *argv[]) struct gic_dist_s * gic_s; //TODO: map gic space - err = gic_dist_init(gic_s, NULL); + err = gic_dist_init(&gic_s, NULL); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't init gic_dist interrupts"); struct lpuart_s * uart_s; @@ -51,10 +52,10 @@ int main(int argc, char *argv[]) err = inthandler_alloc_dest_irq_cap(IMX8X_UART3_INT, &inter_cap); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't alloc dest cap"); - struct waitset ws = get_default_waitset() + struct waitset * ws = get_default_waitset(); // waitset_init(&ws); - err = inthandler_setup(inter_cap, &ws, MKCLOSURE(shelly_interrupt_handler, shelly_s)); + err = inthandler_setup(inter_cap, ws, MKCLOSURE(shelly_interrupt_handler, (void *) &shelly_s)); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't setup interrupt handler"); err = gic_dist_enable_interrupt(gic_s, IMX8X_UART3_INT, 0b11111111, 0); From b892aeaeb6b4f8c2be4ea492a5dbace016f207e4 Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Wed, 25 May 2022 16:01:24 +0200 Subject: [PATCH 03/14] shelly interrupt handler working --- include/spawn/spawn.h | 1 + lib/spawn/spawn.c | 29 +++++++++++++++++++---- usr/shelly/shelly.c | 55 ++++++++++++++++++++++++++++++++++++------- usr/shelly/shelly.h | 12 ++++++++-- 4 files changed, 81 insertions(+), 16 deletions(-) diff --git a/include/spawn/spawn.h b/include/spawn/spawn.h index 8258421..6c9c51d 100644 --- a/include/spawn/spawn.h +++ b/include/spawn/spawn.h @@ -53,6 +53,7 @@ struct spawninfo { struct capref cspace_cap_dispframe; // < A capability to the dispatcher frame, used to communicate between a process and the CPU driver. struct capref cspace_cap_argspage; // < A page containing a list of command line arguments. struct capref cspace_cap_vspace; // < The frame capability used to store the serialized vspace + struct capref cspace_cap_irq; // < the irq capability for interrupts struct capref vspace_cap_l0_pagetable; diff --git a/lib/spawn/spawn.c b/lib/spawn/spawn.c index 4b2be44..e579ac8 100644 --- a/lib/spawn/spawn.c +++ b/lib/spawn/spawn.c @@ -468,6 +468,9 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, si->cspace_cap_vspace.cnode = si->cspace_l2_cnode_taskcn; si->cspace_cap_vspace.slot = TASKCN_SLOT_VSPACE; + si->cspace_cap_irq.cnode = si->cspace_l2_cnode_taskcn; + si->cspace_cap_irq.slot = TASKCN_SLOT_IRQ; + err = cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC0, &si->cspace_l2_cnode_slot_alloc_0); if (err_is_fail(err)) return err; err = cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC1, &si->cspace_l2_cnode_slot_alloc_1); @@ -495,6 +498,9 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, err = cap_retype(si->cspace_cap_selfep, si->cspace_cap_dispatcher, 0, ObjType_EndPointLMP, 0, 1); if (err_is_fail(err)) return err_push(err, SPAWN_ERR_CREATE_SELFEP); + err = cap_copy(si->cspace_cap_irq, cap_irq); + if (err_is_fail(err)) return err; + // give the child an endpoint to talk to init lmp_chan_init(&si->init_chan); err = endpoint_create(DEFAULT_LMP_BUF_WORDS, &si->init_chan.local_cap, &si->init_chan.endpoint); @@ -506,12 +512,16 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, // Set up capability arguments. This would ideally be passed somehow as an argument to spawn instead. size_t arg0_base = 0; size_t arg0_size = 0; + size_t arg1_base = 0; + size_t arg1_size = 0; if (strcmp(argv[0], "enet") == 0) { arg0_base = IMX8X_ENET_BASE; arg0_size = IMX8X_ENET_SIZE; } else if (strcmp(argv[0], "shelly") == 0) { arg0_base = IMX8X_UART3_BASE; arg0_size = IMX8X_UART_SIZE; + arg1_base = IMX8X_GIC_DIST_BASE; + arg1_size = IMX8X_GIC_DIST_SIZE; } //TODO: also map GIC (interrupt controller) for shelly @@ -523,15 +533,24 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, .cnode = si->cspace_l2_cnode_argcn, .slot = 0 }; - char buf[256]; - debug_print_cap_at_capref(buf, 256, cap_io); - debug_printf(buf); - printf("\n"); - debug_printf("offset=%x\n", arg0_base - IMX8X_START_DEV_RANGE); + // char buf[256]; + // debug_print_cap_at_capref(buf, 256, cap_io); + // debug_printf(buf); + // printf("\n"); + // debug_printf("offset=%x\n", arg0_base - IMX8X_START_DEV_RANGE); err = cap_retype(arg0_cap, cap_io, (arg0_base - IMX8X_START_DEV_RANGE), ObjType_DevFrame, arg0_size, 1); if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_RETYPE); } + if (arg1_base != 0) { + struct capref arg1_cap = { + .cnode = si->cspace_l2_cnode_argcn, + .slot = 1 + }; + err = cap_retype(arg1_cap, cap_io, (arg1_base - IMX8X_START_DEV_RANGE), ObjType_DevFrame, arg1_size, 1); + if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_RETYPE); + } + // - Setup the child's vspace // afeer: create level 0 page table // the l0 page table is in the first slot (PAGECN_SLOT_VROOT) of the pagecn cnode. diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 9469dfe..9922ce4 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -17,7 +17,7 @@ __attribute__((__used__)) static void shelly_interrupt_handler(void * arg) { // struct shelly_st * shelly_s = (struct shelly_st *) arg; - debug_printf("[shelly_interrupt_handler]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + SHELLY_DEBUG("[shelly_interrupt_handler]\n"); return; } @@ -27,40 +27,77 @@ int main(int argc, char *argv[]) debug_printf("welcome to shelly!\n"); struct shelly_st shelly_s; - //afeer: map device registers + + //afeer: map lpuart registers struct capref cap_arg0 = { .cnode = cnode_arg, .slot = 0 }; err = paging_map_frame_attr(get_current_paging_state(), - (void **) &shelly_s.dev_base, IMX8X_UART_SIZE, + (void **) &shelly_s.lpuart_base, IMX8X_UART_SIZE, cap_arg0, VREGION_FLAGS_READ_WRITE_NOCACHE); - if (err_is_fail(err)) return err; + if (err_is_fail(err)) USER_PANIC_ERR(err, "while mapping lpuart registers"); + SHELLY_DEBUG("mapped lpuart\n"); + + //afeer: map gic registers + struct capref cap_arg1 = { + .cnode = cnode_arg, + .slot = 1 + }; + err = paging_map_frame_attr(get_current_paging_state(), + (void**) &shelly_s.gic_base, IMX8X_GIC_DIST_SIZE, + cap_arg1, VREGION_FLAGS_READ_WRITE_NOCACHE); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while mapping gic registers"); + + SHELLY_DEBUG("mapped gic\n"); + + //afeer: init gic driver struct gic_dist_s * gic_s; - //TODO: map gic space - err = gic_dist_init(&gic_s, NULL); + err = gic_dist_init(&gic_s, shelly_s.gic_base); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't init gic_dist interrupts"); + SHELLY_DEBUG("initialized gic driver\n"); + + //afeer: init lpuart driver struct lpuart_s * uart_s; - err = lpuart_init(&uart_s, shelly_s.dev_base); + err = lpuart_init(&uart_s, shelly_s.lpuart_base); if (err_is_fail(err)) { USER_PANIC_ERR(err, "couldn't init lpuart"); } + SHELLY_DEBUG("initialized lpuart driver\n"); + struct capref inter_cap; err = inthandler_alloc_dest_irq_cap(IMX8X_UART3_INT, &inter_cap); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't alloc dest cap"); - struct waitset * ws = get_default_waitset(); - // waitset_init(&ws); + SHELLY_DEBUG("created interrupt cap\n"); + char buf[256]; + debug_print_cap_at_capref(buf, 256, inter_cap); + debug_printf(buf); + struct waitset * ws = get_default_waitset(); err = inthandler_setup(inter_cap, ws, MKCLOSURE(shelly_interrupt_handler, (void *) &shelly_s)); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't setup interrupt handler"); + SHELLY_DEBUG("setup interrupt handler\n"); + err = gic_dist_enable_interrupt(gic_s, IMX8X_UART3_INT, 0b11111111, 0); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable gic interrupts"); + SHELLY_DEBUG("enabled gic interrupt\n"); + err = lpuart_enable_interrupt(uart_s); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable lpuart interrupts"); + + SHELLY_DEBUG("enabled lpuart interrupt\n"); + + while (true) { + err = event_dispatch(ws); + if (err_is_fail(err)) { + DEBUG_ERR(err, "in event_dispatch"); + abort(); + } + } } \ No newline at end of file diff --git a/usr/shelly/shelly.h b/usr/shelly/shelly.h index 67341eb..8ea68fc 100644 --- a/usr/shelly/shelly.h +++ b/usr/shelly/shelly.h @@ -10,9 +10,17 @@ #ifndef SHELLY_H_ #define SHELLY_H_ +#define SHELLY_DEBUG_ON 1 + +#if defined(SHELLY_DEBUG_ON) +#define SHELLY_DEBUG(x...) debug_printf("[SHELLY_DEBUG] " x); +#else +#define SHELLY_DEBUG(x, ...) ((void)0) +#endif + struct shelly_st { - void * dev_base; - size_t dev_size; + void * lpuart_base; // < virtual address of the lpuart device registers + void * gic_base; // < virtual address of the gic device registers }; #endif // ndef SHELLY_H_ From 5773c47d49c244cf38437ffc14d84f1ab1d5ed34 Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Wed, 25 May 2022 16:18:20 +0200 Subject: [PATCH 04/14] input/output for shelly seems to be working! poggers --- usr/shelly/shelly.c | 32 +++++++++++++++++++------------- usr/shelly/shelly.h | 6 ++++++ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 9922ce4..e97872f 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -16,9 +16,16 @@ __attribute__((__used__)) static void shelly_interrupt_handler(void * arg) { - // struct shelly_st * shelly_s = (struct shelly_st *) arg; - SHELLY_DEBUG("[shelly_interrupt_handler]\n"); - return; + errval_t err; + struct shelly_st * shelly_s = (struct shelly_st *) arg; + // SHELLY_DEBUG("[shelly_interrupt_handler]\n"); + + char input_char; + err = lpuart_getchar(shelly_s->uart_s, &input_char); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to get character"); + + err = lpuart_putchar(shelly_s->uart_s, input_char); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); } int main(int argc, char *argv[]) @@ -26,7 +33,8 @@ int main(int argc, char *argv[]) errval_t err; debug_printf("welcome to shelly!\n"); - struct shelly_st shelly_s; + struct shelly_st * shelly_s = calloc(sizeof(struct shelly_st), 1); + assert(shelly_s); //afeer: map lpuart registers struct capref cap_arg0 = { @@ -34,7 +42,7 @@ int main(int argc, char *argv[]) .slot = 0 }; err = paging_map_frame_attr(get_current_paging_state(), - (void **) &shelly_s.lpuart_base, IMX8X_UART_SIZE, + (void **) &shelly_s->lpuart_base, IMX8X_UART_SIZE, cap_arg0, VREGION_FLAGS_READ_WRITE_NOCACHE); if (err_is_fail(err)) USER_PANIC_ERR(err, "while mapping lpuart registers"); @@ -46,22 +54,20 @@ int main(int argc, char *argv[]) .slot = 1 }; err = paging_map_frame_attr(get_current_paging_state(), - (void**) &shelly_s.gic_base, IMX8X_GIC_DIST_SIZE, + (void**) &shelly_s->gic_base, IMX8X_GIC_DIST_SIZE, cap_arg1, VREGION_FLAGS_READ_WRITE_NOCACHE); if (err_is_fail(err)) USER_PANIC_ERR(err, "while mapping gic registers"); SHELLY_DEBUG("mapped gic\n"); //afeer: init gic driver - struct gic_dist_s * gic_s; - err = gic_dist_init(&gic_s, shelly_s.gic_base); + err = gic_dist_init(&shelly_s->gic_s, shelly_s->gic_base); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't init gic_dist interrupts"); SHELLY_DEBUG("initialized gic driver\n"); //afeer: init lpuart driver - struct lpuart_s * uart_s; - err = lpuart_init(&uart_s, shelly_s.lpuart_base); + err = lpuart_init(&shelly_s->uart_s, shelly_s->lpuart_base); if (err_is_fail(err)) { USER_PANIC_ERR(err, "couldn't init lpuart"); } @@ -78,17 +84,17 @@ int main(int argc, char *argv[]) debug_printf(buf); struct waitset * ws = get_default_waitset(); - err = inthandler_setup(inter_cap, ws, MKCLOSURE(shelly_interrupt_handler, (void *) &shelly_s)); + err = inthandler_setup(inter_cap, ws, MKCLOSURE(shelly_interrupt_handler, (void *) shelly_s)); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't setup interrupt handler"); SHELLY_DEBUG("setup interrupt handler\n"); - err = gic_dist_enable_interrupt(gic_s, IMX8X_UART3_INT, 0b11111111, 0); + err = gic_dist_enable_interrupt(shelly_s->gic_s, IMX8X_UART3_INT, 0b11111111, 0); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable gic interrupts"); SHELLY_DEBUG("enabled gic interrupt\n"); - err = lpuart_enable_interrupt(uart_s); + err = lpuart_enable_interrupt(shelly_s->uart_s); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable lpuart interrupts"); SHELLY_DEBUG("enabled lpuart interrupt\n"); diff --git a/usr/shelly/shelly.h b/usr/shelly/shelly.h index 8ea68fc..33497fa 100644 --- a/usr/shelly/shelly.h +++ b/usr/shelly/shelly.h @@ -18,9 +18,15 @@ #define SHELLY_DEBUG(x, ...) ((void)0) #endif +#include +#include + struct shelly_st { void * lpuart_base; // < virtual address of the lpuart device registers void * gic_base; // < virtual address of the gic device registers + + struct lpuart_s * uart_s; // < state of the uart driver + struct gic_dist_s * gic_s; // < state of the gic driver }; #endif // ndef SHELLY_H_ From 99c30cb2e7bfd70bd56e88814cd5063ca1f81eeb Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Mon, 30 May 2022 23:50:04 +0200 Subject: [PATCH 05/14] sloooooooooow --- include/aos/ump_binding.h | 1 + lib/aos/Hakefile | 1 + lib/aos/aos_rpc.c | 27 ++++---- lib/aos/init.c | 40 +++++++++--- lib/spawn/rpc_server.c | 51 ++++++++------- usr/shelly/shelly.c | 127 ++++++++++++++++++++++++++++++++++---- usr/shelly/shelly.h | 25 ++++++-- 7 files changed, 211 insertions(+), 61 deletions(-) diff --git a/include/aos/ump_binding.h b/include/aos/ump_binding.h index 6e4029a..f19f823 100644 --- a/include/aos/ump_binding.h +++ b/include/aos/ump_binding.h @@ -8,6 +8,7 @@ enum ump_server_id { UMP_SERVER_ECHO, UMP_SERVER_NET, + UMP_SERVER_SHELLY, UMP_SERVER_COUNT // How many servers exist }; diff --git a/lib/aos/Hakefile b/lib/aos/Hakefile index 909e0ea..1a2d3f8 100644 --- a/lib/aos/Hakefile +++ b/lib/aos/Hakefile @@ -53,6 +53,7 @@ "sys_debug.c", "syscalls.c", "systime.c", + "shelly_client.c", "thread_once.c", "thread_sync.c", "threads.c", diff --git a/lib/aos/aos_rpc.c b/lib/aos/aos_rpc.c index 12ac19e..8481355 100644 --- a/lib/aos/aos_rpc.c +++ b/lib/aos/aos_rpc.c @@ -17,6 +17,7 @@ #include #include +#include static void noop_callback(void *arg) { } @@ -166,14 +167,16 @@ aos_rpc_serial_getchar(struct aos_rpc *rpc, char *retc) { // Implement functionality to request a character from // the serial driver. errval_t err; - uintptr_t retval; + // uintptr_t retval; - err = do_aos_rpc( - rpc, RPC_MTYPE_SERIAL_GETCHAR, - NULL_CAP, 0, 0, 0, - NULL, NULL, &retval, NULL); + err = shelly_client_getchar(rpc, retc); - *retc = retval; + // err = do_aos_rpc( + // rpc, RPC_MTYPE_SERIAL_GETCHAR, + // NULL_CAP, 0, 0, 0, + // NULL, NULL, &retval, NULL); + + // *retc = retval; return err; } @@ -184,11 +187,13 @@ aos_rpc_serial_putchar(struct aos_rpc *rpc, char c) { // serial port. errval_t err; - err = do_aos_rpc( - rpc, RPC_MTYPE_SERIAL_PUTCHAR, - NULL_CAP, 0, c, 0, - NULL, NULL, NULL, NULL - ); + err = shelly_client_putchar(rpc, c); + + // err = do_aos_rpc( + // rpc, RPC_MTYPE_SERIAL_PUTCHAR, + // NULL_CAP, 0, c, 0, + // NULL, NULL, NULL, NULL + // ); return err; } diff --git a/lib/aos/init.c b/lib/aos/init.c index 236180d..3092cf8 100644 --- a/lib/aos/init.c +++ b/lib/aos/init.c @@ -30,6 +30,8 @@ #include "init.h" #include +#include + /// Are we the init domain (and thus need to take some special paths)? static bool init_domain; static bool init_chan_initialized; @@ -103,28 +105,45 @@ static void handle_init_recv(void *arg) static size_t aos_terminal_write(const char *buf, size_t len) { + errval_t err; if(len == 0) return 0; struct aos_rpc *rpc = aos_rpc_get_serial_channel(); - if (rpc == NULL) { - debug_printf("[aos_terminal_write] RPC NOT YET INITIALIZED: %.*s\n", len, buf); - USER_PANIC("Make sure to initialize aos_rpc before barrelfish_libc_glue_init is called."); + for (int i = 0; i < len; ++i) { + err = aos_rpc_serial_putchar(rpc, buf[i]); + if (err_is_fail(err)) return err; } - return aos_rpc_serial_write(rpc, buf, len); + return SYS_ERR_OK; + // if (rpc == NULL) { + // debug_printf("[aos_terminal_write] RPC NOT YET INITIALIZED: %.*s\n", len, buf); + // USER_PANIC("Make sure to initialize aos_rpc before barrelfish_libc_glue_init is called."); + // } + + // return aos_rpc_serial_write(rpc, buf, len); } static size_t aos_terminal_read(char *buf, size_t len) { + errval_t err; if(len == 0) return 0; struct aos_rpc *rpc = aos_rpc_get_serial_channel(); - if (rpc == NULL) { - debug_printf("[aos_terminal_read] RPC NOT YET INITIALIZED: %.*s\n", len, buf); - USER_PANIC("Make sure to initialize aos_rpc before barrelfish_libc_glue_init is called."); + for (int i = 0; i < len; ++i) { + char in; + err = aos_rpc_serial_getchar(rpc, &in); + if (err_is_fail(err)) return err; + buf[i] = in; } - return aos_rpc_serial_read(rpc, buf, len); + return SYS_ERR_OK; + + // if (rpc == NULL) { + // debug_printf("[aos_terminal_read] RPC NOT YET INITIALIZED: %.*s\n", len, buf); + // USER_PANIC("Make sure to initialize aos_rpc before barrelfish_libc_glue_init is called."); + // } + + // return aos_rpc_serial_read(rpc, buf, len); } /* Set libc function pointers */ @@ -243,7 +262,12 @@ errval_t barrelfish_init_onthread(struct spawn_domain_params *params) * use it for the ram allocator */ //afeer: script page 135, tell domain to use our memserver. err = ram_alloc_set(NULL); + if (err_is_fail(err)) return err; + if (strcmp(params->argv[0], "shelly") != 0) { + err = shelly_client_init(); + if (err_is_fail(err)) DEBUG_ERR(err, "when trying to init shelly client"); + } // right now we don't have the nameservice & don't need the terminal // and domain spanning, so we return here return SYS_ERR_OK; diff --git a/lib/spawn/rpc_server.c b/lib/spawn/rpc_server.c index 5cfd525..725c80c 100644 --- a/lib/spawn/rpc_server.c +++ b/lib/spawn/rpc_server.c @@ -6,6 +6,7 @@ #include #include #include +#include extern coreid_t my_core_id; rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT]; @@ -189,34 +190,38 @@ static errval_t handle_rpc_get_ram_cap( return SYS_ERR_OK; } -static errval_t handle_rpc_serial_getchar( - struct generic_rpc_server *rpc, - struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1, - struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1 -) { +// static errval_t handle_rpc_serial_getchar( +// struct generic_rpc_server *rpc, +// struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1, +// struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1 +// ) { +// errval_t err; - grading_rpc_handler_serial_getchar(); +// grading_rpc_handler_serial_getchar(); +// char c; +// err = shelly_client_getchar(&c); +// *ret1 = c; +// if (err_is_fail(err)) return err; - // MARKER SHELL: Replace with UART call - *ret0 = getchar(); +// return SYS_ERR_OK; +// } - return SYS_ERR_OK; -} +// static errval_t handle_rpc_serial_putchar( +// struct generic_rpc_server *rpc, +// struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1, +// struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1 +// ) { +// errval_t err; -static errval_t handle_rpc_serial_putchar( - struct generic_rpc_server *rpc, - struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1, - struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1 -) { - char c = arg0; +// char c = arg0; - grading_rpc_handler_serial_putchar(c); +// grading_rpc_handler_serial_putchar(c); - // MARKER SHELL: Replace with UART call - putchar(c); +// err = shelly_client_putchar(c); +// if (err_is_fail(err)) return err; - return SYS_ERR_OK; -} +// return SYS_ERR_OK; +// } static errval_t handle_rpc_serial_write( struct generic_rpc_server *rpc, @@ -502,8 +507,8 @@ rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT] = { [RPC_MTYPE_SEND_NUMBER] = handle_rpc_send_number, [RPC_MTYPE_SEND_STRING] = handle_rpc_send_string, [RPC_MTYPE_GET_RAM_CAP] = handle_rpc_get_ram_cap, - [RPC_MTYPE_SERIAL_GETCHAR] = handle_rpc_serial_getchar, - [RPC_MTYPE_SERIAL_PUTCHAR] = handle_rpc_serial_putchar, + // [RPC_MTYPE_SERIAL_GETCHAR] = handle_rpc_serial_getchar, + // [RPC_MTYPE_SERIAL_PUTCHAR] = handle_rpc_serial_putchar, [RPC_MTYPE_SERIAL_WRITE] = handle_rpc_serial_write, [RPC_MTYPE_SERIAL_READ] = handle_rpc_serial_read, [RPC_MTYPE_PROCESS_SPAWN] = handle_rpc_process_spawn, diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index e97872f..3c13ef2 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -12,29 +12,125 @@ #include #include #include + +#include +#include +#include + #include "shelly.h" +//state that is shared for all clients +static struct shelly_st_global * global_state; + __attribute__((__used__)) static void shelly_interrupt_handler(void * arg) { errval_t err; - struct shelly_st * shelly_s = (struct shelly_st *) arg; - // SHELLY_DEBUG("[shelly_interrupt_handler]\n"); + SHELLY_DEBUG("[shelly_interrupt_handler]\n"); + assert(global_state); char input_char; - err = lpuart_getchar(shelly_s->uart_s, &input_char); + err = lpuart_getchar(global_state->uart_s, &input_char); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to get character"); - err = lpuart_putchar(shelly_s->uart_s, input_char); + err = lpuart_putchar(global_state->uart_s, input_char); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); } +static void handle_send_completed(void *arg, struct ump_send_queue_entry *entry) { + free((void *)entry->header); + free((void *)entry->payload); + free(entry); +} + +static void send_response(struct shelly_st_local * local_state, errval_t err, size_t payload_size, void *payload) { + assert(local_state); + + struct shelly_header * header = malloc(sizeof(struct shelly_header)); + assert(header); + header->type = SHELLY_MSG_RESPONSE; + + struct ump_send_queue_entry *entry = malloc(sizeof(struct ump_send_queue_entry)); + if (entry == NULL) USER_PANIC("Ran out of memory"); + + ump_send( + local_state->send_chan, + entry, + sizeof(struct shelly_header), + header, + payload_size, + payload, + handle_send_completed, + NULL + ); +} + +static void handle_client_request(void *arg, size_t header_size, void *header_buf, size_t payload_size); +static void handle_payload(void *arg, size_t payload_size, void *payload) { + struct shelly_st_local * local_state = arg; + assert(local_state); + assert(global_state); + // SHELLY_DEBUG("[handle_payload] client_id=%d\n", local_state->client_id); + // listen for the next request on this channel + ump_recv_header(local_state->recv_chan, handle_client_request, local_state); +} + +static void handle_client_request(void *arg, size_t header_size, void *header_buf, size_t payload_size) { + errval_t err; + struct shelly_st_local * local_state = arg; + assert(local_state); + assert(global_state); + + struct shelly_header * header = (struct shelly_header *) header_buf; + + if (header->type == SHELLY_MSG_GETCHAR) { + char input_char = '\0'; + err = lpuart_getchar(global_state->uart_s, &input_char); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to get character"); + } else if (header->type == SHELLY_MSG_PUTCHAR) { + err = lpuart_putchar(global_state->uart_s, header->character); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); + } + + send_response(local_state, SYS_ERR_OK, 0, NULL); + + // skip payload + ump_recv_payload(local_state->recv_chan, NULL, handle_payload, local_state); +} + +static errval_t connection_callback(void *arg, struct capref cap) { + errval_t err; + + SHELLY_DEBUG("incoming connection\n"); + assert(global_state); + + //create a new local state + struct shelly_st_local * local_state = calloc(sizeof(struct shelly_st_local), 1); + assert(local_state); + + local_state->client_id = global_state->num_clients; + global_state->num_clients += 1; + + // we can run the server on the default waitset since we are dispatching on + // it for listening to connections anyways + err = ump_chan_init(UMP_ROLE_SERVER, &local_state->send_chan, &local_state->recv_chan, sizeof(struct shelly_header), cap, get_default_waitset()); + if (err_is_fail(err)) return err; + // SHELLY_DEBUG("[connection_callback] local_state=%p\n", local_state); + + ump_recv_header(local_state->recv_chan, handle_client_request, local_state); + + SHELLY_DEBUG("connection ready to receive requests\n"); + + return SYS_ERR_OK; +} + + int main(int argc, char *argv[]) { errval_t err; debug_printf("welcome to shelly!\n"); - struct shelly_st * shelly_s = calloc(sizeof(struct shelly_st), 1); - assert(shelly_s); + global_state = calloc(sizeof(struct shelly_st_global), 1); + assert(global_state); //afeer: map lpuart registers struct capref cap_arg0 = { @@ -42,7 +138,7 @@ int main(int argc, char *argv[]) .slot = 0 }; err = paging_map_frame_attr(get_current_paging_state(), - (void **) &shelly_s->lpuart_base, IMX8X_UART_SIZE, + (void **) &global_state->lpuart_base, IMX8X_UART_SIZE, cap_arg0, VREGION_FLAGS_READ_WRITE_NOCACHE); if (err_is_fail(err)) USER_PANIC_ERR(err, "while mapping lpuart registers"); @@ -54,20 +150,20 @@ int main(int argc, char *argv[]) .slot = 1 }; err = paging_map_frame_attr(get_current_paging_state(), - (void**) &shelly_s->gic_base, IMX8X_GIC_DIST_SIZE, + (void**) &global_state->gic_base, IMX8X_GIC_DIST_SIZE, cap_arg1, VREGION_FLAGS_READ_WRITE_NOCACHE); if (err_is_fail(err)) USER_PANIC_ERR(err, "while mapping gic registers"); SHELLY_DEBUG("mapped gic\n"); //afeer: init gic driver - err = gic_dist_init(&shelly_s->gic_s, shelly_s->gic_base); + err = gic_dist_init(&global_state->gic_s, global_state->gic_base); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't init gic_dist interrupts"); SHELLY_DEBUG("initialized gic driver\n"); //afeer: init lpuart driver - err = lpuart_init(&shelly_s->uart_s, shelly_s->lpuart_base); + err = lpuart_init(&global_state->uart_s, global_state->lpuart_base); if (err_is_fail(err)) { USER_PANIC_ERR(err, "couldn't init lpuart"); } @@ -84,21 +180,26 @@ int main(int argc, char *argv[]) debug_printf(buf); struct waitset * ws = get_default_waitset(); - err = inthandler_setup(inter_cap, ws, MKCLOSURE(shelly_interrupt_handler, (void *) shelly_s)); + err = inthandler_setup(inter_cap, ws, MKCLOSURE(shelly_interrupt_handler, NULL)); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't setup interrupt handler"); SHELLY_DEBUG("setup interrupt handler\n"); - err = gic_dist_enable_interrupt(shelly_s->gic_s, IMX8X_UART3_INT, 0b11111111, 0); + err = gic_dist_enable_interrupt(global_state->gic_s, IMX8X_UART3_INT, 0b11111111, 0); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable gic interrupts"); SHELLY_DEBUG("enabled gic interrupt\n"); - err = lpuart_enable_interrupt(shelly_s->uart_s); + err = lpuart_enable_interrupt(global_state->uart_s); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't enable lpuart interrupts"); SHELLY_DEBUG("enabled lpuart interrupt\n"); + SHELLY_DEBUG("registering as shelly server\n"); + struct ump_binding_server server; + err = ump_binding_register(&server, UMP_SERVER_SHELLY, connection_callback, NULL); + if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to register UMP server"); + while (true) { err = event_dispatch(ws); if (err_is_fail(err)) { diff --git a/usr/shelly/shelly.h b/usr/shelly/shelly.h index 33497fa..11c3440 100644 --- a/usr/shelly/shelly.h +++ b/usr/shelly/shelly.h @@ -10,7 +10,7 @@ #ifndef SHELLY_H_ #define SHELLY_H_ -#define SHELLY_DEBUG_ON 1 +// #define SHELLY_DEBUG_ON 1 #if defined(SHELLY_DEBUG_ON) #define SHELLY_DEBUG(x...) debug_printf("[SHELLY_DEBUG] " x); @@ -20,13 +20,26 @@ #include #include +#include -struct shelly_st { - void * lpuart_base; // < virtual address of the lpuart device registers - void * gic_base; // < virtual address of the gic device registers +#define SHELLY_BUF_SIZE 2048 +//state that is shared for all clients +struct shelly_st_global { + void * lpuart_base; // < virtual address of the lpuart device registers + void * gic_base; // < virtual address of the gic device registers - struct lpuart_s * uart_s; // < state of the uart driver - struct gic_dist_s * gic_s; // < state of the gic driver + struct lpuart_s * uart_s; // < state of the uart driver + struct gic_dist_s * gic_s; // < state of the gic driver + + u_int32_t num_clients; + char buf[SHELLY_BUF_SIZE]; +}; + +//state that different for each client +struct shelly_st_local { + uint32_t client_id; + struct ump_recv_chan * recv_chan; + struct ump_send_chan * send_chan; }; #endif // ndef SHELLY_H_ From 74418ff85e9e3a65c577f0359dcfd5797f2d170c Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Tue, 31 May 2022 00:36:32 +0200 Subject: [PATCH 06/14] missing files --- include/aos/shelly_client.h | 39 ++++++++++++ lib/aos/shelly_client.c | 116 ++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 include/aos/shelly_client.h create mode 100644 lib/aos/shelly_client.c diff --git a/include/aos/shelly_client.h b/include/aos/shelly_client.h new file mode 100644 index 0000000..8592ca6 --- /dev/null +++ b/include/aos/shelly_client.h @@ -0,0 +1,39 @@ +#ifndef _SHELLY_CLIENT_H_ +#define _SHELLY_CLIENT_H_ + +#include + +// #define SHELLY_CLIENT_DEBUG_ON 1 + +#if defined(SHELLY_CLIENT_DEBUG_ON) +#define SHELLY_CLIENT_DEBUG(x...) debug_printf("[SHELLY_CLIENT_DEBUG] " x); +#else +#define SHELLY_CLIENT_DEBUG(x, ...) ((void)0) +#endif + + +struct shelly_client_state { + struct ump_send_chan *send_chan; + struct ump_recv_chan *recv_chan; + + struct capref shared_frame; + bool request_ongoing; +}; + +enum shelly_msg_type { + SHELLY_MSG_PUTCHAR, + SHELLY_MSG_GETCHAR, + SHELLY_MSG_RESPONSE, +}; + +struct shelly_header { + enum shelly_msg_type type; + char character; +}; + + +errval_t shelly_client_init(void); +errval_t shelly_client_getchar(struct aos_rpc * rpc, char * ret); +errval_t shelly_client_putchar(struct aos_rpc * rpc, char input); + +#endif /* _SHELLY_CLIENT_H_ */ \ No newline at end of file diff --git a/lib/aos/shelly_client.c b/lib/aos/shelly_client.c new file mode 100644 index 0000000..6680547 --- /dev/null +++ b/lib/aos/shelly_client.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include + +// use a waitset to make the calls blocking +struct waitset ws; +static struct shelly_client_state state; + +errval_t shelly_client_init(void) { + errval_t err; + SHELLY_CLIENT_DEBUG("[shelly_client_init]\n"); + + waitset_init(&ws); + + state.request_ongoing = false; + + //connect to shelly + struct aos_rpc *rpc = aos_rpc_get_init_channel(); + // retry several times, waiting inbetween in case the server is still starting up + for (int attempts = 0; attempts < 50; attempts++) { + err = aos_rpc_ump_connect(rpc, UMP_SERVER_SHELLY, &state.shared_frame); + if (err_no(err) != LIB_ERR_UMP_NOT_REGISTERED) break; + barrelfish_usleep(100000); + } + if (err_is_fail(err)) return err; + + //create the ump channel to the serial driver (a.k.a. shelly) + err = ump_chan_init(UMP_ROLE_CLIENT, &state.send_chan, &state.recv_chan, sizeof(struct shelly_header), state.shared_frame, &ws); + if (err_is_fail(err)) return err; + + // set_shelly_rpc(rpc); + + return SYS_ERR_OK; +} + +static void handle_payload(void *arg, size_t payload_size, void *payload) { + state.request_ongoing = false; +} + +static void handle_response(void *arg, size_t header_size, void *header_buf, size_t payload_size) { + // struct shelly_header *header = header_buf; + SHELLY_CLIENT_DEBUG("[handle_response]\n"); + + ump_recv_payload(state.recv_chan, NULL, handle_payload, NULL); +} + +static void handle_send_completed(void *arg, struct ump_send_queue_entry *entry) { + SHELLY_CLIENT_DEBUG("[handle_send_completed]\n"); + free((void *)entry->header); + free(entry); +} + +errval_t shelly_client_getchar(struct aos_rpc * rpc, char * ret) { + errval_t err; + SHELLY_CLIENT_DEBUG("[shelly_client_getchar]\n"); + + state.request_ongoing = true; + + struct shelly_header * header = malloc(sizeof(struct shelly_header)); + if (header == NULL) return LIB_ERR_MALLOC_FAIL; + struct ump_send_queue_entry *entry = malloc(sizeof(struct ump_send_queue_entry)); + if (entry == NULL) return LIB_ERR_MALLOC_FAIL; + + header->type = SHELLY_MSG_GETCHAR; + header->character = '\0'; + + ump_send(state.send_chan, entry, sizeof(struct shelly_header), header, 0, NULL, handle_send_completed, NULL); + + // register response handler + ump_recv_header(state.recv_chan, handle_response, NULL); + + // wait for the response + while (state.request_ongoing) { + err = event_dispatch(&ws); + if (err_is_fail(err)) { + DEBUG_ERR(err, "in event_dispatch"); + abort(); + } + } + + return SYS_ERR_OK; +} + +errval_t shelly_client_putchar(struct aos_rpc * rpc, char input) { + errval_t err; + SHELLY_CLIENT_DEBUG("[shelly_client_putchar]\n"); + + state.request_ongoing = true; + + struct shelly_header * header = malloc(sizeof(struct shelly_header)); + if (header == NULL) return LIB_ERR_MALLOC_FAIL; + struct ump_send_queue_entry *entry = malloc(sizeof(struct ump_send_queue_entry)); + if (entry == NULL) return LIB_ERR_MALLOC_FAIL; + + header->type = SHELLY_MSG_PUTCHAR; + header->character = input; + + ump_send(state.send_chan, entry, sizeof(struct shelly_header), header, 1, &input, handle_send_completed, NULL); + + // register response handler + ump_recv_header(state.recv_chan, handle_response, NULL); + + // wait for the response + while (state.request_ongoing) { + err = event_dispatch(&ws); + if (err_is_fail(err)) { + DEBUG_ERR(err, "in event_dispatch"); + abort(); + } + } + + return SYS_ERR_OK; +} From 5850f35d954a60614962153295b63e7556640c85 Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Tue, 31 May 2022 17:33:55 +0200 Subject: [PATCH 07/14] echo command somewhat working --- include/aos/shelly_client.h | 18 ++++++----- lib/aos/shelly_client.c | 22 +++++++++++-- usr/shelly/shelly.c | 61 +++++++++++++++++++++++++++++++------ usr/shelly/shelly.h | 8 +++++ usr/shelly/shelly_cmd.c | 48 +++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+), 21 deletions(-) create mode 100644 usr/shelly/shelly_cmd.c diff --git a/include/aos/shelly_client.h b/include/aos/shelly_client.h index 8592ca6..4c382b0 100644 --- a/include/aos/shelly_client.h +++ b/include/aos/shelly_client.h @@ -12,14 +12,6 @@ #endif -struct shelly_client_state { - struct ump_send_chan *send_chan; - struct ump_recv_chan *recv_chan; - - struct capref shared_frame; - bool request_ongoing; -}; - enum shelly_msg_type { SHELLY_MSG_PUTCHAR, SHELLY_MSG_GETCHAR, @@ -31,6 +23,16 @@ struct shelly_header { char character; }; +struct shelly_client_state { + struct ump_send_chan *send_chan; + struct ump_recv_chan *recv_chan; + + struct capref shared_frame; + bool request_ongoing; + struct shelly_header * current_request; + + char * buf; +}; errval_t shelly_client_init(void); errval_t shelly_client_getchar(struct aos_rpc * rpc, char * ret); diff --git a/lib/aos/shelly_client.c b/lib/aos/shelly_client.c index 6680547..b3a1c57 100644 --- a/lib/aos/shelly_client.c +++ b/lib/aos/shelly_client.c @@ -16,6 +16,8 @@ errval_t shelly_client_init(void) { waitset_init(&ws); state.request_ongoing = false; + state.buf = NULL; + state.current_request = NULL; //connect to shelly struct aos_rpc *rpc = aos_rpc_get_init_channel(); @@ -41,15 +43,24 @@ static void handle_payload(void *arg, size_t payload_size, void *payload) { } static void handle_response(void *arg, size_t header_size, void *header_buf, size_t payload_size) { - // struct shelly_header *header = header_buf; + struct shelly_header *header = header_buf; SHELLY_CLIENT_DEBUG("[handle_response]\n"); + if (state.current_request->type == SHELLY_MSG_GETCHAR) { + *state.buf = header->character; + } else if (state.current_request->type == SHELLY_MSG_PUTCHAR) { + //nothing to do + } else { + SHELLY_CLIENT_DEBUG("[handle_response] unexpected request type"); + } + ump_recv_payload(state.recv_chan, NULL, handle_payload, NULL); } static void handle_send_completed(void *arg, struct ump_send_queue_entry *entry) { SHELLY_CLIENT_DEBUG("[handle_send_completed]\n"); free((void *)entry->header); + free((void *)entry->payload); free(entry); } @@ -58,14 +69,16 @@ errval_t shelly_client_getchar(struct aos_rpc * rpc, char * ret) { SHELLY_CLIENT_DEBUG("[shelly_client_getchar]\n"); state.request_ongoing = true; + state.buf = ret; struct shelly_header * header = malloc(sizeof(struct shelly_header)); if (header == NULL) return LIB_ERR_MALLOC_FAIL; + state.current_request = header; struct ump_send_queue_entry *entry = malloc(sizeof(struct ump_send_queue_entry)); if (entry == NULL) return LIB_ERR_MALLOC_FAIL; header->type = SHELLY_MSG_GETCHAR; - header->character = '\0'; + header->character = 0; ump_send(state.send_chan, entry, sizeof(struct shelly_header), header, 0, NULL, handle_send_completed, NULL); @@ -80,6 +93,7 @@ errval_t shelly_client_getchar(struct aos_rpc * rpc, char * ret) { abort(); } } + SHELLY_CLIENT_DEBUG("[shelly_client_getchar] done\n"); return SYS_ERR_OK; } @@ -92,13 +106,14 @@ errval_t shelly_client_putchar(struct aos_rpc * rpc, char input) { struct shelly_header * header = malloc(sizeof(struct shelly_header)); if (header == NULL) return LIB_ERR_MALLOC_FAIL; + state.current_request = header; struct ump_send_queue_entry *entry = malloc(sizeof(struct ump_send_queue_entry)); if (entry == NULL) return LIB_ERR_MALLOC_FAIL; header->type = SHELLY_MSG_PUTCHAR; header->character = input; - ump_send(state.send_chan, entry, sizeof(struct shelly_header), header, 1, &input, handle_send_completed, NULL); + ump_send(state.send_chan, entry, sizeof(struct shelly_header), header, 0, NULL, handle_send_completed, NULL); // register response handler ump_recv_header(state.recv_chan, handle_response, NULL); @@ -111,6 +126,7 @@ errval_t shelly_client_putchar(struct aos_rpc * rpc, char input) { abort(); } } + SHELLY_CLIENT_DEBUG("[shelly_client_getchar] done\n"); return SYS_ERR_OK; } diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 3c13ef2..4c2c285 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -22,10 +22,12 @@ //state that is shared for all clients static struct shelly_st_global * global_state; +#include "shelly_cmd.c" + __attribute__((__used__)) -static void shelly_interrupt_handler(void * arg) { +static void handle_lpuart_interrupt(void * arg) { errval_t err; - SHELLY_DEBUG("[shelly_interrupt_handler]\n"); + SHELLY_DEBUG("[handle_lpuart_interrupt]\n"); assert(global_state); char input_char; @@ -34,6 +36,28 @@ static void shelly_interrupt_handler(void * arg) { err = lpuart_putchar(global_state->uart_s, input_char); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); + + if (input_char == ASCII_NL || input_char == ASCII_EOF || input_char == ASCII_CR) { + err = lpuart_putchar(global_state->uart_s, '\n'); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); + + global_state->buf[global_state->buffer_i] = '\0'; + global_state->buffer_i += 1; + + handle_shelly_cmd(global_state->buf, global_state->buffer_i); + + global_state->buffer_i = 0; + + err = lpuart_putchar(global_state->uart_s, ASCII_EOT); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); + err = lpuart_putchar(global_state->uart_s, '>'); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); + } else { + global_state->buf[global_state->buffer_i] = input_char; + global_state->buffer_i += 1; + global_state->buffer_i %= SHELLY_BUF_SIZE; + } + SHELLY_DEBUG("[handle_lpuart_interrupt] done\n"); } static void handle_send_completed(void *arg, struct ump_send_queue_entry *entry) { @@ -45,6 +69,7 @@ static void handle_send_completed(void *arg, struct ump_send_queue_entry *entry) static void send_response(struct shelly_st_local * local_state, errval_t err, size_t payload_size, void *payload) { assert(local_state); + SHELLY_DEBUG("[send_response]\n"); struct shelly_header * header = malloc(sizeof(struct shelly_header)); assert(header); header->type = SHELLY_MSG_RESPONSE; @@ -62,6 +87,7 @@ static void send_response(struct shelly_st_local * local_state, errval_t err, si handle_send_completed, NULL ); + SHELLY_DEBUG("[send_response] done\n"); } static void handle_client_request(void *arg, size_t header_size, void *header_buf, size_t payload_size); @@ -69,9 +95,13 @@ static void handle_payload(void *arg, size_t payload_size, void *payload) { struct shelly_st_local * local_state = arg; assert(local_state); assert(global_state); + + SHELLY_DEBUG("[handle_payload]\n"); + // SHELLY_DEBUG("[handle_payload] client_id=%d\n", local_state->client_id); // listen for the next request on this channel ump_recv_header(local_state->recv_chan, handle_client_request, local_state); + SHELLY_DEBUG("[handle_payload] done\n"); } static void handle_client_request(void *arg, size_t header_size, void *header_buf, size_t payload_size) { @@ -80,6 +110,8 @@ static void handle_client_request(void *arg, size_t header_size, void *header_bu assert(local_state); assert(global_state); + SHELLY_DEBUG("[handle_client_request]\n"); + struct shelly_header * header = (struct shelly_header *) header_buf; if (header->type == SHELLY_MSG_GETCHAR) { @@ -91,12 +123,16 @@ static void handle_client_request(void *arg, size_t header_size, void *header_bu if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); } + SHELLY_DEBUG("[handle_client_request] send_response\n"); send_response(local_state, SYS_ERR_OK, 0, NULL); // skip payload + SHELLY_DEBUG("[handle_client_request] skip payload\n"); ump_recv_payload(local_state->recv_chan, NULL, handle_payload, local_state); + SHELLY_DEBUG("[handle_client_request] done\n"); } +__attribute__((__used__)) static errval_t connection_callback(void *arg, struct capref cap) { errval_t err; @@ -112,7 +148,7 @@ static errval_t connection_callback(void *arg, struct capref cap) { // we can run the server on the default waitset since we are dispatching on // it for listening to connections anyways - err = ump_chan_init(UMP_ROLE_SERVER, &local_state->send_chan, &local_state->recv_chan, sizeof(struct shelly_header), cap, get_default_waitset()); + err = ump_chan_init(UMP_ROLE_SERVER, &local_state->send_chan, &local_state->recv_chan, sizeof(struct shelly_header), cap, global_state->ws); if (err_is_fail(err)) return err; // SHELLY_DEBUG("[connection_callback] local_state=%p\n", local_state); @@ -132,6 +168,10 @@ int main(int argc, char *argv[]) global_state = calloc(sizeof(struct shelly_st_global), 1); assert(global_state); + global_state->num_clients = 0; + global_state->buffer_i = 0; + global_state->ws = get_default_waitset(); + //afeer: map lpuart registers struct capref cap_arg0 = { .cnode = cnode_arg, @@ -179,8 +219,9 @@ int main(int argc, char *argv[]) debug_print_cap_at_capref(buf, 256, inter_cap); debug_printf(buf); - struct waitset * ws = get_default_waitset(); - err = inthandler_setup(inter_cap, ws, MKCLOSURE(shelly_interrupt_handler, NULL)); + // struct waitset * ws = calloc(sizeof(struct waitset), 1); + // waitset_init(ws); + err = inthandler_setup(inter_cap, global_state->ws, MKCLOSURE(handle_lpuart_interrupt, NULL)); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't setup interrupt handler"); SHELLY_DEBUG("setup interrupt handler\n"); @@ -195,13 +236,13 @@ int main(int argc, char *argv[]) SHELLY_DEBUG("enabled lpuart interrupt\n"); - SHELLY_DEBUG("registering as shelly server\n"); - struct ump_binding_server server; - err = ump_binding_register(&server, UMP_SERVER_SHELLY, connection_callback, NULL); - if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to register UMP server"); + // SHELLY_DEBUG("registering as shelly server\n"); + // struct ump_binding_server server; + // err = ump_binding_register(&server, UMP_SERVER_SHELLY, connection_callback, NULL); + // if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to register UMP server"); while (true) { - err = event_dispatch(ws); + err = event_dispatch(global_state->ws); if (err_is_fail(err)) { DEBUG_ERR(err, "in event_dispatch"); abort(); diff --git a/usr/shelly/shelly.h b/usr/shelly/shelly.h index 11c3440..039b823 100644 --- a/usr/shelly/shelly.h +++ b/usr/shelly/shelly.h @@ -22,9 +22,16 @@ #include #include +#define ASCII_NL 10 // < new line +#define ASCII_CR 13 // < carriage return +#define ASCII_EOF 4 // < end of file +#define ASCII_EOT 3 // < end of text + #define SHELLY_BUF_SIZE 2048 //state that is shared for all clients struct shelly_st_global { + struct waitset * ws; + void * lpuart_base; // < virtual address of the lpuart device registers void * gic_base; // < virtual address of the gic device registers @@ -33,6 +40,7 @@ struct shelly_st_global { u_int32_t num_clients; char buf[SHELLY_BUF_SIZE]; + size_t buffer_i; }; //state that different for each client diff --git a/usr/shelly/shelly_cmd.c b/usr/shelly/shelly_cmd.c new file mode 100644 index 0000000..169ec28 --- /dev/null +++ b/usr/shelly/shelly_cmd.c @@ -0,0 +1,48 @@ +#include +#include "shelly.h" + + + +static void shelly_cmd_echo(char* argv[], int argc) { + errval_t err; + SHELLY_DEBUG("[shelly_cmd_echo] argc=%d\n", argc); + + for (int i = 0; argv[1][i] != '\0'; ++i) { + err = lpuart_putchar(global_state->uart_s, argv[1][i]); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); + } + err = lpuart_putchar(global_state->uart_s, '\0'); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); +} + +static void handle_shelly_cmd(char* str, size_t len) { + SHELLY_DEBUG("[handle_shelly_cmd] len=%d\n", len); + + if (len <= 1) { + return; + } + + int argc = 1; + for (int i = 0; i < len; ++i) { + if (str[i] == ' ') ++argc; + } + char * argv[argc]; + + const char delim[2] = " "; + + for (int i = 0; i < argc; ++i) { + if (i == 0) { + argv[i] = strtok(str, delim); + } else { + argv[i] = strtok(NULL, delim); + } + SHELLY_DEBUG("[handle_shelly_cmd] arg[%d]=%s\n", i, argv[i]); + } + + if (strcmp(argv[0], "echo") == 0) { + shelly_cmd_echo(argv, argc); + } else { + SHELLY_DEBUG("unknown command %s\n", argv[0]); + } +} + From 10beb87b1376f4027a659a50e2f1a106468625e2 Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Tue, 31 May 2022 23:04:18 +0200 Subject: [PATCH 08/14] implement rudimentary run command --- usr/shelly/shelly.c | 5 +-- usr/shelly/shelly_cmd.c | 80 +++++++++++++++++++++++++++++------------ 2 files changed, 60 insertions(+), 25 deletions(-) diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 4c2c285..9a8214c 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -12,10 +12,10 @@ #include #include #include - #include #include #include +#include #include "shelly.h" @@ -44,7 +44,8 @@ static void handle_lpuart_interrupt(void * arg) { global_state->buf[global_state->buffer_i] = '\0'; global_state->buffer_i += 1; - handle_shelly_cmd(global_state->buf, global_state->buffer_i); + err = handle_shelly_cmd(global_state->buf, global_state->buffer_i); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while running command"); global_state->buffer_i = 0; diff --git a/usr/shelly/shelly_cmd.c b/usr/shelly/shelly_cmd.c index 169ec28..d2cc1e6 100644 --- a/usr/shelly/shelly_cmd.c +++ b/usr/shelly/shelly_cmd.c @@ -1,48 +1,82 @@ #include #include "shelly.h" +__attribute__((__used__)) +static void parse_cmd_line(char * line, int * argc, char ** argv) { + *argc = 0; + char *token = strtok(line, " "); + while (token != NULL) { + argv[*argc] = token; + token = strtok(NULL, " "); + *argc += 1; + } +} - -static void shelly_cmd_echo(char* argv[], int argc) { +static errval_t shelly_cmd_echo(char * line) { errval_t err; SHELLY_DEBUG("[shelly_cmd_echo] argc=%d\n", argc); - for (int i = 0; argv[1][i] != '\0'; ++i) { - err = lpuart_putchar(global_state->uart_s, argv[1][i]); + for (int i = 0; line[i] != '\0'; ++i) { + err = lpuart_putchar(global_state->uart_s, line[i]); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); } err = lpuart_putchar(global_state->uart_s, '\0'); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); + + return SYS_ERR_OK; } -static void handle_shelly_cmd(char* str, size_t len) { +static errval_t shelly_cmd_run(char * line) { + errval_t err; + + SHELLY_DEBUG("[shelly_cmd_run] line=%s\n", line); + + // start process + domainid_t pid; + struct aos_rpc * rpc = aos_rpc_get_process_channel(); + err = aos_rpc_process_spawn(rpc, line, 0, &pid); + if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to spawn process"); + SHELLY_DEBUG("[shelly_cmd_run] spawned process\n"); + + // // get process name + // char *name; + // err = aos_rpc_process_get_name(rpc, pid, &name); + // if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to get process name"); + // printf("Process Name: %s\n", name); + + // // get all PIDs + // domainid_t *pids; + // size_t pid_count; + // err = aos_rpc_process_get_all_pids(rpc, &pids, &pid_count); + // if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to get all PIDs"); + // printf("PIDs:\n"); + // for(size_t i = 0; i < pid_count; ++i) { + // printf(" %lu\n", pids[i]); + // } + + return SYS_ERR_OK; +} + +static errval_t handle_shelly_cmd(char* line, size_t len) { SHELLY_DEBUG("[handle_shelly_cmd] len=%d\n", len); - if (len <= 1) { - return; + return SYS_ERR_OK; } - int argc = 1; - for (int i = 0; i < len; ++i) { - if (str[i] == ' ') ++argc; - } - char * argv[argc]; + char * cmd = strtok(line, " "); - const char delim[2] = " "; + char * remaining_line = line + strlen(cmd) + 1; - for (int i = 0; i < argc; ++i) { - if (i == 0) { - argv[i] = strtok(str, delim); - } else { - argv[i] = strtok(NULL, delim); - } - SHELLY_DEBUG("[handle_shelly_cmd] arg[%d]=%s\n", i, argv[i]); - } + // debug_printf("remaining_line = %s\n", remaining_line); - if (strcmp(argv[0], "echo") == 0) { - shelly_cmd_echo(argv, argc); + if (strcmp(cmd, "echo") == 0) { + return shelly_cmd_echo(remaining_line); + } else if (strcmp(cmd, "run") == 0) { + return shelly_cmd_run(remaining_line); } else { SHELLY_DEBUG("unknown command %s\n", argv[0]); } + + return SYS_ERR_OK; } From 7842837d5ad76cf13c47202f8e985ef19227eec8 Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Wed, 1 Jun 2022 13:11:27 +0200 Subject: [PATCH 09/14] enable shelly ump server --- usr/shelly/shelly.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 9a8214c..78da716 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -237,10 +237,10 @@ int main(int argc, char *argv[]) SHELLY_DEBUG("enabled lpuart interrupt\n"); - // SHELLY_DEBUG("registering as shelly server\n"); - // struct ump_binding_server server; - // err = ump_binding_register(&server, UMP_SERVER_SHELLY, connection_callback, NULL); - // if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to register UMP server"); + SHELLY_DEBUG("registering as shelly server\n"); + struct ump_binding_server server; + err = ump_binding_register(&server, UMP_SERVER_SHELLY, connection_callback, NULL); + if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to register UMP server"); while (true) { err = event_dispatch(global_state->ws); From e28c9dccde5002c13316aa17bc1000d2f9d09385 Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Wed, 1 Jun 2022 14:02:33 +0200 Subject: [PATCH 10/14] fix lpuart read --- errors/errno.fugu | 5 +++ usr/shelly/shelly.c | 75 ++++++++++++++++++++++++++++++----------- usr/shelly/shelly.h | 4 +++ usr/shelly/shelly_cmd.c | 14 +++----- 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/errors/errno.fugu b/errors/errno.fugu index fcf10dc..005c0ad 100755 --- a/errors/errno.fugu +++ b/errors/errno.fugu @@ -1433,3 +1433,8 @@ errors sdhc SDHCD_ERR_ { failure BULK_FRAME_SET "Bulk frame already set", failure BULK_FRAME_NOT_SET "Bulk frame not set", }; + +errors shelly SHELLY_ERR_ { + failure BUFFER_OVERFLOW "Buffer limits reached", + failure WRITE "String write failed", +}; \ No newline at end of file diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 78da716..0c738dd 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -24,6 +24,35 @@ static struct shelly_st_global * global_state; #include "shelly_cmd.c" +//prints a null terminated string +errval_t shelly_write_str(char * str) { + errval_t err; + for (size_t i = 0; str[i] != '\0'; ++i) { + err = lpuart_putchar(global_state->uart_s, str[i]); + if (err_is_fail(err)) return err_push(err, SHELLY_ERR_WRITE); + } + err = lpuart_putchar(global_state->uart_s, '\0'); + if (err_is_fail(err)) return err_push(err, SHELLY_ERR_WRITE); + return SYS_ERR_OK; +} + +void shelly_reset_buffer(void) { + global_state->buffer_i = 0; + global_state->buf[0] = '\0'; +} + +errval_t shelly_buffer_append(char c) { + global_state->buf[global_state->buffer_i] = c; + global_state->buffer_i += 1; + + if (global_state->buffer_i == SHELLY_BUF_SIZE) { + shelly_reset_buffer(); + return SHELLY_ERR_BUFFER_OVERFLOW; + } + + return SYS_ERR_OK; +} + __attribute__((__used__)) static void handle_lpuart_interrupt(void * arg) { errval_t err; @@ -31,32 +60,38 @@ static void handle_lpuart_interrupt(void * arg) { assert(global_state); char input_char; - err = lpuart_getchar(global_state->uart_s, &input_char); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to get character"); + while (true) { + err = lpuart_getchar(global_state->uart_s, &input_char); + if (err == LPUART_ERR_NO_DATA) { + break; + } else if (err_is_fail(err)) { + USER_PANIC_ERR(err, "while trying to get character"); + } - err = lpuart_putchar(global_state->uart_s, input_char); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - - if (input_char == ASCII_NL || input_char == ASCII_EOF || input_char == ASCII_CR) { - err = lpuart_putchar(global_state->uart_s, '\n'); + err = lpuart_putchar(global_state->uart_s, input_char); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - global_state->buf[global_state->buffer_i] = '\0'; - global_state->buffer_i += 1; + if (input_char == ASCII_NL || input_char == ASCII_EOF || input_char == ASCII_CR) { + err = lpuart_putchar(global_state->uart_s, '\n'); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - err = handle_shelly_cmd(global_state->buf, global_state->buffer_i); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while running command"); + global_state->buf[global_state->buffer_i] = '\0'; + global_state->buffer_i += 1; - global_state->buffer_i = 0; + err = handle_shelly_cmd(global_state->buf, global_state->buffer_i); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while running command"); - err = lpuart_putchar(global_state->uart_s, ASCII_EOT); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - err = lpuart_putchar(global_state->uart_s, '>'); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - } else { - global_state->buf[global_state->buffer_i] = input_char; - global_state->buffer_i += 1; - global_state->buffer_i %= SHELLY_BUF_SIZE; + shelly_reset_buffer(); + + err = shelly_write_str("\x3>"); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write string"); + } else { + err = shelly_buffer_append(input_char); + if (err_is_fail(err)) { + err = shelly_write_str("shelly buffer full! resetting...\n"); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write string"); + } + } } SHELLY_DEBUG("[handle_lpuart_interrupt] done\n"); } diff --git a/usr/shelly/shelly.h b/usr/shelly/shelly.h index 039b823..6f3a40f 100644 --- a/usr/shelly/shelly.h +++ b/usr/shelly/shelly.h @@ -50,4 +50,8 @@ struct shelly_st_local { struct ump_send_chan * send_chan; }; +errval_t shelly_write_str(char * str); +void shelly_reset_buffer(void); +errval_t shelly_buffer_append(char c); + #endif // ndef SHELLY_H_ diff --git a/usr/shelly/shelly_cmd.c b/usr/shelly/shelly_cmd.c index d2cc1e6..593f995 100644 --- a/usr/shelly/shelly_cmd.c +++ b/usr/shelly/shelly_cmd.c @@ -15,14 +15,8 @@ static void parse_cmd_line(char * line, int * argc, char ** argv) { static errval_t shelly_cmd_echo(char * line) { errval_t err; SHELLY_DEBUG("[shelly_cmd_echo] argc=%d\n", argc); - - for (int i = 0; line[i] != '\0'; ++i) { - err = lpuart_putchar(global_state->uart_s, line[i]); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - } - err = lpuart_putchar(global_state->uart_s, '\0'); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - + err = shelly_write_str(line); + if (err_is_fail(err)) return err; return SYS_ERR_OK; } @@ -74,7 +68,9 @@ static errval_t handle_shelly_cmd(char* line, size_t len) { } else if (strcmp(cmd, "run") == 0) { return shelly_cmd_run(remaining_line); } else { - SHELLY_DEBUG("unknown command %s\n", argv[0]); + char buf[256]; + snprintf(buf, 256, "unknown command %s\n", cmd); + shelly_write_str(buf); } return SYS_ERR_OK; From e979d98a33e6e00b94fbc68ac48c9bd5bb8c482f Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Wed, 1 Jun 2022 15:07:25 +0200 Subject: [PATCH 11/14] somewhat fix newline --- usr/shelly/shelly.c | 46 ++++++++++++++++++++--------------------- usr/shelly/shelly.h | 3 ++- usr/shelly/shelly_cmd.c | 3 +-- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 0c738dd..3ad4d53 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -24,6 +24,10 @@ static struct shelly_st_global * global_state; #include "shelly_cmd.c" +bool is_newline(char c) { + return c == ASCII_NL || c == ASCII_EOF || c == ASCII_CR; +} + //prints a null terminated string errval_t shelly_write_str(char * str) { errval_t err; @@ -38,7 +42,7 @@ errval_t shelly_write_str(char * str) { void shelly_reset_buffer(void) { global_state->buffer_i = 0; - global_state->buf[0] = '\0'; + memset(global_state->buf, 0, SHELLY_BUF_SIZE); } errval_t shelly_buffer_append(char c) { @@ -56,7 +60,6 @@ errval_t shelly_buffer_append(char c) { __attribute__((__used__)) static void handle_lpuart_interrupt(void * arg) { errval_t err; - SHELLY_DEBUG("[handle_lpuart_interrupt]\n"); assert(global_state); char input_char; @@ -71,19 +74,22 @@ static void handle_lpuart_interrupt(void * arg) { err = lpuart_putchar(global_state->uart_s, input_char); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - if (input_char == ASCII_NL || input_char == ASCII_EOF || input_char == ASCII_CR) { - err = lpuart_putchar(global_state->uart_s, '\n'); + if (is_newline(input_char)) { + err = lpuart_putchar(global_state->uart_s, ASCII_CR); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); global_state->buf[global_state->buffer_i] = '\0'; global_state->buffer_i += 1; + err = shelly_write_str("\n\xd"); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write string"); + err = handle_shelly_cmd(global_state->buf, global_state->buffer_i); if (err_is_fail(err)) USER_PANIC_ERR(err, "while running command"); shelly_reset_buffer(); - err = shelly_write_str("\x3>"); + err = shelly_write_str("\n\xd>"); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write string"); } else { err = shelly_buffer_append(input_char); @@ -93,7 +99,6 @@ static void handle_lpuart_interrupt(void * arg) { } } } - SHELLY_DEBUG("[handle_lpuart_interrupt] done\n"); } static void handle_send_completed(void *arg, struct ump_send_queue_entry *entry) { @@ -105,7 +110,7 @@ static void handle_send_completed(void *arg, struct ump_send_queue_entry *entry) static void send_response(struct shelly_st_local * local_state, errval_t err, size_t payload_size, void *payload) { assert(local_state); - SHELLY_DEBUG("[send_response]\n"); + // SHELLY_DEBUG("[send_response]\n"); struct shelly_header * header = malloc(sizeof(struct shelly_header)); assert(header); header->type = SHELLY_MSG_RESPONSE; @@ -123,7 +128,7 @@ static void send_response(struct shelly_st_local * local_state, errval_t err, si handle_send_completed, NULL ); - SHELLY_DEBUG("[send_response] done\n"); + // SHELLY_DEBUG("[send_response] done\n"); } static void handle_client_request(void *arg, size_t header_size, void *header_buf, size_t payload_size); @@ -132,12 +137,8 @@ static void handle_payload(void *arg, size_t payload_size, void *payload) { assert(local_state); assert(global_state); - SHELLY_DEBUG("[handle_payload]\n"); - - // SHELLY_DEBUG("[handle_payload] client_id=%d\n", local_state->client_id); // listen for the next request on this channel ump_recv_header(local_state->recv_chan, handle_client_request, local_state); - SHELLY_DEBUG("[handle_payload] done\n"); } static void handle_client_request(void *arg, size_t header_size, void *header_buf, size_t payload_size) { @@ -146,8 +147,6 @@ static void handle_client_request(void *arg, size_t header_size, void *header_bu assert(local_state); assert(global_state); - SHELLY_DEBUG("[handle_client_request]\n"); - struct shelly_header * header = (struct shelly_header *) header_buf; if (header->type == SHELLY_MSG_GETCHAR) { @@ -157,15 +156,16 @@ static void handle_client_request(void *arg, size_t header_size, void *header_bu } else if (header->type == SHELLY_MSG_PUTCHAR) { err = lpuart_putchar(global_state->uart_s, header->character); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); + if (is_newline(header->character)) { + err = lpuart_putchar(global_state->uart_s, ASCII_CR); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); + } } - SHELLY_DEBUG("[handle_client_request] send_response\n"); send_response(local_state, SYS_ERR_OK, 0, NULL); // skip payload - SHELLY_DEBUG("[handle_client_request] skip payload\n"); ump_recv_payload(local_state->recv_chan, NULL, handle_payload, local_state); - SHELLY_DEBUG("[handle_client_request] done\n"); } __attribute__((__used__)) @@ -199,7 +199,6 @@ static errval_t connection_callback(void *arg, struct capref cap) { int main(int argc, char *argv[]) { errval_t err; - debug_printf("welcome to shelly!\n"); global_state = calloc(sizeof(struct shelly_st_global), 1); assert(global_state); @@ -251,12 +250,7 @@ int main(int argc, char *argv[]) if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't alloc dest cap"); SHELLY_DEBUG("created interrupt cap\n"); - char buf[256]; - debug_print_cap_at_capref(buf, 256, inter_cap); - debug_printf(buf); - // struct waitset * ws = calloc(sizeof(struct waitset), 1); - // waitset_init(ws); err = inthandler_setup(inter_cap, global_state->ws, MKCLOSURE(handle_lpuart_interrupt, NULL)); if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't setup interrupt handler"); @@ -272,11 +266,15 @@ int main(int argc, char *argv[]) SHELLY_DEBUG("enabled lpuart interrupt\n"); - SHELLY_DEBUG("registering as shelly server\n"); struct ump_binding_server server; err = ump_binding_register(&server, UMP_SERVER_SHELLY, connection_callback, NULL); if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to register UMP server"); + SHELLY_DEBUG("registered as shelly server\n"); + + err = shelly_write_str("welcome to Shelly(TM)(TM)!\n"); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write welcome message"); + while (true) { err = event_dispatch(global_state->ws); if (err_is_fail(err)) { diff --git a/usr/shelly/shelly.h b/usr/shelly/shelly.h index 6f3a40f..a43e3d8 100644 --- a/usr/shelly/shelly.h +++ b/usr/shelly/shelly.h @@ -10,7 +10,7 @@ #ifndef SHELLY_H_ #define SHELLY_H_ -// #define SHELLY_DEBUG_ON 1 +#define SHELLY_DEBUG_ON 1 #if defined(SHELLY_DEBUG_ON) #define SHELLY_DEBUG(x...) debug_printf("[SHELLY_DEBUG] " x); @@ -50,6 +50,7 @@ struct shelly_st_local { struct ump_send_chan * send_chan; }; +bool is_newline(char c); errval_t shelly_write_str(char * str); void shelly_reset_buffer(void); errval_t shelly_buffer_append(char c); diff --git a/usr/shelly/shelly_cmd.c b/usr/shelly/shelly_cmd.c index 593f995..eb8e8e7 100644 --- a/usr/shelly/shelly_cmd.c +++ b/usr/shelly/shelly_cmd.c @@ -14,7 +14,6 @@ static void parse_cmd_line(char * line, int * argc, char ** argv) { static errval_t shelly_cmd_echo(char * line) { errval_t err; - SHELLY_DEBUG("[shelly_cmd_echo] argc=%d\n", argc); err = shelly_write_str(line); if (err_is_fail(err)) return err; return SYS_ERR_OK; @@ -52,7 +51,7 @@ static errval_t shelly_cmd_run(char * line) { } static errval_t handle_shelly_cmd(char* line, size_t len) { - SHELLY_DEBUG("[handle_shelly_cmd] len=%d\n", len); + // SHELLY_DEBUG("[handle_shelly_cmd] len=%d\n", len); if (len <= 1) { return SYS_ERR_OK; } From be08ca06be541f15cf1f40a49972064b6e7d752f Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Wed, 1 Jun 2022 16:42:15 +0200 Subject: [PATCH 12/14] add ps command and fix performance on samecore ump --- errors/errno.fugu | 2 ++ lib/aos/ump_chan.c | 1 + usr/shelly/shelly.c | 12 +++++++----- usr/shelly/shelly_cmd.c | 43 +++++++++++++++++++++++++---------------- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/errors/errno.fugu b/errors/errno.fugu index 005c0ad..db22626 100755 --- a/errors/errno.fugu +++ b/errors/errno.fugu @@ -1437,4 +1437,6 @@ errors sdhc SDHCD_ERR_ { errors shelly SHELLY_ERR_ { failure BUFFER_OVERFLOW "Buffer limits reached", failure WRITE "String write failed", + failure SPAWN_RPC "Spawn RPC failed", + failure PS_RPC "ps RPC failed", }; \ No newline at end of file diff --git a/lib/aos/ump_chan.c b/lib/aos/ump_chan.c index c9fd08f..c28ccd2 100644 --- a/lib/aos/ump_chan.c +++ b/lib/aos/ump_chan.c @@ -287,6 +287,7 @@ static void ump_worker_schedule(struct ump_worker_context *worker_context) { // this is supposed to be called single threaded and only upon event trigger // hence this cannot be a reregister and thus not fail assert(err_is_ok(err)); + thread_yield(); } /** diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 3ad4d53..487fb3d 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -81,20 +81,20 @@ static void handle_lpuart_interrupt(void * arg) { global_state->buf[global_state->buffer_i] = '\0'; global_state->buffer_i += 1; - err = shelly_write_str("\n\xd"); + err = shelly_write_str("\n\r"); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write string"); err = handle_shelly_cmd(global_state->buf, global_state->buffer_i); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while running command"); + if (err_is_fail(err)) DEBUG_ERR(err, "while running command"); shelly_reset_buffer(); - err = shelly_write_str("\n\xd>"); + err = shelly_write_str("\n\r>"); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write string"); } else { err = shelly_buffer_append(input_char); if (err_is_fail(err)) { - err = shelly_write_str("shelly buffer full! resetting...\n"); + err = shelly_write_str("shelly buffer full! resetting...\n\r"); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write string"); } } @@ -147,6 +147,8 @@ static void handle_client_request(void *arg, size_t header_size, void *header_bu assert(local_state); assert(global_state); + // SHELLY_DEBUG("[handle_client_request] client_id=%d\n", local_state->client_id); + struct shelly_header * header = (struct shelly_header *) header_buf; if (header->type == SHELLY_MSG_GETCHAR) { @@ -272,7 +274,7 @@ int main(int argc, char *argv[]) SHELLY_DEBUG("registered as shelly server\n"); - err = shelly_write_str("welcome to Shelly(TM)(TM)!\n"); + err = shelly_write_str("Welcome to Shelly(TM)(TM)!\n\r"); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write welcome message"); while (true) { diff --git a/usr/shelly/shelly_cmd.c b/usr/shelly/shelly_cmd.c index eb8e8e7..99d2f02 100644 --- a/usr/shelly/shelly_cmd.c +++ b/usr/shelly/shelly_cmd.c @@ -28,25 +28,32 @@ static errval_t shelly_cmd_run(char * line) { domainid_t pid; struct aos_rpc * rpc = aos_rpc_get_process_channel(); err = aos_rpc_process_spawn(rpc, line, 0, &pid); - if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to spawn process"); - SHELLY_DEBUG("[shelly_cmd_run] spawned process\n"); + if (err == SPAWN_ERR_FIND_MODULE) { + err = shelly_write_str("[run]:couldn't find module:\n\r"); + if (err_is_fail(err)) return err; + err = shelly_write_str(line); + if (err_is_fail(err)) return err; + err = shelly_write_str("\n\r"); + if (err_is_fail(err)) return err; + } else if (err_is_fail(err)) return err_push(err, SHELLY_ERR_SPAWN_RPC); - // // get process name - // char *name; - // err = aos_rpc_process_get_name(rpc, pid, &name); - // if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to get process name"); - // printf("Process Name: %s\n", name); + return SYS_ERR_OK; +} - // // get all PIDs - // domainid_t *pids; - // size_t pid_count; - // err = aos_rpc_process_get_all_pids(rpc, &pids, &pid_count); - // if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to get all PIDs"); - // printf("PIDs:\n"); - // for(size_t i = 0; i < pid_count; ++i) { - // printf(" %lu\n", pids[i]); - // } +static errval_t shelly_cmd_ps(char * line) { + errval_t err; + domainid_t *pids; + size_t pid_count; + struct aos_rpc * rpc = aos_rpc_get_process_channel(); + err = aos_rpc_process_get_all_pids(rpc, &pids, &pid_count); + if (err_is_fail(err)) return err_push(err, SHELLY_ERR_PS_RPC); + shelly_write_str("PIDs:\n\r"); + char buf[256]; + for(size_t i = 0; i < pid_count; ++i) { + snprintf(buf, 256, " %lu\n\r", pids[i]); + shelly_write_str(buf); + } return SYS_ERR_OK; } @@ -66,9 +73,11 @@ static errval_t handle_shelly_cmd(char* line, size_t len) { return shelly_cmd_echo(remaining_line); } else if (strcmp(cmd, "run") == 0) { return shelly_cmd_run(remaining_line); + } else if (strcmp(cmd, "ps") == 0) { + return shelly_cmd_ps(remaining_line); } else { char buf[256]; - snprintf(buf, 256, "unknown command %s\n", cmd); + snprintf(buf, 256, "unknown command \"%s\"\n\r", cmd); shelly_write_str(buf); } From ea71de7c8be0d590ce45fc2e9fa36521eca781c5 Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Wed, 1 Jun 2022 17:01:45 +0200 Subject: [PATCH 13/14] implement help command --- lib/aos/init.c | 19 ++++++++----------- usr/shelly/shelly_cmd.c | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/lib/aos/init.c b/lib/aos/init.c index 3092cf8..d3746bc 100644 --- a/lib/aos/init.c +++ b/lib/aos/init.c @@ -109,17 +109,16 @@ static size_t aos_terminal_write(const char *buf, size_t len) if(len == 0) return 0; struct aos_rpc *rpc = aos_rpc_get_serial_channel(); + if (rpc == NULL) { + debug_printf("[aos_terminal_write] RPC NOT YET INITIALIZED: %.*s\n", len, buf); + USER_PANIC("Make sure to initialize aos_rpc before barrelfish_libc_glue_init is called."); + } for (int i = 0; i < len; ++i) { err = aos_rpc_serial_putchar(rpc, buf[i]); if (err_is_fail(err)) return err; } return SYS_ERR_OK; - // if (rpc == NULL) { - // debug_printf("[aos_terminal_write] RPC NOT YET INITIALIZED: %.*s\n", len, buf); - // USER_PANIC("Make sure to initialize aos_rpc before barrelfish_libc_glue_init is called."); - // } - // return aos_rpc_serial_write(rpc, buf, len); } @@ -129,6 +128,10 @@ static size_t aos_terminal_read(char *buf, size_t len) if(len == 0) return 0; struct aos_rpc *rpc = aos_rpc_get_serial_channel(); + if (rpc == NULL) { + debug_printf("[aos_terminal_read] RPC NOT YET INITIALIZED: %.*s\n", len, buf); + USER_PANIC("Make sure to initialize aos_rpc before barrelfish_libc_glue_init is called."); + } for (int i = 0; i < len; ++i) { char in; err = aos_rpc_serial_getchar(rpc, &in); @@ -137,12 +140,6 @@ static size_t aos_terminal_read(char *buf, size_t len) } return SYS_ERR_OK; - - // if (rpc == NULL) { - // debug_printf("[aos_terminal_read] RPC NOT YET INITIALIZED: %.*s\n", len, buf); - // USER_PANIC("Make sure to initialize aos_rpc before barrelfish_libc_glue_init is called."); - // } - // return aos_rpc_serial_read(rpc, buf, len); } diff --git a/usr/shelly/shelly_cmd.c b/usr/shelly/shelly_cmd.c index 99d2f02..30891ac 100644 --- a/usr/shelly/shelly_cmd.c +++ b/usr/shelly/shelly_cmd.c @@ -12,6 +12,22 @@ static void parse_cmd_line(char * line, int * argc, char ** argv) { } } +static errval_t shelly_cmd_help(char * line) { + errval_t err; + err = shelly_write_str("commands implemented:\n\r"); + if (err_is_fail(err)) return err; + err = shelly_write_str("- echo\n\r"); + if (err_is_fail(err)) return err; + err = shelly_write_str("- run\n\r"); + if (err_is_fail(err)) return err; + err = shelly_write_str("- ps\n\r"); + if (err_is_fail(err)) return err; + err = shelly_write_str("- help\n\r"); + if (err_is_fail(err)) return err; + + return SYS_ERR_OK; +} + static errval_t shelly_cmd_echo(char * line) { errval_t err; err = shelly_write_str(line); @@ -75,6 +91,8 @@ static errval_t handle_shelly_cmd(char* line, size_t len) { return shelly_cmd_run(remaining_line); } else if (strcmp(cmd, "ps") == 0) { return shelly_cmd_ps(remaining_line); + } else if (strcmp(cmd, "help") == 0) { + return shelly_cmd_help(remaining_line); } else { char buf[256]; snprintf(buf, 256, "unknown command \"%s\"\n\r", cmd); From 2901caad24e318b97632f24631a3ff1e7f0ad33e Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Wed, 1 Jun 2022 17:22:15 +0200 Subject: [PATCH 14/14] add core argument for run command --- usr/shelly/shelly.c | 2 +- usr/shelly/shelly_cmd.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 487fb3d..fcc6088 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -89,7 +89,7 @@ static void handle_lpuart_interrupt(void * arg) { shelly_reset_buffer(); - err = shelly_write_str("\n\r>"); + err = shelly_write_str("\n\ryou@windows me > "); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write string"); } else { err = shelly_buffer_append(input_char); diff --git a/usr/shelly/shelly_cmd.c b/usr/shelly/shelly_cmd.c index 30891ac..8ccf5a6 100644 --- a/usr/shelly/shelly_cmd.c +++ b/usr/shelly/shelly_cmd.c @@ -16,9 +16,11 @@ static errval_t shelly_cmd_help(char * line) { errval_t err; err = shelly_write_str("commands implemented:\n\r"); if (err_is_fail(err)) return err; - err = shelly_write_str("- echo\n\r"); + err = shelly_write_str("- echo [string]\n\r"); if (err_is_fail(err)) return err; - err = shelly_write_str("- run\n\r"); + err = shelly_write_str("- run [core] [binary]\n\r"); + if (err_is_fail(err)) return err; + err = shelly_write_str(" run a module from bootinfo\n\r"); if (err_is_fail(err)) return err; err = shelly_write_str("- ps\n\r"); if (err_is_fail(err)) return err; @@ -40,12 +42,15 @@ static errval_t shelly_cmd_run(char * line) { SHELLY_DEBUG("[shelly_cmd_run] line=%s\n", line); + char * module_line; + long core_id = strtol(line, &module_line, 10); + module_line += 1; // start process domainid_t pid; struct aos_rpc * rpc = aos_rpc_get_process_channel(); - err = aos_rpc_process_spawn(rpc, line, 0, &pid); + err = aos_rpc_process_spawn(rpc, module_line, core_id, &pid); if (err == SPAWN_ERR_FIND_MODULE) { - err = shelly_write_str("[run]:couldn't find module:\n\r"); + err = shelly_write_str("[run] couldn't find module:\n\r"); if (err_is_fail(err)) return err; err = shelly_write_str(line); if (err_is_fail(err)) return err;