[app] add a standalone routine and a command line app start routine
This commit is contained in:
82
app/app.c
82
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 <stdio.h>
|
||||
#include <app.h>
|
||||
#include <string.h>
|
||||
#include <lk/err.h>
|
||||
#include <lk/console_cmd.h>
|
||||
#include <kernel/thread.h>
|
||||
|
||||
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 <name> : 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);
|
||||
|
||||
@@ -9,19 +9,26 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <lk/compiler.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__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 */
|
||||
|
||||
Reference in New Issue
Block a user