summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2009-09-15 21:11:42 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2009-09-15 21:11:42 +0000
commitf421fee4651720bb84f69b4584cebd6129adc5f4 (patch)
tree88acd261d45996cea57d06a507edfdc6061bf025
parent9253a0c46605cd844420e6d59f7f08b5aac438c2 (diff)
2009-09-15 Joel Sherrill <joel.sherrill@oarcorp.com>
* .cvsignore, ChangeLog, Makefile, README, commands.adb, commands.ads, config.h, main.adb, rtems_shell.ads, shell_init.c: New files.
-rw-r--r--shell/.cvsignore5
-rw-r--r--shell/ChangeLog8
-rw-r--r--shell/Makefile35
-rw-r--r--shell/README11
-rw-r--r--shell/commands.adb35
-rw-r--r--shell/commands.ads21
-rw-r--r--shell/config.h13
-rw-r--r--shell/main.adb21
-rw-r--r--shell/rtems_shell.ads43
-rw-r--r--shell/shell_init.c152
10 files changed, 344 insertions, 0 deletions
diff --git a/shell/.cvsignore b/shell/.cvsignore
new file mode 100644
index 0000000..cf1b678
--- /dev/null
+++ b/shell/.cvsignore
@@ -0,0 +1,5 @@
+b~hello.adb
+b~hello.ads
+b~hello.ali
+hello
+hello.ali
diff --git a/shell/ChangeLog b/shell/ChangeLog
new file mode 100644
index 0000000..7c8e66f
--- /dev/null
+++ b/shell/ChangeLog
@@ -0,0 +1,8 @@
+2009-09-15 Joel Sherrill <joel.sherrill@oarcorp.com>
+
+ * .cvsignore, ChangeLog, Makefile, README, commands.adb, commands.ads,
+ config.h, main.adb, rtems_shell.ads, shell_init.c: New files.
+
+2009-09-13 Cynthia Cicalese <cicalese@mitre.org>
+
+ * Created example.
diff --git a/shell/Makefile b/shell/Makefile
new file mode 100644
index 0000000..43ccc72
--- /dev/null
+++ b/shell/Makefile
@@ -0,0 +1,35 @@
+#
+# $Id$
+#
+
+PROGRAM=shell
+
+include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+LINKARGS += -ltelnetd
+
+# stack size for the first Ada thread
+CFLAGS +=-DGNAT_MAIN_STACKSPACE=100
+
+# initialize the network stack -- assumes existence of networkconfig.h
+CFLAGS +=-DMAIN_USE_NETWORKING=1
+
+# Should we prompt for command line arguments?
+# DEFINES +=-DMAIN_USE_REQUIRES_COMMAND_LINE
+
+# If you want to hard-code the command line, define this to a string
+# DEFINES += -DMAIN_COMMAND_LINE="ARGS"
+
+# Do we have extra configuration?
+DEFINES += -DHAS_EXTRA_CONFIGURATION
+
+# Some tests need to be able to do a gethostbyname
+NEED_ROOTFS_FOR_HOST_INFO=yes
+
+EXTRA_OBJS=shell_init.o
+
+include ../Makefile.shared
+
+shell_init.o: shell_init.c
diff --git a/shell/README b/shell/README
new file mode 100644
index 0000000..8c097e3
--- /dev/null
+++ b/shell/README
@@ -0,0 +1,11 @@
+#
+# $Id$
+#
+
+This directory contains an example of using an Ada application
+with the RTEMS Shell and telnetd. It demonstrates how to
+add your own custom commands to the RTEMS Shell.
+
+See the README.Makefiles in the top directory for instructions
+on building for most BSPs.
+
diff --git a/shell/commands.adb b/shell/commands.adb
new file mode 100644
index 0000000..d7971ce
--- /dev/null
+++ b/shell/commands.adb
@@ -0,0 +1,35 @@
+--
+-- $Id$
+--
+
+with Ada.Text_IO; use Ada.Text_IO;
+
+package body Commands is
+
+ function Prompt return String is begin
+ return "RTEMS> ";
+ end Prompt;
+
+ function C_Prompt return chars_ptr is
+ begin
+ return New_String (Prompt);
+ end C_Prompt;
+
+ function Command_Test_Arguments
+ (ArgC : Argument_Count_Type;
+ ArgV : Argument_Vector_Type)
+ return int
+ is
+ Arguments : Argument_Array (1 .. ArgC);
+ Count : Argument_Count_Type := 1;
+ begin
+ Arguments := Argument_Vector_Package.Value (ArgV, ArgC);
+ loop
+ exit when Count > ArgC;
+ Put_Line (Value (Arguments (Count)));
+ Count := Count + 1;
+ end loop;
+ return 0;
+ end Command_Test_Arguments;
+
+end Commands;
diff --git a/shell/commands.ads b/shell/commands.ads
new file mode 100644
index 0000000..ce47730
--- /dev/null
+++ b/shell/commands.ads
@@ -0,0 +1,21 @@
+--
+-- $Id$
+--
+
+with Interfaces.C; use Interfaces.C;
+with Interfaces.C.Strings; use Interfaces.C.Strings;
+with RTEMS_Shell; use RTEMS_Shell;
+
+package Commands is
+
+ function Prompt return String;
+ function C_Prompt return chars_ptr;
+ pragma Convention (C, C_Prompt);
+
+ function Command_Test_Arguments
+ (ArgC : Argument_Count_Type;
+ ArgV : Argument_Vector_Type)
+ return int;
+ pragma Convention (C, Command_Test_Arguments);
+
+end Commands;
diff --git a/shell/config.h b/shell/config.h
new file mode 100644
index 0000000..0461f88
--- /dev/null
+++ b/shell/config.h
@@ -0,0 +1,13 @@
+/*
+ * Extra configuration for telnet/shell
+ *
+ * $Id$
+ */
+
+#define CONFIGURE_MAXIMUM_PTYS 8
+
+#define CONFIGURE_STACK_CHECKER_ENABLED
+
+#define ADA_APPLICATION_NEEDS_EXTRA_MEMORY 256
+
+#define CONFIGURE_MAXIMUM_DRIVERS 10
diff --git a/shell/main.adb b/shell/main.adb
new file mode 100644
index 0000000..a4ae014
--- /dev/null
+++ b/shell/main.adb
@@ -0,0 +1,21 @@
+--
+-- $Id$
+--
+
+with Interfaces.C.Strings; use Interfaces.C.Strings;
+with Commands; use Commands;
+with RTEMS_Shell; use RTEMS_Shell;
+
+procedure Main is
+begin
+ RTEMS_Shell_Add_Command
+ (New_String ("args"),
+ New_String ("test"),
+ New_String ("Test passing arguments"),
+ Command_Test_Arguments'Access);
+ Set_RTEMS_Shell_Prompt_Function (C_Prompt'Access);
+ Initialize_Telnet_Daemon;
+ loop
+ Invoke_RTEMS_Shell;
+ end loop;
+end Main;
diff --git a/shell/rtems_shell.ads b/shell/rtems_shell.ads
new file mode 100644
index 0000000..8f7b5d6
--- /dev/null
+++ b/shell/rtems_shell.ads
@@ -0,0 +1,43 @@
+--
+-- $Id$
+--
+
+with Interfaces.C; use Interfaces.C;
+with Interfaces.C.Strings; use Interfaces.C.Strings;
+with Interfaces.C.Pointers;
+
+package RTEMS_Shell is
+
+ type Argument_Array is array (ptrdiff_t range <>) of aliased chars_ptr;
+
+ package Argument_Vector_Package is
+ new Pointers (Index => ptrdiff_t,
+ Element => chars_ptr,
+ Element_Array => Argument_Array,
+ Default_Terminator => Null_Ptr);
+
+ subtype Argument_Count_Type is ptrdiff_t;
+ subtype Argument_Vector_Type is Argument_Vector_Package.Pointer;
+
+ type Command_Function_Type is access function (ArgC : Argument_Count_Type;
+ ArgV : Argument_Vector_Type) return int;
+ pragma Convention (C, Command_Function_Type);
+
+ procedure RTEMS_Shell_Add_Command(Name : chars_ptr; Category : chars_ptr;
+ Help : chars_ptr; Command_Function : Command_Function_Type);
+ pragma Import (C, RTEMS_Shell_Add_Command, "rtems_shell_add_cmd");
+
+ type Prompt_Function_Type is access function return chars_ptr;
+ pragma Convention (C, Prompt_Function_Type);
+
+ procedure Set_RTEMS_Shell_Prompt_Function(
+ Prompt_Function : Prompt_Function_Type);
+ pragma Import (C, Set_RTEMS_Shell_Prompt_Function, "set_prompt_function");
+
+ procedure Invoke_RTEMS_Shell;
+ pragma Import (C, Invoke_RTEMS_Shell, "invoke_rtems_shell");
+
+ procedure Initialize_Telnet_Daemon;
+ pragma Import (C, Initialize_Telnet_Daemon, "init_telnet_daemon");
+
+end RTEMS_Shell;
diff --git a/shell/shell_init.c b/shell/shell_init.c
new file mode 100644
index 0000000..32d7bbe
--- /dev/null
+++ b/shell/shell_init.c
@@ -0,0 +1,152 @@
+/*
+ * This is a derived from the init.c file in the telnetd demo.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+
+#include <errno.h>
+#include <time.h>
+
+#include <stdio.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/telnetd.h>
+#include <rtems/shell.h>
+
+#include <rtems/error.h>
+#include <rpc/rpc.h>
+#include <netinet/in.h>
+#include <time.h>
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include "../networkconfig.h"
+
+// I'm not sure why this is necessary
+#include <rtems/bdbuf.h>
+const rtems_bdbuf_config rtems_bdbuf_configuration;
+
+typedef char * (* prompt_function_t)(void);
+
+static prompt_function_t prompt_function = NULL;
+
+extern void set_prompt_function(prompt_function_t f)
+{
+ prompt_function = f;
+}
+
+extern char * get_prompt(void);
+void rtems_shell_get_prompt(
+ rtems_shell_env_t *shell_env,
+ char *prompt,
+ size_t size
+)
+{
+ char curdir[256];
+
+ if (prompt_function == NULL)
+ {
+ getcwd(curdir,sizeof(curdir));
+ snprintf(prompt, size - 1, "%s%s[%s] %c ",
+ ((shell_env->taskname) ? shell_env->taskname : ""),
+ ((shell_env->taskname) ? " " : ""),
+ curdir,
+ geteuid()?'$':'#');
+
+ }
+ else
+ snprintf(prompt, size - 1, prompt_function());
+}
+
+/*
+ * If true, listen on socket(s).
+ * If false, remain on console.
+ */
+/* #define REMAIN_ON_CONSOLE */
+bool remain_on_console = false;
+
+#include <rtems/shell.h>
+
+#define SHELL_HELP_MSG \
+ "Starting rtemsShell via telnetd -- default account is rtems w/no password\n"
+
+#define CONFIGURE_SHELL_COMMANDS_ALL_NETWORKING
+#define CONFIGURE_SHELL_COMMANDS_ALL
+
+#define CONFIGURE_SHELL_COMMANDS_INIT
+#include <rtems/shellconfig.h>
+
+
+static void rtemsShell(
+ char *pty_name,
+ void *cmd_arg
+)
+{
+ rtems_shell_env_t env = rtems_global_shell_env;
+
+ env.devname = pty_name;
+ env.taskname = "TLNT";
+ env.login_check = rtems_shell_login_check;
+
+ if ( !remain_on_console )
+ printk("============== Starting Shell ==============\n");
+
+ rtems_shell_main_loop( &env );
+
+ if ( !remain_on_console )
+ printk("============== Exiting Shell ==============\n");
+}
+
+#define SHELL_ENTRY rtemsShell
+
+/*
+ * Telnet demon configuration
+ */
+rtems_telnetd_config_table rtems_telnetd_config = {
+ .command = SHELL_ENTRY,
+ .arg = NULL,
+ .priority = 1, /* We feel important today */
+ .stack_size = 20 * RTEMS_MINIMUM_STACK_SIZE, /* Shell needs a large stack */
+ .login_check = NULL, /* Shell asks for user and password */
+ .keep_stdio = false
+};
+
+/*
+ * Initialization Aid
+ */
+void init_telnet_daemon(void)
+{
+ fprintf(stderr, "\n\n*** Telnetd Server Test ***\n\r" );
+
+ fprintf(stderr, "============== Initializing Network ==============\n");
+ rtems_bsdnet_initialize_network ();
+
+ fprintf(stderr, "============== Add Route ==============\n");
+ rtems_bsdnet_show_inet_routes ();
+
+ fprintf(stderr, "============== Start Telnetd ==============\n");
+
+ printk( SHELL_HELP_MSG );
+
+ #if defined(REMAIN_ON_CONSOLE)
+ remain_on_console = true;
+ #endif
+
+ rtems_global_shell_env.login_check = rtems_shell_login_check;
+ rtems_telnetd_config.keep_stdio = remain_on_console;
+
+ rtems_telnetd_initialize();
+}
+
+
+#include <stdlib.h>
+#include <rtems.h>
+#include <rtems/telnetd.h>
+
+/* Helper for Ada */
+void invoke_rtems_shell(void)
+{
+ rtemsShell("console", NULL);
+}
+