RTEMS Shell Guide (6.a3cfaea).¶
The authors have used their best efforts in preparing this material. These efforts include the development, research, and testing of the theories and programs to determine their effectiveness. No warranty of any kind, expressed or implied, with regard to the software or the material contained in this document is provided. No liability arising out of the application or use of any product described in this document is assumed. The authors reserve the right to revise this material and to make changes from time to time in the content hereof without obligation to notify anyone of such revision or changes.
The RTEMS Project is hosted at https://www.rtems.org. Any inquiries concerning RTEMS, its related support components, or its documentation should be directed to the RTEMS Project community.
1. Preface¶
Real-time embedded systems vary widely based upon their operational and maintenance requirements. Some of these systems provide ways for the user or developer to interact with them. This interaction could be used for operational, diagnostic, or configuration purposes. The capabilities described in this manual are those provided with RTEMS to provide a command line interface for user access. Some of these commands will be familiar as standard POSIX utilities while others are RTEMS specific or helpful in debugging and analyzing an embedded system. As a simple example of the powerful and very familiar capabilities that the RTEMS Shell provides to an application, consider the following example which hints at some of the capabilities available:
Welcome to rtems-6.0.99.0(SPARC/w/FPU/sis)
COPYRIGHT (c) 1989-2011.
On-Line Applications Research Corporation (OAR).
Login into RTEMS
login: rtems
Password:
RTEMS SHELL (Ver.1.0-FRC):/dev/console. Feb 28 2008. 'help' to list commands.
SHLL [/] $ cat /etc/passwd
root:*:0:0:root::/:/bin/sh
rtems:*:1:1:RTEMS Application::/:/bin/sh
tty:!:2:2:tty owner::/:/bin/false
SHLL [/] $ ls /dev
-rwxr-xr-x 1 rtems root 0 Jan 01 00:00 console
-rwxr-xr-x 1 root root 0 Jan 01 00:00 console_b
2 files 0 bytes occupied
SHLL [/] $ stackuse
Stack usage by thread
ID NAME LOW HIGH CURRENT AVAILABLE USED
0x09010001 IDLE 0x023d89a0 - 0x023d99af 0x023d9760 4096 608
0x0a010001 UI1 0x023d9f30 - 0x023daf3f 0x023dad18 4096 1804
0x0a010002 SHLL 0x023db4c0 - 0x023df4cf 0x023de9d0 16384 6204
0xffffffff INTR 0x023d2760 - 0x023d375f 0x00000000 4080 316
SHLL [/] $ mount -L
File systems: msdos
SHLL [/] $
In the above example, the user rtems logs into a SPARC based RTEMS system. The first command is cat /etc/passwd
. This simple command lets us know that this application is running the In Memory File System (IMFS) and that the infrastructure has provided dummy entries for /etc/passwd and a few other files. The contents of /etc/passwd let us know that the user could have logged in as root
. In fact, the root
user has more permissions than rtems
who is not allowed to write into the filesystem.
The second command is ls /dev
which lets us know that RTEMS has POSIX-style device nodes which can be accesses through standard I/O function calls.
The third command executed is the RTEMS specific stackuse
which gives a report on the stack usage of each thread in the system. Since stack overflows are a common error in deeply embedded systems, this is a surprising simple, yet powerful debugging aid.
Finally, the last command, mount -L
hints that RTEMS supports a variety of mountable filesystems. With support for MS-DOS FAT on IDE/ATA and Flash devices as well as network-based filesystens such as NFS and TFTP, the standard free RTEMS provides a robuse infrastructure for embedded applications.
This manual describes the RTEMS Shell and its command set. In our terminology, the Shell is just a loop reading user input and turning that input into commands with argument. The Shell provided with RTEMS is a simple command reading loop with limited scripting capabilities. It can be connected to via a standard serial port or connected to the RTEMS telnetd
server for use across a network.
Each command in the command set is implemented as a single subroutine which has a main-style prototype. The commands interpret their arguments and operate upon stdin, stdout, and stderr by default. This allows each command to be invoked independent of the shell.
The described separation of shell from commands from communications mechanism was an important design goal. At one level, the RTEMS Shell is a complete shell environment providing access to multiple POSIX compliant filesystems and TCP/IP stack. The subset of capabilities available is easy to configure and the standard Shell can be logged into from either a serial port or via telnet. But at another level, the Shell is a large set of components which can be integrated into the user’s developed command interpreter. In either case, it is trivial to add custom commands to the command set available.
1.1. Acknowledgements¶
The Institute of Electrical and Electronics Engineers, Inc and The Open Group, have given us permission to reprint portions of their documentation.
Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (c) 2001-2004 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between this version and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html. This notice shall appear on any product containing this material.
2. Configuration and Initialization¶
2.1. Introduction¶
This chapter provides information on how the application configures and initializes the RTEMS shell.
2.2. Configuration¶
The command set available to the application is user configurable. It is configured using a mechanism similar to the confdefs.h
mechanism used to specify application configuration.
In the simplest case, if the user wishes to configure a command set with all commands available that are neither filesystem management (e.g. mounting, formating, etc.) or network related, then the following is all that is required:
#define CONFIGURE_SHELL_COMMANDS_INIT
#define CONFIGURE_SHELL_COMMANDS_ALL
#include <rtems/shellconfig.h>
In a slightly more complex example, if the user wishes to include all networking commands as well as support for mounting MS-DOS and NFS filesystems, then the following is all that is required:
#define CONFIGURE_SHELL_COMMANDS_INIT
#define CONFIGURE_SHELL_COMMANDS_ALL
#define CONFIGURE_SHELL_MOUNT_MSDOS
#define CONFIGURE_SHELL_MOUNT_NFS
#include <rtems/shellconfig.h>
The shell uses a POSIX key to reference the shell’s per thread environment. A user’s application needs to account for this key. If the application has a configuration for POSIX keys add one extra for the shell. If there is no entry add to the configuration:
#define CONFIGURE_MAXIMUM_POSIX_KEYS (5)
2.2.1. Customizing the Command Set¶
The user can configure specific command sets by either building up the set from individual commands or starting with a complete set and disabling individual commands. Each command has two configuration macros associated with it.
- CONFIGURE_SHELL_COMMAND_XXX
Each command has a constant of this form which is defined when building a command set by individually enabling specific commands.
- CONFIGURE_SHELL_NO_COMMAND_XXX
In contrast, each command has a similar command which is defined when the application is configuring a command set by disabling specific commands in the set.
2.2.2. Adding Custom Commands¶
One of the design goals of the RTEMS Shell was to make it easy for a user to add custom commands specific to their application. We believe this design goal was accomplished. In order to add a custom command, the user is required to do the following:
Provide a main-style function which implements the command. If that command function uses a
getopt
related function to parse arguments, it MUST use the reentrant form.Provide a command definition structure of type
rtems_shell_cmd_t
.Configure that command using the
CONFIGURE_SHELL_USER_COMMANDS
macro.
Custom aliases are configured similarly but the user only provides an alias definition structure of type rtems_shell_alias_t
and configures the alias via the CONFIGURE_SHELL_USER_ALIASES
macro.
In the following example, we have implemented a custom command named usercmd
which simply prints the arguments it was passed. We have also provided an alias for usercmd
named userecho
.
#include <rtems/shell.h>
int main_usercmd(int argc, char **argv)
{
int i;
printf( "UserCommand: argc=%d\n", argc );
for (i=0 ; i<argc ; i++ )
printf( "argv[%d]= %s\n", i, argv[i] );
return 0;
}
rtems_shell_cmd_t Shell_USERCMD_Command = {
"usercmd", /* name */
"usercmd n1 [n2 [n3...]]", /* usage */
"user", /* topic */
main_usercmd, /* command */
NULL, /* alias */
NULL, /* next */
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, /* mode */
0, /* uid */
0 /* gid */
};
rtems_shell_alias_t Shell_USERECHO_Alias = {
"usercmd", /* command */
"userecho" /* alias */
};
#define CONFIGURE_SHELL_USER_COMMANDS &Shell_USERCMD_Command
#define CONFIGURE_SHELL_USER_ALIASES &Shell_USERECHO_Alias
#define CONFIGURE_SHELL_COMMANDS_INIT
#define CONFIGURE_SHELL_COMMANDS_ALL
#define CONFIGURE_SHELL_MOUNT_MSDOS
#include <rtems/shellconfig.h>
Notice in the above example, that the user wrote the main for their command (e.g. main_usercmd
) which looks much like any other main()
. They then defined a rtems_shell_cmd_t
structure named Shell_USERCMD_Command
which describes that command. This command definition structure is registered into the static command set by defining CONFIGURE_SHELL_USER_COMMANDS
to &Shell_USERCMD_Command
.
Similarly, to add the userecho
alias, the user provides the alias definition structure named Shell_USERECHO_Alias
and defines CONFIGURE_SHELL_USER_ALIASES
to configure the alias.
The user can configure any number of commands and aliases in this manner.
2.3. Initialization¶
The shell may be easily attached to a serial port or to the telnetd
server. This section describes how that is accomplished.
2.3.1. Attached to a Serial Port¶
Starting the shell attached to the console or a serial port is very simple. The user invokes rtems_shell_init
with parameters to indicate the characteristics of the task that will be executing the shell including name, stack size, and priority. The user also specifies the device that the shell is to be attached to.
This example is taken from the fileio
sample test. This shell portion of this test can be run on any target which provides a console with input and output capabilities. It does not include any commands which cannot be supported on all BSPs. The source code for this test is in testsuites/samples/fileio
with the shell configuration in the init.c
file.
#include <rtems/shell.h>
void start_shell(void)
{
printf(" =========================\n");
printf(" starting shell\n");
printf(" =========================\n");
rtems_shell_init(
"SHLL", /* task name */
RTEMS_MINIMUM_STACK_SIZE * 4, /* task stack size */
100, /* task priority */
"/dev/console", /* device name */
false, /* run forever */
true, /* wait for shell to terminate */
rtems_shell_login_check /* login check function,
use NULL to disable a login check */
);
}
In the above example, the call to rtems_shell_init
spawns a task to run the RTEMS Shell attached to /dev/console
and executing at priority 100. The caller suspends itself and lets the shell take over the console device. When the shell is exited by the user, then control returns to the caller.
2.3.2. Attached to a Socket¶
TBD
2.4. Access Control¶
2.4.1. Login Checks¶
Login checks are optional for the RTEMS shell and can be configured via a login check handler passed to rtems_shell_init()
. One login check handler is rtems_shell_login_check()
.
2.4.2. Configuration Files¶
The following files are used by the login check handler rtems_shell_login_check()
to validate a passphrase for a user and to set up the user environment for the shell command execution.
/etc/passwd
The format for each line is
user_name:password:UID:GID:GECOS:directory:shell
with colon separated fields. For more information refer to the Linux PASSWD(5) man page. Use a
password
of*
to disable the login of the user. An empty password allows login without a password for this user. In contrast to standard UNIX systems, this file is only readable and writeable for the user with an UID of zero by default. Thedirectory
is used to perform a filesystem change root operation inrtems_shell_login_check()
in contrast to a normal usage as the HOME directory of the user. The default content is:root::0:0::::
so there is no password required for the
root
user./etc/group
The format for each line is:
group_name:password:GID:user_list
with colon separated fields. The
user_list
is comma separated. For more information refer to the Linux GROUP(5) man page. In contrast to standard UNIX systems, this file is only readable and writeable for the user with an UID of zero by default. The default content isroot::0:
2.4.3. Command Visibility and Execution Permission¶
Each command has:
an owner,
a group, and
a read permission flag for the owner, the group and all other users, and
an execution permission flag for the owner, the group and all other users.
The read and write permission flags are stored in the command mode. The read permission flags determine the visibility of the command for the current user. The execution permission flags determine the ability to execute a command for the current user. These command properties can be displayed and changed with the:
cmdls
,cmdchown
, andcmdchmod
commands. The access is determined by the effective UID, the effective GID and the supplementary group IDs of the current user and follows the standard filesystem access procedure.
2.4.4. Add CRYPT(3) Formats¶
By default the crypt_r()
function used by rtems_shell_login_check()
supports only plain text passphrases. Use crypt_add_format()
to add more formats. The following formats are available out of the box:
crypt_md5_format
,crypt_sha256_format
, andcrypt_sha512_format
.
An example follows:
#include <crypt.h>
void add_formats( void )
{
crypt_add_format( &crypt_md5_format );
crypt_add_format( &crypt_sha512_format );
}
2.5. Functions¶
This section describes the Shell related C functions which are publicly available related to initialization and configuration.
2.5.1. rtems_shell_init - Initialize the shell¶
- CALLING SEQUENCE:
rtems_status_code rtems_shell_init( const char *task_name, size_t task_stacksize, rtems_task_priority task_priority, const char *devname, bool forever, bool wait, rtems_login_check login_check );
- DIRECTIVE STATUS CODES:
RTEMS_SUCCESSFUL
- Shell task spawned successfully others - to indicate a failure condition- DESCRIPTION:
This service creates a task with the specified characteristics to run the RTEMS Shell attached to the specified
devname
.- NOTES:
This method invokes the
rtems_task_create
andrtems_task_start
directives and as such may return any status code that those directives may return.There is one POSIX key necessary for all shell instances together and one POSIX key value pair per instance. You should make sure that your RTEMS configuration accounts for these resources.
2.5.2. rtems_shell_login_check - Default login check handler¶
- CALLING SEQUENCE:
bool rtems_shell_login_check( const char *user, const char *passphrase );
- DIRECTIVE STATUS CODES:
true
- login is allowed, andfalse
- otherwise.- DESCRIPTION:
This function checks if the specified passphrase is valid for the specified user.
- NOTES:
As a side-effect if the specified passphrase is valid for the specified user, this function:
performs a filesystem change root operation to the directory of the specified user if the directory path is non-empty,
changes the owner of the current shell device to the UID of the specified user,
sets the real and effective UID of the current user environment to the UID of the specified user,
sets the real and effective GID of the current user environment to the GID of the specified user, and
sets the supplementary group IDs of the current user environment to the supplementary group IDs of the specified user.
In case the filesystem change root operation fails, then the environment setup is aborted and
false
is returned.
3. General Commands¶
3.1. Introduction¶
The RTEMS shell has the following general commands:
help - Print command help
alias - Add alias for an existing command
cmdls - List commands
cmdchown - Change user or owner of commands
cmdchmod - Change mode of commands
date - Print or set current date and time
echo - Produce message in a shell script
sleep - Delay for a specified amount of time
id - show uid gid euid and egid
tty - show ttyname
whoami - print effective user id
getenv - print environment variable
setenv - set environment variable
unsetenv - unset environment variable
time - time command execution
logoff - logoff from the system
rtc - RTC driver configuration
i2cdetect - detect I2C devices
i2cget - get data from an EEPROM like I2C device
i2cset - write data to an EEPROM like I2C device
spi - read and write simple data to an SPI bus
exit - alias for logoff command
3.2. Commands¶
This section details the General Commands available. A subsection is dedicated to each of the commands and describes the behavior and configuration of that command as well as providing an example usage.
3.2.1. help - Print command help¶
- SYNOPSYS:
help misc
- DESCRIPTION:
This command prints the command help. Help without arguments prints a list of topics and help with a topic prints the help for that topic.
- EXIT STATUS:
This command returns 0.
- NOTES:
The help print will break the output up based on the environment variable SHELL_LINES. If this environment variable is not set the default is 16 lines. If set the number of lines is set to that the value. If the shell lines is set 0 there will be no break.
- EXAMPLES:
The following is an example of how to use
alias
:SHLL [/] $ help help: ('r' repeat last cmd - 'e' edit last cmd) TOPIC? The topics are mem, misc, files, help, rtems, network, monitor SHLL [/] $ help misc help: list for the topic 'misc' alias - alias old new time - time command [arguments...] joel - joel [args] SCRIPT date - date [YYYY-MM-DD HH:MM:SS] echo - echo [args] sleep - sleep seconds [nanoseconds] id - show uid, gid, euid, and egid tty - show ttyname whoami - show current user logoff - logoff from the system setenv - setenv [var] [string] getenv - getenv [var] unsetenv - unsetenv [var] umask - umask [new_umask] Press any key to continue... rtc - real time clock read and set SHLL [/] $ setenv SHELL_ENV 0 SHLL [/] $ help misc help: list for the topic 'misc' alias - alias old new time - time command [arguments...] joel - joel [args] SCRIPT date - date [YYYY-MM-DD HH:MM:SS] echo - echo [args] sleep - sleep seconds [nanoseconds] id - show uid, gid, euid, and egid tty - show ttyname whoami - show current user logoff - logoff from the system setenv - setenv [var] [string] getenv - getenv [var] unsetenv - unsetenv [var