diff options
-rw-r--r-- | nuttx/ChangeLog | 5 | ||||
-rw-r--r-- | nuttx/Documentation/NuttX.html | 5 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_stdio.c | 2 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh.h | 82 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_main.c | 270 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_proccmds.c | 41 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_telnetd.c | 26 | ||||
-rw-r--r-- | nuttx/sched/sched_getprioritymax.c | 2 | ||||
-rw-r--r-- | nuttx/sched/sched_getprioritymin.c | 2 |
9 files changed, 333 insertions, 102 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 246bf4ef0..b1c599add 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -394,6 +394,7 @@ 0.3.13 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> - * Added mkfatfs command to NSH - * Added mkfifo command to NSH + * Added mkfatfs, mkfifo, sleep, usleep and nice commands to NSH + * NSH will not execute commands in background + * sched_get_priority_max/min returned error on SCHED_RR diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html index a00736b20..0daaf1afb 100644 --- a/nuttx/Documentation/NuttX.html +++ b/nuttx/Documentation/NuttX.html @@ -1028,8 +1028,9 @@ buildroot-0.1.0 2007-03-09 <spudmonkey@racsa.co.cr> <pre><ul> nuttx-0.3.13 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> - * Added mkfatfs command to NSH - * Added mkfifo command to NSH + * Added mkfatfs, mkfifo, sleep, usleep and nice commands to NSH + * NSH will not execute commands in background + * sched_get_priority_max/min returned error on SCHED_RR pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> diff --git a/nuttx/arch/sim/src/up_stdio.c b/nuttx/arch/sim/src/up_stdio.c index cfa5eb225..543407b99 100644 --- a/nuttx/arch/sim/src/up_stdio.c +++ b/nuttx/arch/sim/src/up_stdio.c @@ -63,7 +63,7 @@ size_t up_hostread(void *buffer, size_t len) { /* Just map to the host fread() */ - return fread(buffer, 1, len, stdout); + return fread(buffer, 1, len, stdin); } size_t up_hostwrite(const void *buffer, size_t len) diff --git a/nuttx/examples/nsh/nsh.h b/nuttx/examples/nsh/nsh.h index 972dc545d..3a8948b2a 100644 --- a/nuttx/examples/nsh/nsh.h +++ b/nuttx/examples/nsh/nsh.h @@ -52,7 +52,7 @@ /* This is the maximum number of arguments that will be accepted for a command */ -#define NSH_MAX_ARGUMENTS 6 +#define NSH_MAX_ARGUMENTS 6 /* strerror() produces much nicer output but is, however, quite large and * will only be used if CONFIG_NSH_STRERROR is defined. @@ -64,6 +64,32 @@ # define NSH_ERRNO errno #endif +/* The following two settings are used only in the telnetd interface */ + +#ifndef CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE +# define CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE 512 +#endif + +#ifndef CONFIG_EXAMPLES_NSH_CMD_SIZE +# define CONFIG_EXAMPLES_NSH_CMD_SIZE 40 +#endif + +/* As threads are created to handle each request, a stack must be allocated + * for the thread. Use a default if the user provided no stacksize. + */ + +#ifndef CONFIG_EXAMPLES_NSH_STACKSIZE +# define CONFIG_EXAMPLES_NSH_STACKSIZE 4096 +#endif + +/* Define to enable dumping of all input/output buffers */ + +#undef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER + +/* Sizing */ + +#define NSH_MAX_LINELEN 80 + /**************************************************************************** * Public Types ****************************************************************************/ @@ -113,42 +139,40 @@ extern int nsh_serialmain(void); /* Shell command handlers */ -#if CONFIG_NFILE_DESCRIPTORS > 0 - extern void cmd_cat(FAR void *handle, int argc, char **argv); - extern void cmd_cp(FAR void *handle, int argc, char **argv); -#endif extern void cmd_echo(FAR void *handle, int argc, char **argv); extern void cmd_exec(FAR void *handle, int argc, char **argv); extern void cmd_exit(FAR void *handle, int argc, char **argv); -#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 - extern void cmd_ifconfig(FAR void *handle, int argc, char **argv); -#endif +extern void cmd_ps(FAR void *handle, int argc, char **argv); + #if CONFIG_NFILE_DESCRIPTORS > 0 + extern void cmd_cat(FAR void *handle, int argc, char **argv); + extern void cmd_cp(FAR void *handle, int argc, char **argv); extern void cmd_ls(FAR void *handle, int argc, char **argv); +# ifndef CONFIG_DISABLE_MOUNTPOINT + extern void cmd_mkdir(FAR void *handle, int argc, char **argv); + extern void cmd_mkfifo(FAR void *handle, int argc, char **argv); + extern void cmd_rm(FAR void *handle, int argc, char **argv); + extern void cmd_rmdir(FAR void *handle, int argc, char **argv); +# ifdef CONFIG_FS_FAT + extern void cmd_mkfatfs(FAR void *handle, int argc, char **argv); + extern void cmd_mount(FAR void *handle, int argc, char **argv); + extern void cmd_umount(FAR void *handle, int argc, char **argv); +# endif /* CONFIG_FS_FAT */ +# endif /* !CONFIG_DISABLE_MOUNTPOINT */ +#endif /* CONFIG_NFILE_DESCRIPTORS */ + +#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 + extern void cmd_ifconfig(FAR void *handle, int argc, char **argv); #endif -#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 - extern void cmd_mkdir(FAR void *handle, int argc, char **argv); -# ifdef CONFIG_FS_FAT /* Need at least one filesytem in configuration */ - extern void cmd_mkfatfs(FAR void *handle, int argc, char **argv); -# endif /* CONFIG_FS_FAT */ - extern void cmd_mkfifo(FAR void *handle, int argc, char **argv); -# ifdef CONFIG_FS_FAT /* Need at least one filesytem in configuration */ - extern void cmd_mount(FAR void *handle, int argc, char **argv); -# endif /* CONFIG_FS_FAT */ -#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS */ -extern void cmd_ps(FAR void *handle, int argc, char **argv); + #ifndef CONFIG_DISABLE_ENVIRON extern void cmd_set(FAR void *handle, int argc, char **argv); -#endif -#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 - extern void cmd_rm(FAR void *handle, int argc, char **argv); - extern void cmd_rmdir(FAR void *handle, int argc, char **argv); -# ifdef CONFIG_FS_FAT /* Need at least one filesytem in configuration */ - extern void cmd_umount(FAR void *handle, int argc, char **argv); -# endif /* CONFIG_FS_FAT */ -#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS */ -#ifndef CONFIG_DISABLE_ENVIRON extern void cmd_unset(FAR void *handle, int argc, char **argv); -#endif +#endif /* CONFIG_DISABLE_ENVIRON */ + +#ifndef CONFIG_DISABLE_SIGNALS + extern void cmd_sleep(FAR void *handle, int argc, char **argv); + extern void cmd_usleep(FAR void *handle, int argc, char **argv); +#endif /* CONFIG_DISABLE_SIGNALS */ #endif /* __NSH_H */ diff --git a/nuttx/examples/nsh/nsh_main.c b/nuttx/examples/nsh/nsh_main.c index cfa3df6e8..b240df2e1 100644 --- a/nuttx/examples/nsh/nsh_main.c +++ b/nuttx/examples/nsh/nsh_main.c @@ -41,7 +41,10 @@ #include <sys/types.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> +#include <sched.h> +#include <errno.h> #include "nsh.h" @@ -115,13 +118,21 @@ static const struct cmdmap_s g_cmdmap[] = #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 { "rm", cmd_rm, 2, 2, "<file-path>" }, { "rmdir", cmd_rmdir, 2, 2, "<dir-path>" }, +#endif +#ifndef CONFIG_DISABLE_SIGNALS + { "sleep", cmd_sleep, 2, 2, "<sec>" }, +#endif /* CONFIG_DISABLE_SIGNALS */ +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 # ifdef CONFIG_FS_FAT /* Need at least one filesytem in configuration */ { "umount", cmd_umount, 2, 2, "<dir-path>" }, -#endif +# endif #endif #ifndef CONFIG_DISABLE_ENVIRON - { "unset", cmd_unset, 2, 2, "<name>" }, + { "unset", cmd_unset, 2, 2, "<name>" }, #endif +#ifndef CONFIG_DISABLE_SIGNALS + { "usleep", cmd_usleep, 2, 2, "<usec>" }, +#endif /* CONFIG_DISABLE_SIGNALS */ { NULL, NULL, 1, 1, NULL } }; @@ -156,6 +167,7 @@ static void cmd_help(FAR void *handle, int argc, char **argv) const struct cmdmap_s *ptr; nsh_output(handle, "NSH commands:\n"); + nsh_output(handle, " nice [-d] <cmd> &\n"); for (ptr = g_cmdmap; ptr->cmd; ptr++) { if (ptr->usage) @@ -179,6 +191,89 @@ static void cmd_unrecognized(FAR void *handle, int argc, char **argv) } /**************************************************************************** + * Name: nsh_execute + ****************************************************************************/ + +static int nsh_execute(int argc, char *argv[]) +{ + const struct cmdmap_s *cmdmap; + const char *cmd; + void *handle; + cmd_t handler = cmd_unrecognized; + + /* Parse all of the arguments following the command name. The form + * of argv is: + * + * argv[0]: Task name "nsh_execute" + * argv[1]: This is string version of the handle needed to execute + * the command (under telnetd). It is a string because + * binary values cannot be provided via char *argv[] + * argv[2]: The command name. This is argv[0] when the arguments + * are, finally, received by the command handler + * argv[3]: The beginning of argument (up to NSH_MAX_ARGUMENTS) + * argv[argc]: NULL terminating pointer + */ + + handle = (void*)strtol(argv[1], NULL, 16); + cmd = argv[2]; + argc -= 2; + + /* See if the command is one that we understand */ + + for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++) + { + if (strcmp(cmdmap->cmd, cmd) == 0) + { + /* Check if a valid number of arguments was provided. We + * do this simple, imperfect checking here so that it does + * not have to be performed in each command. + */ + + if (argc < cmdmap->minargs) + { + /* Fewer than the minimum number were provided */ + + nsh_output(handle, g_fmtargrequired, cmd); + return ERROR; + } + else if (argc > cmdmap->maxargs) + { + /* More than the maximum number were provided */ + + nsh_output(handle, g_fmttoomanyargs, cmd); + return ERROR; + } + else + { + /* A valid number of arguments were provided (this does + * not mean they are right). + */ + + handler = cmdmap->handler; + break; + } + } + } + + handler(handle, argc, &argv[2]); + return OK; +} + +/**************************************************************************** + * Name: nsh_setprio + ****************************************************************************/ + +static inline void nsh_setprio(void) +{ + int max_priority = sched_get_priority_max(SCHED_RR); + int min_priority = sched_get_priority_min(SCHED_RR); + struct sched_param param; + + param.sched_priority = (max_priority + min_priority) >> 1; + (void)sched_setscheduler(0, SCHED_RR, ¶m); +} + +/**************************************************************************** * Public Functions ****************************************************************************/ @@ -197,6 +292,7 @@ void user_initialize(void) int user_start(int argc, char *argv[]) { + nsh_setprio(); return nsh_main(); } @@ -206,76 +302,170 @@ int user_start(int argc, char *argv[]) int nsh_parse(FAR void *handle, char *cmdline) { - const struct cmdmap_s *cmdmap; - char *argv[NSH_MAX_ARGUMENTS+1]; - char *saveptr; - char *cmd; - int argc; + FAR char *argv[NSH_MAX_ARGUMENTS+4]; + FAR char strhandle[2*sizeof(FAR char*)+3]; + FAR char *saveptr; + FAR char *cmd; + boolean bg; + int nice = 0; + int argc; + int ret; + + memset(argv, 0, (NSH_MAX_ARGUMENTS+4)*sizeof(char*)); /* Parse out the command at the beginning of the line */ cmd = strtok_r(cmdline, " \t\n", &saveptr); if (cmd) { - cmd_t handler = cmd_unrecognized; + /* Check if the command is preceded by "nice" */ + + if (strcmp(cmd, "nice") == 0) + { + /* Nicenesses range from -20 (most favorable scheduling) to 19 + * (least favorable). Default is 10. + */ + + nice = 10; + + /* Get the cmd (or -d option of nice command) */ - /* Parse all of the arguments following the command name */ + cmd = strtok_r(NULL, " \t\n", &saveptr); + if (cmd && strcmp(cmd, "-d") == 0) + { + FAR char *val = strtok_r(NULL, " \t\n", &saveptr); + if (val) + { + char *endptr; + nice = (int)strtol(val, &endptr, 0); + if (nice > 19 || nice < -20 || endptr == val || *endptr != '\0') + { + nsh_output(handle, g_fmtarginvalid, "nice"); + return ERROR; + } + cmd = strtok_r(NULL, " \t\n", &saveptr); + } + } + } + } + /* Check if any command was provided */ - argv[0] = cmd; - for (argc = 1; argc < NSH_MAX_ARGUMENTS+1; argc++) + if (cmd) + { + /* Parse all of the arguments following the command name. The form + * of argv is: + * + * argv[0]: Not really used. It is just a place hold for where the + * task name would be if the same command were executed + * in the "background" + * argv[1]: This is string version of the handle needed to execute + * the command (under telnetd). It is a string because + * binary values cannot be provided via char *argv[] + * argv[2]: The command name. This is argv[0] when the arguments + * are, finally, received by the command handler + * argv[3]: The beginning of argument (up to NSH_MAX_ARGUMENTS) + * argv[argc]: NULL terminating pointer + */ + + sprintf(strhandle, "%p\n", handle); + argv[0] = "nsh_execute"; + argv[1] = strhandle; + argv[2] = cmd; + for (argc = 3; argc < NSH_MAX_ARGUMENTS+4; argc++) { - argv[argc] = strtok_r( NULL, " \t\n", &saveptr); + argv[argc] = strtok_r(NULL, " \t\n", &saveptr); if (!argv[argc]) { break; } } - if (argc > NSH_MAX_ARGUMENTS) + /* Check if the command should run in background */ + + bg = FALSE; + if (strcmp(argv[argc-1], "&") == 0) { - nsh_output(handle, g_fmttoomanyargs, cmd); + bg = TRUE; + argv[argc-1] = NULL; + argc--; } - /* See if the command is one that we understand */ + if (argc > NSH_MAX_ARGUMENTS+3) + { + nsh_output(handle, g_fmttoomanyargs, cmd); + } - for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++) + if (bg) { - if (strcmp(cmdmap->cmd, cmd) == 0) + struct sched_param param; + int priority; + + /* Get the execution priority of this task */ + + ret = sched_getparam(0, ¶m); + if (ret != 0) { - /* Check if a valid number of arguments was provided. We - * do this simple, imperfect checking here so that it does - * not have to be performed in each command. - */ + nsh_output(handle, g_fmtcmdfailed, cmd, "sched_getparm", NSH_ERRNO); + return ERROR; + } - if (argc < cmdmap->minargs) - { - /* Fewer than the minimum number were provided */ + /* Determine the priority to execute the command */ - nsh_output(handle, g_fmtargrequired, cmd); - return ERROR; - } - else if (argc > cmdmap->maxargs) + priority = param.sched_priority; + if (nice != 0) + { + priority -= nice; + if (nice < 0) { - /* More than the maximum number were provided */ - - nsh_output(handle, g_fmttoomanyargs, cmd); - return ERROR; + int max_priority = sched_get_priority_max(SCHED_RR); + if (priority > max_priority) + { + priority = max_priority; + } } else { - /* A valid number of arguments were provided (this does - * not mean they are right). - */ - - handler = cmdmap->handler; - break; + int min_priority = sched_get_priority_min(SCHED_RR); + if (priority < min_priority) + { + priority = min_priority; + } } } + + /* Execute the command as a separate task at the appropriate priority */ + +#ifndef CONFIG_CUSTOM_STACK + ret = task_create("nsh_execute", priority, CONFIG_EXAMPLES_NSH_STACKSIZE, + nsh_execute, &argv[1]); +#else + ret = task_create("nsh_execute", priority, nsh_execute, &argv[1]); +#endif + if (ret < 0) + { + nsh_output(handle, g_fmtcmdfailed, cmd, "task_create", NSH_ERRNO); + return ERROR; + } +#ifdef CONFIG_DEBUG + nsh_output(handle, "%s [%d:%d:%d]\n", cmd, ret, priority, param.sched_priority); +#else + nsh_output(handle, "%s [%d]\n", cmd, ret); +#endif + } + else + { + ret = nsh_execute(argc, argv); } - handler(handle, argc, argv); - return OK; + /* Return success if the command succeeded (or at least, starting of the + * command task succeeded). + */ + + if (ret == 0) + { + return OK; + } } return ERROR; diff --git a/nuttx/examples/nsh/nsh_proccmds.c b/nuttx/examples/nsh/nsh_proccmds.c index 7cd14e437..4140c277d 100644 --- a/nuttx/examples/nsh/nsh_proccmds.c +++ b/nuttx/examples/nsh/nsh_proccmds.c @@ -42,6 +42,7 @@ #include <stdio.h> #include <stdlib.h> +#include <unistd.h> #include <sched.h> #include "nsh.h" @@ -162,3 +163,43 @@ void cmd_ps(FAR void *handle, int argc, char **argv) nsh_output(handle, "PID PRI SCHD TYPE NP STATE NAME\n"); sched_foreach(ps_task, handle); } + +/**************************************************************************** + * Name: cmd_sleep + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_SIGNALS +void cmd_sleep(FAR void *handle, int argc, char **argv) +{ + char *endptr; + long secs; + + secs = strtol(argv[1], &endptr, 0); + if (!secs || endptr == argv[1] || *endptr != '\0') + { + nsh_output(handle, g_fmtarginvalid, argv[0]); + return; + } + sleep(secs); +} +#endif + +/**************************************************************************** + * Name: cmd_usleep + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_SIGNALS +void cmd_usleep(FAR void *handle, int argc, char **argv) +{ + char *endptr; + long usecs; + + usecs = strtol(argv[1], &endptr, 0); + if (!usecs || endptr == argv[1] || *endptr != '\0') + { + nsh_output(handle, g_fmtarginvalid, argv[0]); + return; + } + usleep(usecs); +} +#endif diff --git a/nuttx/examples/nsh/nsh_telnetd.c b/nuttx/examples/nsh/nsh_telnetd.c index c156fcd13..089a27faf 100644 --- a/nuttx/examples/nsh/nsh_telnetd.c +++ b/nuttx/examples/nsh/nsh_telnetd.c @@ -79,32 +79,6 @@ #define TELNET_DO 253 #define TELNET_DONT 254 -/* Configurable settings */ - -#ifndef CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE -# define CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE 512 -#endif - -#ifndef CONFIG_EXAMPLES_NSH_CMD_SIZE -# define CONFIG_EXAMPLES_NSH_CMD_SIZE 40 -#endif - -/* As threads are created to handle each request, a stack must be allocated - * for the thread. Use a default if the user provided no stacksize. - */ - -#ifndef CONFIG_EXAMPLES_NSH_STACKSIZE -# define CONFIG_EXAMPLES_NSH_STACKSIZE 4096 -#endif - -/* Enabled dumping of all input/output buffers */ - -#undef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER - -/* Sizing */ - -#define NSH_MAX_LINELEN 80 - /**************************************************************************** * Private Types ****************************************************************************/ diff --git a/nuttx/sched/sched_getprioritymax.c b/nuttx/sched/sched_getprioritymax.c index 6c1125c07..683d27660 100644 --- a/nuttx/sched/sched_getprioritymax.c +++ b/nuttx/sched/sched_getprioritymax.c @@ -90,7 +90,7 @@ int sched_get_priority_max(int policy) { - if (policy != SCHED_FIFO) + if (policy != SCHED_FIFO && policy != SCHED_RR) { return ERROR; } diff --git a/nuttx/sched/sched_getprioritymin.c b/nuttx/sched/sched_getprioritymin.c index e8b62a5f8..c57b22f6b 100644 --- a/nuttx/sched/sched_getprioritymin.c +++ b/nuttx/sched/sched_getprioritymin.c @@ -90,7 +90,7 @@ int sched_get_priority_min(int policy) { - if (policy != SCHED_FIFO) + if (policy != SCHED_FIFO && policy != SCHED_RR) { return ERROR; } |