diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 603d2db97f..614381c900 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3131,4 +3131,11 @@ point numbers. * lib/stdio/lib_libdtoa.c and lib_libvsprintf.c: Correct some floating point options. + * arch/arm/lpc43xx/lpc32_usb0dev.c: Add framework for development of + an USB0, device-side driver for the LPC43XX. The initial check-in, + however, is simply for the LPC31xx driver with name changes. The + LPC31xx has the same USB IP, but will require some additional initialization + (and lots of testing) before it can be used with the LPC43xx. + * nuttx/Documentation/NuttShell.html: Added a section covering ways to + customize the behavior or NSH. diff --git a/nuttx/Documentation/NuttShell.html b/nuttx/Documentation/NuttShell.html index 0413a46956..a92cbadd8e 100644 --- a/nuttx/Documentation/NuttShell.html +++ b/nuttx/Documentation/NuttShell.html @@ -332,6 +332,36 @@ 3.2 NSH-Specific Configuration Settings +
+ Further Information. + See the section on Customimizing the NuttShell for additional, more detailed information about the NSH start-up script and how to modify it. +
+| @@ -2644,6 +2679,816 @@ nsh> |
+ 4.0 Customimizing the NuttShell+ |
+
+ Overview. + 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. +
+ +
+ 4.1 The NSH Library and NSH Initialization+ |
+
+ Overview.
+ NSH is implemented as a library that can be found at apps/nshlib.
+ 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 apps/examples/nsh/nsh_main.c 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 main() function.
+ That initialization performed by that example is discussed in the following paragraphs.
+
+ The NSH start-up sequence is very simple.
+ As an example, the code at apps/examples/nsh/nsh_main.c illustrates how to start NSH.
+ It simple does the following:
+
+ If you have C++ static initializers, it will call your implementation of up_cxxinitialize() which will, in turn, call those static initializers.
+ For the case of the STM3240G-EVAL board, the implementation of up_cxxinitialize() can be found at nuttx/configs/stm3240g-eval/src/up_cxxinitialize.c.
+
+ This function then calls nsh_initialize() which initializes the NSH library.
+ nsh_initialize() is described in more detail below.
+
+ If the Telnetconsole is enabled, it calls nsh_telnetstart() which resides in the NSH library.
+ nsh_telnetstart() will start the Telnet daemon that will listen for Telnet connections and start remote NSH sessions.
+
+ If a local console is enabled (probably on a serial port), then nsh_consolemain() is called.
+ nsh_consolemain() also resides in the NSH library.
+ nsh_consolemain() does not return so that finished the entire NSH initialization sequence.
+
nsh_initialize()
+ The NSH initialization function, nsh_initialize(), be found in apps/nshlib/nsh_init.c.
+ It does only three things:
+
+ nsh_romfsetc():
+ If so configured, it executes an NSH start-up script that can be found at /etc/init.d/rcS in the target file system.
+ The nsh_romfsetc() function can be found in apps/nshlib/nsh_romfsetc.c.
+ This function will (1) register a ROMFS file system, then (2) mount the ROMFS file system.
+ /etc is the default location where a read-only, ROMFS file system is mounted by nsh_romfsetc().
+
+ The ROMFS image is, itself, just built into the firmware.
+ By default, this rcS start-up script contains the following logic:
+
+# Create a RAMDISK and mount it at XXXRDMOUNTPOUNTXXX + +mkrd -m XXXMKRDMINORXXX -s XXMKRDSECTORSIZEXXX XXMKRDBLOCKSXXX +mkfatfs /dev/ramXXXMKRDMINORXXX +mount -t vfat /dev/ramXXXMKRDMINORXXX XXXRDMOUNTPOUNTXXX ++ +
+ Where the XXXX*XXXX strings get replaced in the template when the ROMFS image is created:
+
+ XXXMKRDMINORXXX will become the RAM device minor number.
+ Default: 0
+
+ XXMKRDSECTORSIZEXXX will become the RAM device sector size
+
+ XXMKRDBLOCKSXXX will become the number of sectors in the device.
+
+ XXXRDMOUNTPOUNTXXX will become the configured mount point.
+ Default: /etc
+
+ By default, the substituted values would yield an rcS file like:
+
+# Create a RAMDISK and mount it at /tmp + +mkrd -m 1 -s 512 1024 +mkfatfs /dev/ram1 +mount -t vfat /dev/ram1 /tmp ++
+ This script will, then: +
+
+ Create a RAMDISK of size 512*1024 bytes at /dev/ram1,
+
+ Format a FAT file system on the RAM disk at /dev/ram1, and then
+
+ Mount the FAT filesystem at a configured mountpoint, /tmp.
+
+ This rcS template file can be found at apps/nshlib/rcS.template.
+ The resulting ROMFS file system can be found in apps/nshlib/nsh_romfsimg.h.
+
+ nsh_archinitialize():
+ Next any architecture-specific NSH initialization will be performed (if any).
+ For the STM3240G-EVAL, this architecture specific initialization can be found at configs/stm3240g-eval/src/up_nsh.c.
+ This it does things like: (1) Initialize SPI devices, (2) Initialize SDIO, and (3) mount any SD cards that may be inserted.
+
+ nsh_netinit():
+ The nsh_netinit() function can be found in apps/nshlib/nsh_netinit.c.
+
+ 4.2 NSH Commands+ |
+
+ Overview. + NSH supports a variety of commands as part of the NSH program. + All of the NSH commands are listed in the NSH documentation above. + 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: +
++nsh> help ++
+ For example, if network support is disabled, then all network-related commands will be missing from the list of commands presented by 'nsh> help'.
+ You can see the specific command dependencies in the table above.
+
+ New commands can be added to the NSH very easily. + You simply need to add two things: +
++ The implementation of your command, and +
++ A new entry in the NSH command table +
+
+ Implementation of Your Command.
+ For example, if you want to add a new a new command called mycmd to NSH, you would first implement the mycmd code in a function with this prototype:
+
+ The argc and argv are used to pass command line arguments to the NSH command.
+ Command line parameters are passed in a very standard way: argv[0] will be the name of the command, and argv[1] through argv[argc-1] are the additional arguments provided on the NSH command line.
+
+ The first parameter, vtbl, 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 vtbl argument when you interact with the NSH logic.
+ The only use you will need to make of the vtbl argument will be for outputting data to the console.
+ You don't use printf() within NSH commands.
+ Instead you would use:
+
+void nsh_output(FAR struct nsh_vtbl_s *vtbl, const char *fmt, …); ++
+ So if you only wanted to output "Hello, World!" on the console, then your whole command implementation might be: +
+
+int cmd_mycmd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+{
+ nsh_output(vtbl, "e;Hello, World!"e;);
+ return 0;
+}
+
+
+ The prototype for the new command should be placed in apps/examples/nshlib/nsh.h>.
+
+ Adding You Command to the NSH Command Table. + All of the commands support by NSH appear in a single table called: +
++const struct cmdmap_s g_cmdmap[] ++
+ That table can be found in the file apps/examples/nshlib/nsh_parse.c.
+ The structure cmdmap_s is also defined in apps/nshlib/nsh_parse.c:
+
+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 */
+};
+
+
+ This structure provides everything that you need to describe your command:
+ Its name (cmd), the function that handles the command (cmd_mycmd()), 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 "nsh> help".
+
+ So, for you sample commnd, you would add the following the to the g_cmdmap[] table:
+
+{ "mycmd", cmd_mycmd, 1, 1, NULL },
+
+
+
+ This entry is particularly simply because mycmd is so simple.
+ Look at the other commands in g_cmdmap[] for more complex examples.
+
+ 4.3 NSH "Built-In" Applications+ |
+
+ Overview. + 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. +
+
+ 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 CONFIG_NSH_BUILTIN_APPS.
+ 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:
+
+Builtin Apps: ++
+ Note that no detailed help information beyond the name of the built-in application is provided. +
+ +
+ Overview.
+ The underlying logic that supports the NSH built-in applications is called "Named Applications".
+ The named application logic can be found at apps/namedapp.
+ This logic simply does the following:
+
+ It supports registration mechanism so that named applications can dynamically register themselves at build time, and +
++ Utility functions to look up, list, and execute the named applications. +
+
+ Named Application Utility Functions.
+ The utility functions exported by the named application logic are prototyped in apps/include/apps.h.
+ These utility functions include:
+
+ int namedapp_isavail(FAR const char *appname);
+ Checks for availability of application registered as appname during build time.
+
+ const char *namedapp_getname(int index);
+ Returns a pointer to a name of built-in application pointed by the index.
+ This is the utility function that is used by NSH in order to list the available built-in applications when "nsh> help" is entered.
+
+ int exec_namedapp(FAR const char *appname, FAR const char **argv);
+ Executes built-in named application registered during compile time.
+ This is the utility function used by NSH to execute the built-in application.
+
+ Autogenerated Header Files. + Application entry points with their requirements are gathered together in two files when NuttX is first built: +
+
+ apps/namedapp/namedapp_proto.h:
+ Prototypes of application task entry points.
+
+ apps/namedapp/namedapp_list.h:
+ Application specific information and start-up requirements
+
+ Registration of Named Applications.
+ The NuttX build occurs in several phases as different build targets are executed:
+ (1) context when the configuration is established,
+ (2) depend when target dependencies are generated, and
+ (3) default (all) when the normal compilation and link operations are performed.
+ Named application information is collected during the make context build phase.
+
+ An example application that can be "built-in" is be found in the apps/examples/hello directory.
+ 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.
+
+ apps/examples/hello.
+ The main routine for apps/examples/hello can be found in apps/examples/hello/main.c.
+ When CONFIG_EXAMPLES_HELLO_BUILTIN is defined, this main routine simplifies to:
+
+int hello_main(int argc, char *argv[])
+{
+ printf("Hello, World!!\n");
+ return 0;
+}
+
+
+
+ This is the built in function that will be registered during the context build phase of the NuttX build.
+ That registration is performed by logic in apps/examples/hello/Makefile.
+ But the build system gets to that logic through a rather tortuous path:
+
+ The top-level context make target is in nuttx/Makefile.
+ All build targets depend upon the context build target.
+ For the apps/ directory, this build target will execute the context target in the apps/Makefile.
+
+ The apps/Makefile will, in turn, execute the context targets in all of the configured sub-directories.
+ In our case will include the Makefile in apps/examples.
+
+ And finally, the apps/examples/Makefilewill execute the context target in all configured examplesub-directores, getting us finally to apps/examples/Makefile (which is covered below).
+ At the conclusion of the context phase, the apps/Makefile will touch a file called .context in the apps/ directory, preventing any further configurations during any subsequent context phase build attempts.
+
+ NOTE: + 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: +
++make distclean ++
+ But then you will have to re-configuration NuttX from scratch.
+ But if you only want to re-build the configuration in the apps/ 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 apps/ directory and will let you continue without re-configuring everything:
+
+make apps_distclean ++ +
+ Logic for the context target in apps/examples/hello/Makefile registers the hello_main() application in the namedapp's namedapp_proto.hand namedapp_list.h files.
+ That logic that does that in apps/examples/hello/Makefile is abstracted below:
+
+ First, the Makefile includes apps/Make.defs:
+
+include $(APPDIR)/Make.defs ++
+ This defines a macro called REGISTER that adds data to the namedapp header files:
+
+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
+
+
+ When this macro runs, you will see the output in the build "Register: hello", that is a sure sign that the registration was successful.
+
+ The make file then defines the application name (hello), the task priority (default), and the stack size that will be allocated in the task runs (2Kb).
+
+APPNAME = hello +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 ++ +
+ And finally, the Makefile invokes the REGISTER macro to added the hello_main() named application.
+ Then, when the system build completes, the hello command can be executed from the NSH command line.
+ When the hello command is executed, it will start the task with entry point hello_main() with the default priority and with a stack size of 2Kb.
+
+.context: +ifeq ($(CONFIG_EXAMPLES_HELLO_BUILTIN),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) + @touch $@ +endif ++
+ Other Uses of Named Application. + 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. +
+ +
+ Named Application Start-Up main() function.
+ 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:
+
+CONFIG_BUILTIN_APP_START=<application name> ++
+ that application will be invoked immediately after system starts instead of the normal, default user_start() entry point.
+ Note that <application name> must be provided just as it would have been on the NSH command line.
+ For example, hello would result in hello_main() being started at power-up.
+
+ 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 CONFIG_BUILTIN_APP_START in this way will bypass NSH and execute your application just as if it were entered from the NSH command line.
+
binfs.
+ binfs is a tiny file system located at apps/namedapp/binfs.c.
+ This provides an alternative what of visualizing installed named applications.
+ Without binfs, you can see the installed named applications using the NSH help command.
+ binfs will create a tiny pseudo-file system mounted at /bin.
+ Using binfs, you can see the available named applications by listing the contents of /bin directory.
+ This gives some superficial Unix compatibility, but does not really add any new functionality.
+
+ 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: +
++CONFIG_SCHED_WAITPID=y ++
+ This configuration option enables support for the standard waitpid() RTOS interface.
+ When that interface is enabled, NSH will use it to wait, sleeping until the built-in application executes to completion.
+
+ Of course, even with CONFIG_SCHED_WAITPID=y defined, specific applications can still be forced to run asynchronously by adding the ampersand (&) after the NSH command.
+
+ The appconfig File.
+ 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 configs/<board>/<configuration>/appconfig.
+ The existence of the appconfig file in the board configuration directory is sufficient to enable building of applications.
+
+ The appconfig file is copied into the apps/ directory as .config when NuttX is configured.
+ .config is included by the top-level apps/Makefile.
+ As a minimum, this configuration file must define files to add to the CONFIGURED_APPS list like:
+
+CONFIGURED_APPS += examples/hello ++ +
+ Changes in the Works.
+ There are changes in the works that will obsolete the appconfig file.
+ These changes will implement an automated configuration system for NuttX.
+ One consequence of this new configuration system is that the appconfig 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: http://tech.groups.yahoo.com/group/nuttx/message/1604.
+
+ 4.4 Customizing NSH Initialization+ |
+
+ Ways to Customize NSH Initialization. + There are three ways to customize the NSH start-up behavior. + Here they are presented in order of increasing difficulty: +
+ +
+ You can extend the initialization logic in configs/stm3240g-eval/src/up_nsh.c.
+ The logic there is called each time that NSH is started and is good place in particular for any device-related initialization.
+
+ You replace the sample code at apps/examples/nsh/nsh_main.c with whatever start-up logic that you want.
+ NSH is a library at apps/nshlib.
+ apps.examplex/nsh is just a tiny, example start-up function (user_start()) 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 user_start() function and then start other tasks from your custom user_start().
+
+ 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 +
++ First of all you should look at NSH Start-Up Script paragraph. + Most everything you need to know can be found there. + That information will be repeated and extended here for completeness. +
+ +
+ NSH Start-Up Script.
+ 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 CONFIG_NSH_ROMFSETC=y, but has several other related configuration options as described with the NSH-specific configuration settings paragraph.
+ This capability also depends on:
+
+ CONFIG_DISABLE_MOUNTPOINT=n.
+ If mount point support is disabled, then you cannot mount any file systems.
+
+ CONFIG_NFILE_DESCRIPTORS > 4.
+ Of course you have to have file descriptions to use any thing in the file system.
+
+ CONFIG_FS_ROMFS enabled.
+ This option enables ROMFS file system support.
+
+ Default Start-Up Behavior. + 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. +
+
+ In this default case, enabling CONFIG_NSH_ROMFSETC will cause NSH to behave as follows at NSH start-up time:
+
+ NSH will create a read-only RAM disk (a ROM disk), containing a tiny ROMFS filesystem containing the following: +
++`--init.d/ + `-- rcS +
+ Where rcS is the NSH start-up script.
+
+ NSH will then mount the ROMFS filesystem at /etc, resulting in:
+
+|--dev/ +| `-- ram0 +`--etc/ + `--init.d/ + `-- rcS+ +
+ By default, the contents of rcS script are:
+
+# Create a RAMDISK and mount it at /tmp + +mkrd -m 1 -s 512 1024 +mkfatfs /dev/ram1 +mount -t vfat /dev/ram1 /tmp ++
+ NSH will execute the script at /etc/init.d/rcS at start-up (before the first NSH prompt).
+ After execution of the script, the root FS will look like:
+
+|--dev/ +| |-- ram0 +| `-- ram1 +|--etc/ +| `--init.d/ +| `-- rcS +`--tmp/ ++ + +
+ Example Configurations.
+ Here are some configurations that have CONFIG_NSH_ROMFSETC=y in the NuttX configuration file.
+ They might provide useful examples:
+
configs/hymini-stm32v/nsh2
+ configs/ntosd-dm320/nsh
+ configs/sim/nsh
+ configs/sim/nsh2
+ configs/sim/nx
+ configs/sim/nx11
+ configs/sim/touchscreen
+ configs/vsn/nsh
+
+ In most of these cases, the configuration sets up the default /etc/init.d/rcS script.
+ The default script is here: apps/nshlib/rcS.template.
+ (The funny values in the template like XXXMKRDMINORXXX get replaced via sed at build time).
+ This default configuration creates a ramdisk and mounts it at /tmp as discussed above.
+
+ If that default behavior is not what you want, then you can provide your own custom rcS script by defining CONFIG_NSH_ARCHROMFS=y in the configuration file.
+ The only example that uses a custom /etc/init.d/rcS file in the NuttX source tree is this one: configs/vsn/nsh.
+ The configs/vsn/nsh/defconfig file also has this definition:
+
CONFIG_NSH_ARCHROMFS=y -- Support an architecture specific ROMFS file.
+ Modifying the ROMFS Image.
+ The contents of the /etc directory are retained in the file apps/nshlib/nsh_romfsimg.h OR, if CONFIG_NSH_ARCHROMFS is defined, include/arch/board/rcs.template.
+ In order to modify the start-up behavior, there are three things to study:
+
+ Configuration Options.
+ The additional CONFIG_NSH_ROMFSETC configuration options discussed with the other NSH-specific configuration settings.
+
+ tools/mkromfsimg.sh Script.
+ The script tools/mkromfsimg.sh creates nsh_romfsimg.h.
+ It is not automatically executed.
+ If you want to change the configuration settings associated with creating and mounting the /tmp directory, then it will be necessary to re-generate this header file using the tools/mkromfsimg.sh script.
+
+ The behavior of this script depends upon several things: +
++ The configuration settings then installed configuration. +
+
+ The genromfs tool(available from http://romfs.sourceforge.net) or included within the NuttX buildroot toolchain.
+ There is a snapshot here: misc/tools/genromfs-0.5.2.tar.gz.
+
+ The xxd 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 vi package).
+
+ The file apps/nshlib/rcS.template (OR, if CONFIG_NSH_ARCHROMFS is defined include/arch/board/rcs.template.
+
+ rcS.template.
+ The file apps/nshlib/rcS.template contains the general form of the rcS file; configured values are plugged into this template file to produce the final rcS file.
+
+ rcS.template.
+ The default rcS.template, apps/nshlib/rcS.template, generates the standard, default apps/nshlib/nsh_romfsimg.h file.
+
+ If CONFIG_NSH_ARCHROMFS is defined in the NuttX configuration file, then a custom, board-specific nsh_romfsimg.h file residing in configs/<board>/includewill be used.
+ NOTE when the OS is configured, include/arch/board will be linked to configs/<board>/include.
+
+ As mention above, the only example that uses a custom /etc/init.d/rcS file in the NuttX source tree is this one: configs/vsn/nsh.
+ The custom script for the configs/vsn case is located at configs/vsn/include/rcS.template.
+
+ All of the startup-behavior is contained in rcS.template.
+ The role of mkromfsimg.sh script is to (1) apply the specific configuration settings to rcS.template to create the final rcS, and (2) to generate the header file nsh_romfsimg.h containg the ROMFS file system image.
+ To do this, mkromfsimg.sh uses two tools that must be installed in your system:
+
+ The genromfs tool that is used to generate the ROMFS file system image.
+
+ The xxd tool that is used to create the C header file.
+
+ You can find the generated ROMFS file system for the configs/vsn case here: configs/vsn/include/rcS.template
+
-
System logging. +
-
-