From b8940bcde553621a97752c22477a3f5d6527614a Mon Sep 17 00:00:00 2001 From: Rahix <rahix@rahix.de> Date: Sun, 11 Aug 2019 14:47:34 +0200 Subject: [PATCH] feat(api): Add initial argument passing This allows pycardium to learn which script it should start once it boots. Arguments can only be read before any API calls are made. Afterward they are lost. To ensure they won't collide with anything during a core 1 restart, they are offset by 0x20 from the start of the API buffer. Signed-off-by: Rahix <rahix@rahix.de> --- epicardium/api/caller.c | 22 ++++++++++++++++++++++ epicardium/api/caller.h | 9 +++++++++ epicardium/api/dispatcher.c | 26 ++++++++++++++++++++++---- epicardium/api/dispatcher.h | 8 ++++++-- pycardium/main.c | 19 +++++++++++++++++-- 5 files changed, 76 insertions(+), 8 deletions(-) diff --git a/epicardium/api/caller.c b/epicardium/api/caller.c index f1ba675fa..7c52d2805 100644 --- a/epicardium/api/caller.c +++ b/epicardium/api/caller.c @@ -53,3 +53,25 @@ void *_api_call_transact(void *buffer) return API_CALL_MEM->buffer; } + +int api_fetch_args(char *buf, size_t cnt) +{ + if (API_CALL_MEM->id != 0) { + /* + * When any call happened before the args are fetched, they are + * overwritten and no longer accessible. + */ + return (-1); + } + + if (API_CALL_MEM->buffer[0x20] == '\0') { + return 0; + } + + int i; + for (i = 0; i < cnt && API_CALL_MEM->buffer[i + 0x20] != '\0'; i++) { + buf[i] = API_CALL_MEM->buffer[i + 0x20]; + } + + return i - 1; +} diff --git a/epicardium/api/caller.h b/epicardium/api/caller.h index d9192c85e..93bd3f3d7 100644 --- a/epicardium/api/caller.h +++ b/epicardium/api/caller.h @@ -27,3 +27,12 @@ void *_api_call_start(api_id_t id, uintptr_t size); * - Pointer to a buffer containing the return value */ void *_api_call_transact(void *buffer); + +/* + * Fetch arguments from the API buffer. This function will only work properly + * directly after startup of core 1. If api_fetch_args() is called after other + * calls have already happened, it will return -1. + * + * Otherwise it will return the length of data which was read. + */ +int api_fetch_args(char *buf, size_t cnt); diff --git a/epicardium/api/dispatcher.c b/epicardium/api/dispatcher.c index 4675c8d4f..730579758 100644 --- a/epicardium/api/dispatcher.c +++ b/epicardium/api/dispatcher.c @@ -1,7 +1,15 @@ -#include <stdlib.h> -#include "sema.h" #include "api/dispatcher.h" + #include "max32665.h" +#include "sema.h" + +#include <stdlib.h> +#include <string.h> + +/* This function is defined by the generated dispatcher code */ +void __api_dispatch_call(api_id_t id, void *buffer); + +static volatile bool event_ready = false; int api_dispatcher_init() { @@ -20,8 +28,6 @@ int api_dispatcher_init() return ret; } -static bool event_ready = false; - bool api_dispatcher_poll_once() { if (event_ready) { @@ -68,3 +74,15 @@ api_id_t api_dispatcher_exec() return id; } + +void api_prepare_args(char *args) +{ + /* + * The args are stored with an offset of 0x20 to make sure they won't + * collide with any integer return value of API calls like epic_exec(). + */ + API_CALL_MEM->id = 0; + for (int i = 0; i <= strlen(args); i++) { + API_CALL_MEM->buffer[i + 0x20] = args[i]; + } +} diff --git a/epicardium/api/dispatcher.h b/epicardium/api/dispatcher.h index a67aa0c40..1294592d7 100644 --- a/epicardium/api/dispatcher.h +++ b/epicardium/api/dispatcher.h @@ -22,5 +22,9 @@ bool api_dispatcher_poll(); */ api_id_t api_dispatcher_exec(); -/* This function is defined by the generated dispatcher code */ -void __api_dispatch_call(api_id_t id, void *buffer); +/* + * Fill the API buffer with data for l0dable/pycardium startup. + * + * The data is a NULL-terminated string. + */ +void api_prepare_args(char *args); diff --git a/pycardium/main.c b/pycardium/main.c index 60c86093a..78450da0b 100644 --- a/pycardium/main.c +++ b/pycardium/main.c @@ -1,4 +1,5 @@ #include "epicardium.h" +#include "api/caller.h" #include "mphalport.h" #include "card10-version.h" @@ -24,10 +25,19 @@ static const char header[] = int main(void) { - epic_uart_write_str(header, sizeof(header)); + char script_name[128] = { 0 }; + int cnt = api_fetch_args(script_name, sizeof(script_name)); pycardium_hal_init(); + epic_uart_write_str(header, sizeof(header)); + + if (cnt < 0) { + printf("pycardium: Error fetching args: %d\n", cnt); + } else if (cnt > 0) { + printf(" Loading %s ...\n", script_name); + } + mp_stack_set_top(&__StackTop); mp_stack_set_limit((mp_int_t)&__StackLimit); @@ -35,8 +45,13 @@ int main(void) gc_init(&__HeapBase + 1024 * 10, &__HeapLimit); mp_init(); - pyexec_file_if_exists("main.py"); + + if (cnt > 0) { + pyexec_file_if_exists(script_name); + } + pyexec_friendly_repl(); + mp_deinit(); } } -- GitLab