From 2c28605d0d0d2bb8f90844c70f435f904037a5de Mon Sep 17 00:00:00 2001 From: Travis Geiselbrecht Date: Tue, 25 May 2021 23:04:41 -0700 Subject: [PATCH] [app] add a standalone routine and a command line app start routine --- app/app.c | 82 +++++++++++++++++++++++++++++++++++++++++++---- app/include/app.h | 9 +++++- 2 files changed, 83 insertions(+), 8 deletions(-) diff --git a/app/app.c b/app/app.c index 789f3d48..e436d748 100644 --- a/app/app.c +++ b/app/app.c @@ -5,14 +5,18 @@ * license that can be found in the LICENSE file or at * https://opensource.org/licenses/MIT */ +#include "app.h" + #include -#include +#include +#include +#include #include extern const struct app_descriptor __start_apps __WEAK; extern const struct app_descriptor __stop_apps __WEAK; -static void start_app(const struct app_descriptor *app); +static void start_app(const struct app_descriptor *app, bool detach); /* one time setup */ void apps_init(void) { @@ -26,8 +30,8 @@ void apps_init(void) { /* start any that want to start on boot */ for (app = &__start_apps; app != &__stop_apps; app++) { - if (app->entry && (app->flags & APP_FLAG_DONT_START_ON_BOOT) == 0) { - start_app(app); + if (app->entry && (app->flags & APP_FLAG_NO_AUTOSTART) == 0) { + start_app(app, true); } } } @@ -40,12 +44,76 @@ static int app_thread_entry(void *arg) { return 0; } -static void start_app(const struct app_descriptor *app) { +static void start_app(const struct app_descriptor *app, bool detach) { uint32_t stack_size = (app->flags & APP_FLAG_CUSTOM_STACK_SIZE) ? app->stack_size : DEFAULT_STACK_SIZE; printf("starting app %s\n", app->name); thread_t *t = thread_create(app->name, &app_thread_entry, (void *)app, DEFAULT_PRIORITY, stack_size); - thread_detach(t); - thread_resume(t); + if (detach) { + thread_detach(t); + thread_resume(t); + } else { + thread_resume(t); + thread_join(t, NULL, INFINITE_TIME); + } } +status_t app_start_by_name(const char *name, bool detached) { + const struct app_descriptor *app; + + /* find the app and call it */ + for (app = &__start_apps; app != &__stop_apps; app++) { + if (!strcmp(app->name, name)) { + start_app(app, detached); + return NO_ERROR; + } + } + + return ERR_NOT_FOUND; +} + +static void list_apps(void) { + const struct app_descriptor *app; + + for (app = &__start_apps; app != &__stop_apps; app++) { + printf("%s\n", app->name); + } +} + +static int cmd_app(int argc, const console_cmd_args *argv) { + if (argc == 1) { +usage: + printf("%s subcommands:\n", argv[0].str); + printf("%s list : list apps compiled into the system\n", argv[0].str); + printf("%s start : run app\n", argv[0].str); + return ERR_INVALID_ARGS; + } else if (!strcmp(argv[1].str, "list")) { + list_apps(); + } else if (!strcmp(argv[1].str, "start")) { + if (argc <= 2) { + printf("not enough args\n"); + goto usage; + } + + app_start_by_name(argv[2].str, false); + } else { + printf("unknown subcommand\n"); + goto usage; + } + + return NO_ERROR; +} + +static int cmd_start(int argc, const console_cmd_args *argv) { + if (argc == 1) { + printf("not enough args\n"); + return ERR_INVALID_ARGS; + } + + return app_start_by_name(argv[1].str, false); +} + +STATIC_COMMAND_START +STATIC_COMMAND("app", "commands to operate on apps", &cmd_app) +STATIC_COMMAND("start", "shortcut for app start", &cmd_start) +STATIC_COMMAND_END(app); diff --git a/app/include/app.h b/app/include/app.h index ded9cb0b..19ac3b2e 100644 --- a/app/include/app.h +++ b/app/include/app.h @@ -9,19 +9,26 @@ #include #include +#include +#include __BEGIN_CDECLS /* app support api */ void apps_init(void); /* one time setup */ +/* start an app by name. + * optionally start detached or wait for it to complete. + */ +status_t app_start_by_name(const char *name, bool detached); + /* app entry point */ struct app_descriptor; typedef void (*app_init)(const struct app_descriptor *); typedef void (*app_entry)(const struct app_descriptor *, void *args); /* app startup flags */ -#define APP_FLAG_DONT_START_ON_BOOT 0x1 +#define APP_FLAG_NO_AUTOSTART 0x1 #define APP_FLAG_CUSTOM_STACK_SIZE 0x2 /* each app needs to define one of these to define its startup conditions */