diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-08-07 20:18:56 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-08-07 20:18:56 +0000 |
commit | 4017253a669e2647cdf54e27d1ae952d994361d3 (patch) | |
tree | 9bcbe9c4ed8c3d704c08ea4e346005ee47f6a69f /nuttx/Documentation/NuttShell.html | |
parent | 2f95fbedfe92f8f2d413eae44e68676826aabeab (diff) | |
download | px4-nuttx-4017253a669e2647cdf54e27d1ae952d994361d3.tar.gz px4-nuttx-4017253a669e2647cdf54e27d1ae952d994361d3.tar.bz2 px4-nuttx-4017253a669e2647cdf54e27d1ae952d994361d3.zip |
Update documentation to describe customization of NSH; Add the framework for a LPC43xx USB0 driver (not functional)
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5015 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/Documentation/NuttShell.html')
-rw-r--r-- | nuttx/Documentation/NuttShell.html | 901 |
1 files changed, 898 insertions, 3 deletions
diff --git a/nuttx/Documentation/NuttShell.html b/nuttx/Documentation/NuttShell.html index 0413a4695..a92cbadd8 100644 --- a/nuttx/Documentation/NuttShell.html +++ b/nuttx/Documentation/NuttShell.html @@ -335,6 +335,36 @@ <tr> <td valign="top" width="22"><img height="20" width="20" src="favicon.ico"></td> <td> + <a href="#customizingnsh">4.0 Customimizing the NuttShell</a> + </td> +</tr> +<tr> + <td><br></td> + <td> + <a href="#custonshlib">4.1 The NSH Library and NSH Initialization</a> + </td> +</tr> +<tr> + <td><br></td> + <td> + <a href="#custoncmds">4.2 NSH Commands</a> + </td> +</tr> +<tr> + <td><br></td> + <td> + <a href="#custapps">4.3 NSH "Built-In" Applications</a> + </td> +</tr> +<tr> + <td><br></td> + <td> + <a href="#custinit">4.4 Customizing NSH Initialization</a> + </td> +</tr> +<tr> + <td valign="top" width="22"><img height="20" width="20" src="favicon.ico"></td> + <td> <a href="#index">Index</a> </td> </table> @@ -655,6 +685,11 @@ mount -t vfat /dev/ram1 /tmp file system image. </p> +<p> + <b>Further Information</b>. + See the section on <a href="#customizingnsh">Customimizing the NuttShell</a> for additional, more detailed information about the NSH start-up script and how to modify it. +</p> + <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> @@ -2647,6 +2682,816 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> + <a name="customizingnsh"><h1>4.0 Customimizing the NuttShell</h1></a> + </td> + </tr> +</table> + +<p> + <b>Overview.</b> + The NuttShell (NSH) is a simple shell application that may be used with NuttX. + It supports a variety of commands and is (very) loosely based on the bash shell and the common utilities used in Unix shell programming. + The paragraphs in this appendix will focus on customizing NSH: Adding new commands, changing the initialization sequence, etc. +</p> + +<table width ="100%"> + <tr bgcolor="#e4e4e4"> + <td> + <a name="custonshlib"><h2>4.1 The NSH Library and NSH Initialization</h2></a> + </td> + </tr> +</table> + +<p> + <b>Overview.</b> + NSH is implemented as a library that can be found at <code>apps/nshlib</code>. + As a library, it can be custom built into any application that follows the NSH initialization sequence described below. + As an example, the code at <code>apps/examples/nsh/nsh_main.c</code> illustrates how to start NSH and the logic there was intended to be incorporated into your own custom code. + Although code was generated simply as an example, in the end most people just use this example code as their application <code>main()</code> function. + That initialization performed by that example is discussed in the following paragraphs. +</p> + +<h3>4.1.1 NSH Initialization sequence</h3> + +<p> + The NSH start-up sequence is very simple. + As an example, the code at <code>apps/examples/nsh/nsh_main.c</code> illustrates how to start NSH. + It simple does the following: +</p> + +<ol> + <li> + <p> + If you have C++ static initializers, it will call your implementation of <code>up_cxxinitialize()</code> which will, in turn, call those static initializers. + For the case of the STM3240G-EVAL board, the implementation of <code>up_cxxinitialize()</code> can be found at <code>nuttx/configs/stm3240g-eval/src/up_cxxinitialize.c</code>. + </p> + <li> + <p> + This function then calls <code>nsh_initialize()</code> which initializes the NSH library. + <code>nsh_initialize()</code> is described in more detail below. + </p> + <li> + <p> + If the Telnetconsole is enabled, it calls <code>nsh_telnetstart()</code> which resides in the NSH library. + <code>nsh_telnetstart()</code> will start the Telnet daemon that will listen for Telnet connections and start remote NSH sessions. + </p> + <li> + <p> + If a local console is enabled (probably on a serial port), then <code>nsh_consolemain()</code> is called. + <code>nsh_consolemain()</code> also resides in the NSH library. + <code>nsh_consolemain()</code> does not return so that finished the entire NSH initialization sequence. + </p> +</ol> + +<h3>4.1.2 <code>nsh_initialize()</code></h3> + +<p> + The NSH initialization function, <code>nsh_initialize()</code>, be found in <code>apps/nshlib/nsh_init.c</code>. + It does only three things: +</p> + +<ol> + <li> + <p> + <code>nsh_romfsetc()</code>: + If so configured, it executes an NSH start-up script that can be found at <code>/etc/init.d/rcS</code> in the target file system. + The <code>nsh_romfsetc()</code> function can be found in <code>apps/nshlib/nsh_romfsetc.c</code>. + This function will (1) register a ROMFS file system, then (2) mount the ROMFS file system. + <code>/etc</code> is the default location where a read-only, ROMFS file system is mounted by <code>nsh_romfsetc()</code>. + </p> + <p> + The ROMFS image is, itself, just built into the firmware. + By default, this <code>rcS</code> start-up script contains the following logic: + </p> +<ul><pre> +# Create a RAMDISK and mount it at XXXRDMOUNTPOUNTXXX + +mkrd -m XXXMKRDMINORXXX -s XXMKRDSECTORSIZEXXX XXMKRDBLOCKSXXX +mkfatfs /dev/ramXXXMKRDMINORXXX +mount -t vfat /dev/ramXXXMKRDMINORXXX XXXRDMOUNTPOUNTXXX +</pre></ul> + + <p> + Where the <code>XXXX*XXXX</code> strings get replaced in the template when the ROMFS image is created: + </p> + <ul> + <li> + <p> + <code>XXXMKRDMINORXXX</code> will become the RAM device minor number. + Default: 0 + </p> + <li> + <p> + <code>XXMKRDSECTORSIZEXXX</code> will become the RAM device sector size + </p> + <li> + <p> + <code>XXMKRDBLOCKSXXX</code> will become the number of sectors in the device. + </p> + <li> + <p> + <code>XXXRDMOUNTPOUNTXXX</code> will become the configured mount point. + Default: <code>/etc</code> + </p> + </ul> + <p> + By default, the substituted values would yield an <code>rcS</code> file like: + </p> +<ul><pre> +# Create a RAMDISK and mount it at /tmp + +mkrd -m 1 -s 512 1024 +mkfatfs /dev/ram1 +mount -t vfat /dev/ram1 /tmp +</pre></ul> + <p> + This script will, then: + </p> + <ul> + <li> + <p> + Create a RAMDISK of size 512*1024 bytes at <code>/dev/ram1</code>, + </p> + <li> + <p> + Format a FAT file system on the RAM disk at <code>/dev/ram1</code>, and then + </p> + <li> + <p> + Mount the FAT filesystem at a configured mountpoint, <code>/tmp</code>. + </p> + </ul> + <p> + This <code>rcS</code> template file can be found at <code>apps/nshlib/rcS.template</code>. + The resulting ROMFS file system can be found in <code>apps/nshlib/nsh_romfsimg.h</code>. + </p> + <li> + <p> + <code>nsh_archinitialize()</code>: + Next any architecture-specific NSH initialization will be performed (if any). + For the STM3240G-EVAL, this architecture specific initialization can be found at <code>configs/stm3240g-eval/src/up_nsh.c</code>. + This it does things like: (1) Initialize SPI devices, (2) Initialize SDIO, and (3) mount any SD cards that may be inserted. + </p> + <li> + <p> + <code>nsh_netinit()</code>: + The <code>nsh_netinit()</code> function can be found in <code>apps/nshlib/nsh_netinit.c</code>. + </p> +</ol> + +<table width ="100%"> + <tr bgcolor="#e4e4e4"> + <td> + <a name="custoncmds"><h2>4.2 NSH Commands</h2></a> + </td> + </tr> +</table> + +<p> + <b>Overview.</b> + NSH supports a variety of commands as part of the NSH program. + All of the NSH commands are listed in the NSH documentation <a href="#cmdoverview">above</a>. + Not all of these commands may be available at any time, however. + Many commands depend upon certain NuttX configuration options. + You can enter the help command at the NSH prompt to see the commands actual available: +</p> +<ul><pre> +nsh> help +</pre></ul> +<p> + For example, if network support is disabled, then all network-related commands will be missing from the list of commands presented by '<code>nsh> help</code>'. + You can see the specific command dependencies in the table <a href="#cmddependencies">above</a>. +</p> + +<h3>4.2.1 Adding New NSH Commands</h3> + +<p> + New commands can be added to the NSH very easily. + You simply need to add two things: +</p> +<ol> + <li> + <p> + The implementation of your command, and + </p> + <li> + <p> + A new entry in the NSH command table + </p> +</ol> + +<p> + <b>Implementation of Your Command.</b> + For example, if you want to add a new a new command called <code>mycmd</code> to NSH, you would first implement the <code>mycmd</code> code in a function with this prototype: +</p> + +<ul></pre> +int cmd_mycmd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +</pre></ul> + +<p> + The <code>argc</code> and <code>argv</code> are used to pass command line arguments to the NSH command. + Command line parameters are passed in a very standard way: <code>argv[0]</code> will be the name of the command, and <code>argv[1]</code> through <code>argv[argc-1]</code> are the additional arguments provided on the NSH command line. +</p> +<p> + The first parameter, <code>vtbl</code>, is special. + This is a pointer to session-specific state information. + You don't need to know the contents of the state information, but you do need to pass this <code>vtbl</code> argument when you interact with the NSH logic. + The only use you will need to make of the <code>vtbl</code> argument will be for outputting data to the console. + You don't use <code>printf()</code> within NSH commands. + Instead you would use: +</p> +<ul><pre> +void nsh_output(FAR struct nsh_vtbl_s *vtbl, const char *fmt, …); +</pre></ul> +<p> + So if you only wanted to output "Hello, World!" on the console, then your whole command implementation might be: +</p> +<ul><pre> +int cmd_mycmd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "e;Hello, World!"e;); + return 0; +} +</pre></ul> +<p> + The prototype for the new command should be placed in <code>apps/examples/nshlib/nsh.h></code>. +</p> + +<p> + <b>Adding You Command to the NSH Command Table</b>. + All of the commands support by NSH appear in a single table called: +</p> +<ul><pre> +const struct cmdmap_s g_cmdmap[] +</pre></ul> +<p> + That table can be found in the file <code>apps/examples/nshlib/nsh_parse.c</code>. + The structure <code>cmdmap_s</code> is also defined in <code>apps/nshlib/nsh_parse.c</code>: +</p> +<ul><pre> +struct cmdmap_s +{ + const char *cmd; /* Name of the command */ + cmd_t handler; /* Function that handles the command */ + uint8_t minargs; /* Minimum number of arguments (including command) */ + uint8_t maxargs; /* Maximum number of arguments (including command) */ + const char *usage; /* Usage instructions for 'help' command */ +}; +</pre></ul> +<p> + This structure provides everything that you need to describe your command: + Its name (<code>cmd</code>), the function that handles the command (<code>cmd_mycmd()</code>), the minimum and maximum number of arguments needed by the command, + and a string describing the command line arguments. + That last string is what is printed when enter "<code>nsh> help</code>". +</p> +<p> + So, for you sample commnd, you would add the following the to the <code>g_cmdmap[]</code> table: +</p> +<ul><pre> +{ "mycmd", cmd_mycmd, 1, 1, NULL }, +</pre></ul> + +<p> + This entry is particularly simply because <code>mycmd</code> is so simple. + Look at the other commands in <code>g_cmdmap[]</code> for more complex examples. +</p> + +<table width ="100%"> + <tr bgcolor="#e4e4e4"> + <td> + <a name="custapps"><h2>4.3 NSH "Built-In" Applications</h2></a> + </td> + </tr> +</table> + +<p> + <b>Overview.</b> + In addition to these commands that are a part of NSH, external programs can also be executed as NSH commands. + These external programs are called "Built-In" Applications for historic reasons. + That terminology is somewhat confusing because the actual NSH commands as described above are truly "built-into" NSH whereas these applications are really external to NuttX. +</p> +<p> + These applications are built-into NSH in the sense that they can be executed by simply typing the name of the application at the NSH prompt. + Built-in application support is enabled with the configuration option <code>CONFIG_NSH_BUILTIN_APPS</code>. + When this configuration option is set, you will also be able to see the built-in applications if you enter "nsh> help". + They will appear at the bottom of the list of NSH commands under: +</p> + +<ul><pre> +Builtin Apps: +</pre></ul> +<p> + Note that no detailed help information beyond the name of the built-in application is provided. +</p> + +<h3>4.3.1 Named Applications</h3> + +<p> + <b>Overview.</b> + The underlying logic that supports the NSH built-in applications is called "Named Applications". + The named application logic can be found at <code>apps/namedapp</code>. + This logic simply does the following: +</p> + +<ol> + <li> + <p> + It supports registration mechanism so that named applications can dynamically register themselves at build time, and + </p> + <li> + <p> + Utility functions to look up, list, and execute the named applications. + </p> +</ol> + +<p> + <b>Named Application Utility Functions</b>. + The utility functions exported by the named application logic are prototyped in <code>apps/include/apps.h</code>. + These utility functions include: +</p> + +<ul> + <li> + <p> + <code>int namedapp_isavail(FAR const char *appname);</code> + Checks for availability of application registered as <code>appname</code> during build time. + </p> + <li> + <p> + <code>const char *namedapp_getname(int index);</code> + Returns a pointer to a name of built-in application pointed by the <code>index</code>. + This is the utility function that is used by NSH in order to list the available built-in applications when "<code>nsh> help</code>" is entered. + </p> + <li> + <p> + <code>int exec_namedapp(FAR const char *appname, FAR const char **argv);</code> + Executes built-in named application registered during compile time. + This is the utility function used by NSH to execute the built-in application. + </p> +</ul> + +<p> + <b>Autogenerated Header Files</b>. + Application entry points with their requirements are gathered together in two files when NuttX is first built: +</p> +<ol> + <li> + <p> + <code>apps/namedapp/namedapp_proto.h</code>: + Prototypes of application task entry points. + </p> + <li> + <p> + <code>apps/namedapp/namedapp_list.h</code>: + Application specific information and start-up requirements + </p> +</ol> + +<p> + <b>Registration of Named Applications</b>. + The NuttX build occurs in several phases as different build targets are executed: + (1) <i>context</i> when the configuration is established, + (2) <i>depend </i>when target dependencies are generated, and + (3) <i>default</i> (<code>all</code>) when the normal compilation and link operations are performed. + Named application information is collected during the make <i>context</i> build phase. +</p> + +<p> + An example application that can be "built-in" is be found in the <code>apps/examples/hello directory</code>. + Let's walk through this specific cause to illustrate the general way that built-in applications are created and how they register themselves so that they can be used from NSH. +</p> + +<p> + <code><b>apps/examples/hello</code></b>. + The main routine for apps/examples/hello can be found in <code>apps/examples/hello/main.c</code>. + When <code>CONFIG_EXAMPLES_HELLO_BUILTIN</code> is defined, this main routine simplifies to: +</p> +<ul><pre> +int hello_main(int argc, char *argv[]) +{ + printf("Hello, World!!\n"); + return 0; +} +</pre></ul> + +<p> + This is the built in function that will be registered during the <i>context</i> build phase of the NuttX build. + That registration is performed by logic in <code>apps/examples/hello/Makefile</code>. + But the build system gets to that logic through a rather tortuous path: +</p> + +<ol> + <li> + <p> + The top-level context make target is in <code>nuttx/Makefile</code>. + All build targets depend upon the <i>context</i> build target. + For the <code>apps/</code> directory, this build target will execute the <i>context</i> target in the <code>apps/Makefile</code>. + </p> + <li> + <p> + The <code>apps/Makefile</code> will, in turn, execute the <i>context</i> targets in all of the configured sub-directories. + In our case will include the <code>Makefile</code> in <code>apps/examples</code>. + </p> + <li> + <p> + And finally, the <code>apps/examples/Makefile</code>will execute the <i>context</i> target in all configured <code>example</code>sub-directores, getting us finally to <code>apps/examples/Makefile</code> (which is covered below).</p> + <li> + <p> + At the conclusion of the <i>context</i> phase, the <code> apps/Makefile</code> will touch a file called <code>.context</code> in the <code>apps/</code> directory, preventing any further configurations during any subsequent <i>context</i> phase build attempts. + </p> +</ol> + +<p> + <b>NOTE</b>: + Since this context build phase can only be executed one time, any subsequent configuration changes that you make will, then, not be reflected in the build sequence. + That is a common area of confusion. + Before you can instantiate the new configuration, you have to first get rid of the old configuration. + The most drastic way to this is: +</p> +<ul><pre> +make distclean +</pre></ul> +<p> + But then you will have to re-configuration NuttX from scratch. + But if you only want to re-build the configuration in the <code>apps/</code> sub-directory, then there is a less labor-intensive way to do that. + The following NuttX make command will remove the configuration only from the <code>apps/</code> directory and will let you continue without re-configuring everything: +</p> +<ul><pre> +make apps_distclean +</pre></ul> + +<p> + Logic for the <code>context</code> target in <code>apps/examples/hello/Makefile</code> registers the <code>hello_main()</code> application in the <code>namedapp</code>'s <code>namedapp_proto.h</code>and <code>namedapp_list.h</code> files. + That logic that does that in <code>apps/examples/hello/Makefile</code> is abstracted below: +</p> +<ol> + <li> + <p> + First, the <code>Makefile</code> includes <code>apps/Make.defs</code>: + </p> +<ul><pre> +include $(APPDIR)/Make.defs +</pre></ul> + <p> + This defines a macro called <code>REGISTER</code> that adds data to the <i>namedapp</i> header files: + </p> +<ul><pre> +define REGISTER + @echo "Register: $1" + @echo "{ \"$1\", $2, $3, $4 }," >> "$(APPDIR)/namedapp/namedapp_list.h" + @echo "EXTERN int $4(int argc, char *argv[]);" >> "$(APPDIR)/namedapp/namedapp_proto.h" +endef +</pre></ul> + <p> + When this macro runs, you will see the output in the build "<code>Register: hello</code>", that is a sure sign that the registration was successful. + </p> + <li> + <p> + The make file then defines the application name (<code>hello</code>), the task priority (default), and the stack size that will be allocated in the task runs (2Kb). + </p> +<ul><pre> +APPNAME = hello +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 +</pre></ul> + + <li> + <p> + And finally, the <code>Makefile</code> invokes the <code>REGISTER</code> macro to added the <code>hello_main()</code> named application. + Then, when the system build completes, the <code>hello</code> command can be executed from the NSH command line. + When the <code>hello</code> command is executed, it will start the task with entry point <code>hello_main()</code> with the default priority and with a stack size of 2Kb. + </p> +<ul><pre> +.context: +ifeq ($(CONFIG_EXAMPLES_HELLO_BUILTIN),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) + @touch $@ +endif +</pre></ul> +</ol> + +<p> + <b>Other Uses of Named Application.</b> + The primary purpose of named applications is to support command line execution of applications from NSH. + However, there are two other uses of named applications that should be mentioned. +</p> + +<ol> + <li> + <p> + <b>Named Application Start-Up <code>main()</code> function</b>. + A named application can even be used as the main, start-up entry point into your embedded software. + When the user defines this option in the NuttX configuration file: + </p> +<ul><pre> +CONFIG_BUILTIN_APP_START=<application name> +</pre></ul> + <p> + that application will be invoked immediately after system starts instead of the normal, default <code>user_start()</code> entry point. + Note that <code><application name></code> must be provided just as it would have been on the NSH command line. + For example, <code>hello</code> would result in <code>hello_main()</code> being started at power-up. + </p> + <p> + This option might be useful in some develop environments where you use NSH only during the debug phase, but want to eliminate NSH in the final product. + Setting <code>CONFIG_BUILTIN_APP_START</code> in this way will bypass NSH and execute your application just as if it were entered from the NSH command line. + </p> + + <li> + <p><b><i>binfs</i></b>. + <i>binfs</i> is a tiny file system located at <code>apps/namedapp/binfs.c</code>. + This provides an alternative what of visualizing installed named applications. + Without <i>binfs</i>, you can see the installed named applications using the NSH help command. + <i>binfs</i> will create a tiny pseudo-file system mounted at <code>/bin</code>. + Using <i>binfs</i>, you can see the available named applications by listing the contents of <code>/bin</code> directory. + This gives some superficial Unix compatibility, but does not really add any new functionality. + </p> +</ol> + +<h3>4.3.2 Synchronous Built-In Applications</h3> + +<p> + By default, built-in commands started from the NSH command line will run asynchronously with NSH. + If you want to force NSH to execute commands then wait for the command to execute, you can enable that feature by adding the following to the NuttX configuration file: +</p> +<ul><pre> +CONFIG_SCHED_WAITPID=y +</pre></ul> +<p> + This configuration option enables support for the standard <code>waitpid()</code> RTOS interface. + When that interface is enabled, NSH will use it to wait, sleeping until the built-in application executes to completion. +</p> +<p> + Of course, even with <code>CONFIG_SCHED_WAITPID=y</code> defined, specific applications can still be forced to run asynchronously by adding the ampersand (&) after the NSH command. +</p> + +<h3>4.3.3 Application Configuration File</h3> + +<p> + <b>The appconfig File</b>. + A special configuration file is used to configure which applications are to be included in the build. + The source for this file is saved at <code>configs/<board>/<configuration>/appconfig</code>. + The existence of the <code>appconfig</code> file in the board configuration directory is sufficient to enable building of applications. +</p> + +<p> + The <code>appconfig</code> file is copied into the <code>apps/</code> directory as <code>.config</code> when NuttX is configured. + <code>.config</code> is included by the top-level <code>apps/Makefile</code>. + As a minimum, this configuration file must define files to add to the <code>CONFIGURED_APPS</code> list like: +</p> +<ul><pre> +CONFIGURED_APPS += examples/hello +</pre></ul> + +<p> + <b>Changes in the Works</b>. + There are changes in the works that will obsolete the <code>appconfig</code> file. + These changes will implement an automated configuration system for NuttX. + One consequence of this new configuration system is that the <code>appconfig</code> file will become obsolete and will be replaced by a new mechanism for selecting applications. + This new mechanism is not yet available, but is dicussed here: <a href="http://tech.groups.yahoo.com/group/nuttx/message/1604">http://tech.groups.yahoo.com/group/nuttx/message/1604</a>. +</p> + +<table width ="100%"> + <tr bgcolor="#e4e4e4"> + <td> + <a name="custinit"><h2>4.4 Customizing NSH Initialization</h2></a> + </td> + </tr> +</table> + +<p> + <b>Ways to Customize NSH Initialization</b>. + There are three ways to customize the NSH start-up behavior. + Here they are presented in order of increasing difficulty: +</p> + +<ol> + <li> + <p> + You can extend the initialization logic in <code>configs/stm3240g-eval/src/up_nsh.c</code>. + The logic there is called each time that NSH is started and is good place in particular for any device-related initialization. + </p> + <li> + <p> + You replace the sample code at <code>apps/examples/nsh/nsh_main.c</code> with whatever start-up logic that you want. + NSH is a library at <code>apps/nshlib</code>. + <code>apps.examplex/nsh</code> is just a tiny, example start-up function (<code>user_start()</code>) that that runs immediately and illustrates how to start NSH + If you want something else to run immediately then you can write your write your own custom <code>user_start()</code> function and then start other tasks from your custom <code>user_start()</code>. + </p> + <li> + <p> + NSH also supports a start-up script that executed when NSH first runs. + This mechanism has the advantage that the start-up script can contain any NSH commands and so can do a lot of work with very little coding. + The disadvantage is that is is considerably more complex to create the start-up script. + It is sufficiently complex that is deserves its own paragraph + </p> +</ol> + +<h3>4.4.1 NuttShell Start up Scripts</h3> + +<p> + First of all you should look at <a href="#startupscript">NSH Start-Up Script</a> paragraph. + Most everything you need to know can be found there. + That information will be repeated and extended here for completeness. +</p> + +<p> + <b>NSH Start-Up Script</b>. + NSH supports options to provide a start up script for NSH. + The start-up script contains any command support by NSH (i.e., that you see when you enter 'nsh> help'). + In general this capability is enabled with <code>CONFIG_NSH_ROMFSETC=y</code>, but has several other related configuration options as described with the <a href="#nshconfiguration">NSH-specific configuration settings</a> paragraph. + This capability also depends on: +</p> + +<ul> + <li> + <p> + <code>CONFIG_DISABLE_MOUNTPOINT=n</code>. + If mount point support is disabled, then you cannot mount <i>any</i> file systems. + </p> + <li> + <p> + <code>CONFIG_NFILE_DESCRIPTORS > 4</code>. + Of course you have to have file descriptions to use any thing in the file system. + </p> + <li> + <p> + <code>CONFIG_FS_ROMFS</code> enabled. + This option enables ROMFS file system support. + </p> +</ul> + +<p> + <b>Default Start-Up Behavior</b>. + The implementation that is provided is intended to provide great flexibility for the use of Start-Up files. + This paragraph will discuss the general behavior when all of the configuration options are set to the default values. +</p> +<p> + In this default case, enabling <code>CONFIG_NSH_ROMFSETC</code> will cause NSH to behave as follows at NSH start-up time: +</p> +<ul> + <li> + <p> + NSH will create a read-only RAM disk (a ROM disk), containing a tiny ROMFS filesystem containing the following: + </p> +<ul><pre> +`--init.d/ + `-- rcS +</pre></ul> + <p> + Where <code>rcS</code> is the NSH start-up script. + </p> + <li> + <p> + NSH will then mount the ROMFS filesystem at <code>/etc</code>, resulting in: + </p> +<ul><pre> +|--dev/ +| `-- ram0 +`--etc/ + `--init.d/ + `-- rcS</PRE> +</pre></ul> + <li> + <p> + By default, the contents of <code>rcS</code> script are: + </p> +<ul><pre> +# Create a RAMDISK and mount it at /tmp + +mkrd -m 1 -s 512 1024 +mkfatfs /dev/ram1 +mount -t vfat /dev/ram1 /tmp +</pre></ul> + <li> + <p> + NSH will execute the script at <code>/etc/init.d/rcS</code> at start-up (before the first NSH prompt). + After execution of the script, the root FS will look like: + </p> +<ul><pre> +|--dev/ +| |-- ram0 +| `-- ram1 +|--etc/ +| `--init.d/ +| `-- rcS +`--tmp/ +</pre></ul> +</ul> + +<p> + <b>Example Configurations</b>. + Here are some configurations that have <code>CONFIG_NSH_ROMFSETC=y</code> in the NuttX configuration file. + They might provide useful examples: +</p> +<ul> + <code>configs/hymini-stm32v/nsh2<br> + configs/ntosd-dm320/nsh<br> + configs/sim/nsh<br> + configs/sim/nsh2<br> + configs/sim/nx<br> + configs/sim/nx11<br> + configs/sim/touchscreen<br> + configs/vsn/nsh</code> +</ul> +<p> + In most of these cases, the configuration sets up the <i>default</i> <code>/etc/init.d/rcS</code> script. + The default script is here: <code>apps/nshlib/rcS.template</code>. + (The funny values in the template like <code>XXXMKRDMINORXXX</code> get replaced via <code>sed</code> at build time). + This default configuration creates a ramdisk and mounts it at <code>/tmp</code> as discussed above. +</p> +<p> + If that default behavior is not what you want, then you can provide your own custom <code>rcS</code> script by defining <code>CONFIG_NSH_ARCHROMFS=y</code> in the configuration file. + The only example that uses a custom /<code>etc/init.d/rcS</code> file in the NuttX source tree is this one: <code>configs/vsn/nsh</code>. + The <code>configs/vsn/nsh/defconfig</code> file also has this definition: +</p> +<ul><code>CONFIG_NSH_ARCHROMFS=y</code> -- Support an architecture specific ROMFS file.</ul> + +<p> + <b>Modifying the ROMFS Image</b>. + The contents of the <code>/etc</code> directory are retained in the file <code>apps/nshlib/nsh_romfsimg.h</code> OR, if <code>CONFIG_NSH_ARCHROMFS</code> is defined, <code>include/arch/board/rcs.template</code>. + In order to modify the start-up behavior, there are three things to study: +</p> + +<ol> + <li> + <p> + <b>Configuration Options.</b> + The additional <code>CONFIG_NSH_ROMFSETC</code> configuration options discussed with the other <a href="#nshconfiguration">NSH-specific configuration settings</a>. + </p> + <li> + <p> + <b><code>tools/mkromfsimg.sh</code> Script</b>. + The script <code>tools/mkromfsimg.sh</code> creates <code>nsh_romfsimg.h</code>. + It is not automatically executed. + If you want to change the configuration settings associated with creating and mounting the <code>/tmp</code> directory, then it will be necessary to re-generate this header file using the <code>tools/mkromfsimg.sh</code> script. + </p> + <p> + The behavior of this script depends upon several things: + </p> + <ol> + <li> + <p> + The configuration settings then installed configuration. + </p> + <li> + <p> + The <code>genromfs</code> tool(available from <a href="http://romfs.sourceforge.net/">http://romfs.sourceforge.net</a>) or included within the NuttX buildroot toolchain. + There is a snapshot here: <code>misc/tools/genromfs-0.5.2.tar.gz</code>. + </p> + <li> + <p> + The <code>xxd</code> tool that is used to generate the C header files (xxd is a normal part of a complete Linux or Cygwin installation, usually as part of the <code>vi</code> package). + </p> + <li> + <p> + The file <code>apps/nshlib/rcS.template</code> (OR, if <code>CONFIG_NSH_ARCHROMFS</code> is defined <code>include/arch/board/rcs.template</code>. + </p> + </ol> + <li> + <p> + <code><b>rcS.template</b></code>. + The file <code>apps/nshlib/rcS.template</code> contains the general form of the <code>rcS</code> file; configured values are plugged into this template file to produce the final <code>rcS</code> file. + </p> +</ol> + +<p> + <b><code>rcS.template</code></b>. + The default <code>rcS.template</code>, </code><code>apps/nshlib/rcS.template</code>, generates the standard, default <code>apps/nshlib/nsh_romfsimg.h</code> file. +</p> + +<p> + If <code>CONFIG_NSH_ARCHROMFS</code> is defined in the NuttX configuration file, then a custom, board-specific <code>nsh_romfsimg.h</code> file residing in <code>configs/<board>/include</code>will be used. + NOTE when the OS is configured, <code>include/arch/board</code> will be linked to <code>configs/<board>/include</code>. +</p> + +<p> + As mention above, the only example that uses a custom <code>/etc/init.d/rcS</code> file in the NuttX source tree is this one: <code>configs/vsn/nsh</code>. + The custom script for the <code>configs/vsn</code> case is located at <code>configs/vsn/include/rcS.template</code>. +</p> + +<p> + All of the startup-behavior is contained in <code>rcS.template</code>. + The role of <code>mkromfsimg.sh</code> script is to (1) apply the specific configuration settings to <code>rcS.template</code> to create the final <code>rcS</code>, and (2) to generate the header file <code>nsh_romfsimg.h</code> containg the ROMFS file system image. + To do this, <code>mkromfsimg.sh</code> uses two tools that must be installed in your system: +</p> +<ol> + <li> + <p> + The <code>genromfs</code> tool that is used to generate the ROMFS file system image.</code> + </p> + <li> + <p> + The <code>xxd</code> tool that is used to create the C header file. + </p> +</ol> +<p> + You can find the generated ROMFS file system for the <code>configs/vsn</code> case here: <code>configs/vsn/include/rcS.template</code> +</p> + +<table width ="100%"> + <tr bgcolor="#e4e4e4"> + <td> <a name="index"><h1>Index</h1></a> </td> </tr> @@ -2657,15 +3502,28 @@ nsh> <ul> <li><a href="#builtinvars"><code>$?</code></a></li> <li><a href="#cmdtest"><code>[</code></a></li> + <li><a href="#custoncmds">Adding NSH commands<</a></li> + <li><a href="#custapps"><code>appconfig</code></a></li> + <li><a href="#custapps">Application configuration file (<code>appconfig</code>)</a></li> + <li><a href="#custapps">Autogenerated header files</a></li> <li><a href="#cmdoverview">Background commands</a></li> <li><a href="#cmdoverview">Background command priority</a></li> + <li><a href="#custapps"><code>binfs</code></a></li> + <li><a href="#custapps">Built-In applications</a></li> <li><a href="#builtinvars">Built-in variables</a></li> <li><a href="#cmdcat"><code>cat</code></a></li> <li><a href="#cmdcd"><code>cd</code></a></li> <li><a href="#commands">Command summaries</a></li> + <li><a href="#custoncmds">Command table</a></li> <li><a href="#conditional">Conditional command execution</a></li> + <li><a href="#custapps"><code>CONFIG_BUILTIN_APP_START</code></a></li> + <li><a href="#custinit"><code>CONFIG_DISABLE_MOUNTPOINT</code></a></li> + <li><a href="#custinit"><code>CONFIG_FS_ROMFS</code></a></li> + <li><a href="#custinit"><code>CONFIG_NFILE_DESCRIPTORS</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_ARCHINIT</code></a></li> + <li><a href="#custinit"><code>CONFIG_NSH_ARCHROMFS</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_BUILTIN_APPS</code></a></li> + <li><a href="#custapps"><code>CONFIG_NSH_BUILTIN_APPS</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_CONSOLE</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_DHCPC</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_DISABLEBG</code></a></li> @@ -2685,6 +3543,7 @@ nsh> <li><a href="#nshconfiguration"><code>CONFIG_NSH_NOMAC</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_ROMFSDEVNO</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_ROMFSETC</code></a></li> + <li><a href="#custinit"><code>CONFIG_NSH_ROMFSETC</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_ARCHROMFS</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_ROMFSMOUNTPT</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_ROMFSSECTSIZE</code></a></li> @@ -2698,27 +3557,35 @@ nsh> <li><a href="#nshconfiguration"><code>CONFIG_NSH_USBDEV_TRACEINIT</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_USBDEV_TRACEINTERRUPTS</code></a></li> <li><a href="#nshconfiguration"><code>CONFIG_NSH_USBDEV_TRACETRANSFERS</code></a></li> + <li><a href="#custapps"><code>CONFIG_SCHED_WAITPID</code></a></li> + <li><a href="#custapps"><code>CONFIGURED_APPS</code></a></li> <li><a href="#configuration">Configuration settings</a></li> <li><a href="#cmddependencies">Configuration settings, command dependencies</a></li> <li><a href="#nshconfiguration">Configuration settings, NSH-specific</a></li> <li><a href="#cmdcp"><code>cp</code></a></li> <li><a href="#currentwd">Current working directory</a></li> + <li><a href="#customizingnsh">Customizing NSH</a></li> + <li><a href="#custinit">Customizing NSH initialization</a></li> <li><a href="#cmddate"><code>date</code></a></li> <li><a href="#cmddd"><code>dd</code></a></li> <li><a href="#cmddf"><code>df</code></a></li> -</ul></td> -<td></ul> <li><a href="#cmdecho"><code>echo</code></a></li> <li><a href="#environvars">Environment Variables</a></li> <li><a href="#startupscript"><code>/etc/init.d/rcS</code></a> <li><a href="#cmdexec"><code>exec</code></a></li> + <li><a href="#custapps"><code>exec_namedapp()</code></a></li> +</ul></td> +<td></ul> <li><a href="#cmdexit"><code>exit</code></a></li> <li><a href="#cmdfree"><code>free</code></a></li> + <li><a href="#custoncmds"><code>g_cmdmap</code></a></li> + <li><a href="#custinit"><code>genromfs</code></a></li> <li><a href="#cmdget"><code>get</code></a></li> <li><a href="#frontend">Greeting</a></li> <li><a href="#cmdhelp"><code>help</code></a></li> <li><a href="#conditional"><code>if-then[-else]-fi</code></a></li> <li><a href="#cmdifconfig"><code>ifconfig</code></a></li> + <li><a href="#custonshlib">Initialization sequence</a></li> <li><a href="#cmdkill"><code>kill</code></a></li> <li><a href="#cmdlosetup"><code>losetup</code></a></li> <li><a href="#cmdls">ls</code></a></li> @@ -2729,10 +3596,28 @@ nsh> <li><a href="#cmdmkfatfs"><code>mkfatfs</code></a></li> <li><a href="#cmdmkfifo"><code>mkfifo</code></a></li> <li><a href="#cmdmkrd"><code>mkrd</code></a></li> + <li><a href="#custinit"><code>mkromfsimg.sh</code></a></li> <li><a href="#cmdmount"><code>mount</code></a></li> <li><a href="#cmdmv"><code>mv</code></a></li> + <li><a href="#custapps">Named application start-up <code>main()</code></a></li> + <li><a href="#custapps">Named applications</a></li> + <li><a href="#custapps"><code>namedapp_getname()</code></a></li> + <li><a href="#custapps"><code>namedapp_isavail()</code></a></li> + <li><a href="#custapps"><code>namedapp_list.h</code></a></li> + <li><a href="#custapps"><code>namedapp_proto.h</code></a></li> <li><a href="#cmdnfsmount"><code>nfsmount</code></a></li> <li><a href="#cmdoverview"><code>nice</code></a></li> + <li><a href="#custonshlib">NSH library (<code>nshlib</code>)</a></li> + <li><a href="#custonshlib"><code>nsh_archinitialize()</code></a></li> + <li><a href="#custonshlib"><code>nsh_consolemain()</code></a></li> + <li><a href="#custonshlib"><code>nsh_initialize()</code></a></li> + <li><a href="#custonshlib"><code>nsh_main()</code></a></li> + <li><a href="#custinit"><code>nsh_main.c</code></a></li> + <li><a href="#custonshlib"><code>nsh_netinit()</code></a></li> + <li><a href="#custoncmds"><code>nsh_output()</code></a></li> + <li><a href="#custonshlib"><code>nsh_romfsetc()</code></a></li> + <li><a href="#custonshlib"><code>nsh_telnetstart()</code></a></li> + <li><a href="#custonshlib"><code>nshlib</code></a></li> <li><a href="#environvars"><code>OLDPWD</code></a></li> <li><a href="#overview">Overview</a></li> <li><a href="#cmdping"><code>ping</code></a></li> @@ -2741,20 +3626,30 @@ nsh> <li><a href="#cmdput"><code>put</code></a></li> <li><a href="#cmdpwd"><code>pwd</code></a></li> <li><a href="#environvars"><code>PWD</code></a></li> + <li><a href="#custinit"><code>rcS.template</code></a></li> <li><a href="#cmdoverview">Re-directed commands</a></li> + <li><a href="#custapps">Registration of named applications</a></li> <li><a href="#cmdrm"><code>rm</code></a></li> <li><a href="#cmdrmdir"><code>rmdir</code></a></li> + <li><a href="#custinit">ROMFS, Modifying the ROMFS image</a></li> <li><a href="#cmdset"><code>set</code></a></li> <li><a href="#cmdsh"><code>sh</code></a></li> <li><a href="#cmdoverview">Simple commands</a></li> <li><a href="#cmdsleep"><code>sleep</code></a></li> - <li><a href="#startupscript">start-up script</a> + <li><a href="#custinit">Start-up, Default behavior</a></li> + <li><a href="#startupscript">Start-up script</a> + <li><a href="#custinit">Start-up script</a></li> + <li><a href="#custapps">Synchronous built-in applications</a></li> <li><a href="#cmdtest"><code>test</code></a></li> <li><a href="#cmdunmount"><code>umount</code></a></li> <li><a href="#cmdunset"><code>unset</code></a></li> + <li><a href="#custonshlib"><code>up_cxxinitialize()</code></a></li> + <li><a href="#custinit"><code>up_nsh.c</code></a></li> <li><a href="#cmdusleep"><code>usleep</code></a></li> + <li><a href="#custapps"><code>waitpid()</code></a></li> <li><a href="#cmdwget"><code>wget</code></a></li> <li><a href="#cmdxd"><code>xd</code></a></li> + <li><a href="#custinit"><code>xxd</code></a></li> </ul></td> </tr></table> |