mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-29 03:36:07 +08:00
+6
-2
@@ -1,12 +1,16 @@
|
|||||||
.built
|
.built
|
||||||
*.context
|
*.context
|
||||||
|
*.bdat
|
||||||
|
*.pdat
|
||||||
.depend
|
.depend
|
||||||
|
.updated
|
||||||
.config
|
.config
|
||||||
|
.config-e
|
||||||
.version
|
.version
|
||||||
.project
|
.project
|
||||||
.cproject
|
.cproject
|
||||||
apps/namedapp/namedapp_list.h
|
apps/builtin/builtin_list.h
|
||||||
apps/namedapp/namedapp_proto.h
|
apps/builtin/builtin_proto.h
|
||||||
Make.dep
|
Make.dep
|
||||||
*.pyc
|
*.pyc
|
||||||
*.o
|
*.o
|
||||||
|
|||||||
@@ -435,3 +435,53 @@
|
|||||||
logic to find the absolute path to the program using the PATH variable.
|
logic to find the absolute path to the program using the PATH variable.
|
||||||
|
|
||||||
6.25 2013-xx-xx Gregory Nutt <gnutt@nuttx.org>
|
6.25 2013-xx-xx Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
|
||||||
|
* Makefiles: Removed dependency of distclean on clean in most top-level
|
||||||
|
files. It makes sense for 'leaf' Makefiles to have this dependency,
|
||||||
|
but it does not make sense for upper-level Makefiles.
|
||||||
|
* apps/namedapp/: Renamed to builtins in preparation for another change.
|
||||||
|
* .context: Removed the .context kludge. This caused lots of problems
|
||||||
|
when changing configurations because there is no easy way to get the
|
||||||
|
system to rebuild the context. Now, the context will be rebuilt
|
||||||
|
whenever there is a change in either .config or the Makefile.
|
||||||
|
* apps/builtin/registry: Updated new built-in registration logic to handle
|
||||||
|
cases where (1) old apps/.config is used, and (2) applications ared
|
||||||
|
removed, not just added.
|
||||||
|
* apps/examples/nettest/Makefile: Fix an error that crept in during
|
||||||
|
some of the recent, massive build system changes.
|
||||||
|
* apps/builtin/Makefile: Need to have auto-generated header files
|
||||||
|
in place early in the dependency generation phase to avoid warnings.
|
||||||
|
It is not important if they are only stubbed out header files at
|
||||||
|
this build phase.
|
||||||
|
* apps/examples/hidbkd: Now supports decoding of encoded special keys
|
||||||
|
if CONFIG_EXAMPLES_HIDKBD_ENCODED is defined.
|
||||||
|
* apps/examples/hidbkd: Add support for decoding key release events
|
||||||
|
as well. However, the USB HID keyboard drier has not yet been
|
||||||
|
updated to detect key release events. That is kind of tricky in
|
||||||
|
the USB HID keyboard report data.
|
||||||
|
* apps/examples/wlan: Remove non-functional example.
|
||||||
|
* apps/examples/ostest/vfork.c: Added a test of vfork().
|
||||||
|
* apps/exampes/posix_spawn: Added a test of poxis_spawn().
|
||||||
|
* apps/examples/ostest: Extend signal handler test to catch
|
||||||
|
death-of-child signals (SIGCHLD).
|
||||||
|
* apps/examples/ostest/waitpid.c: Add a test for waitpid(), waitid(),
|
||||||
|
and wait().
|
||||||
|
* builtin/binfs.c: Add hooks for dup() method (not implemented).
|
||||||
|
* builtin/exec_builtin.c, nshlib/nsh_parse.c, and nshlib/nsh_builtin.c:
|
||||||
|
NSH now supports re-direction of I/O to files (but still not from).
|
||||||
|
* builtin/binfs.c: Greatly simplified (it is going to need to be
|
||||||
|
very lightweight). Now supports open, close, and a new ioctl to recover
|
||||||
|
the builtin filename. The latter will be needed to support a binfs
|
||||||
|
binfmt.
|
||||||
|
* builtin/binfs.c: Move apps/builtin/binfs.c to fs/binfs/fs_binfs.c
|
||||||
|
CONFIG_APPS_BINDIR rename CONFIG_FS_BINFS
|
||||||
|
* apps/include/builtin.h: Some of the content of
|
||||||
|
apps/include/apps.h moved to include/nuttx/binfmt/builtin.h.
|
||||||
|
apps/include/apps.h renamed builtin.h
|
||||||
|
* apps/builtin/exec_builtins.c: Move utility builtin
|
||||||
|
utility functions from apps/builtin/exec_builtins.c to
|
||||||
|
binfmt/libbuiltin/libbuiltin_utils.c
|
||||||
|
* apps/nshlib/nsh_mountcmds.c: The block driver/source
|
||||||
|
argument is now optional. Many files systems do not need
|
||||||
|
a source and it is really stupid to have to enter a bogus
|
||||||
|
source parameter.
|
||||||
|
|||||||
+2
-2
@@ -3,8 +3,8 @@
|
|||||||
# see misc/tools/kconfig-language.txt.
|
# see misc/tools/kconfig-language.txt.
|
||||||
#
|
#
|
||||||
|
|
||||||
menu "Named Applications"
|
menu "Built-In Applications"
|
||||||
source "$APPSDIR/namedapp/Kconfig"
|
source "$APPSDIR/builtin/Kconfig"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "Examples"
|
menu "Examples"
|
||||||
|
|||||||
+12
-3
@@ -34,8 +34,17 @@
|
|||||||
#
|
#
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
|
BUILTIN_REGISTRY = $(APPDIR)$(DELIM)builtin$(DELIM)registry
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_NUTTX_NEWCONFIG),y)
|
||||||
|
DEPCONFIG = $(TOPDIR)$(DELIM).config
|
||||||
|
else
|
||||||
|
DEPCONFIG = $(TOPDIR)$(DELIM).config $(APPDIR)$(DELIM).config
|
||||||
|
endif
|
||||||
|
|
||||||
define REGISTER
|
define REGISTER
|
||||||
@echo "Register: $1"
|
$(Q) echo "Register: $1"
|
||||||
@echo "{ \"$1\", $2, $3, $4 }," >> "$(APPDIR)/namedapp/namedapp_list.h"
|
$(Q) echo "{ \"$1\", $2, $3, $4 }," > "$(BUILTIN_REGISTRY)$(DELIM)$4.bdat"
|
||||||
@echo "EXTERN int $4(int argc, char *argv[]);" >> "$(APPDIR)/namedapp/namedapp_proto.h"
|
$(Q) echo "int $4(int argc, char *argv[]);" > "$(BUILTIN_REGISTRY)$(DELIM)$4.pdat"
|
||||||
|
$(Q) touch "$(BUILTIN_REGISTRY)$(DELIM).updated"
|
||||||
endef
|
endef
|
||||||
|
|||||||
+18
-25
@@ -45,14 +45,14 @@ APPDIR = ${shell pwd}
|
|||||||
# action. It is created by the configured appconfig file (a copy of which
|
# action. It is created by the configured appconfig file (a copy of which
|
||||||
# appears in this directory as .config)
|
# appears in this directory as .config)
|
||||||
# SUBDIRS is the list of all directories containing Makefiles. It is used
|
# SUBDIRS is the list of all directories containing Makefiles. It is used
|
||||||
# only for cleaning. namedapp must always be the first in the list. This
|
# only for cleaning. builtin must always be the first in the list. This
|
||||||
# list can be extended by the .config file as well.
|
# list can be extended by the .config file as well.
|
||||||
|
|
||||||
CONFIGURED_APPS =
|
CONFIGURED_APPS =
|
||||||
#SUBDIRS = examples graphics interpreters modbus namedapp nshlib netutils system
|
|
||||||
ALL_SUBDIRS = $(dir $(shell /usr/bin/find . -name Makefile))
|
|
||||||
SUBDIRS = namedapp/ $(filter-out ./ ./namedapp/ ./examples/,$(ALL_SUBDIRS))
|
|
||||||
|
|
||||||
|
SUBDIRS = examples interpreters builtin nshlib system
|
||||||
|
|
||||||
|
#SUBDIRS = examples graphics interpreters modbus builtin nshlib netutils system
|
||||||
|
|
||||||
# There are two different mechanisms for obtaining the list of configured
|
# There are two different mechanisms for obtaining the list of configured
|
||||||
# directories:
|
# directories:
|
||||||
@@ -73,20 +73,20 @@ SUBDIRS = namedapp/ $(filter-out ./ ./namedapp/ ./examples/,$(ALL_SUBDIRS))
|
|||||||
|
|
||||||
ifeq ($(CONFIG_NUTTX_NEWCONFIG),y)
|
ifeq ($(CONFIG_NUTTX_NEWCONFIG),y)
|
||||||
|
|
||||||
# namedapp/Make.defs must be included first
|
# builtin/Make.defs must be included first
|
||||||
|
|
||||||
-include namedapp/Make.defs
|
include builtin/Make.defs
|
||||||
-include examples/Make.defs
|
include examples/Make.defs
|
||||||
-include graphics/Make.defs
|
include graphics/Make.defs
|
||||||
-include interpreters/Make.defs
|
include interpreters/Make.defs
|
||||||
-include modbus/Make.defs
|
include modbus/Make.defs
|
||||||
-include netutils/Make.defs
|
include netutils/Make.defs
|
||||||
-include nshlib/Make.defs
|
include nshlib/Make.defs
|
||||||
-include system/Make.defs
|
include system/Make.defs
|
||||||
|
|
||||||
# INSTALLED_APPS is the list of currently available application directories. It
|
# INSTALLED_APPS is the list of currently available application directories. It
|
||||||
# is the same as CONFIGURED_APPS, but filtered to exclude any non-existent
|
# is the same as CONFIGURED_APPS, but filtered to exclude any non-existent
|
||||||
# application directory. namedapp is always in the list of applications to be
|
# application directory. builtin is always in the list of applications to be
|
||||||
# built.
|
# built.
|
||||||
|
|
||||||
INSTALLED_APPS =
|
INSTALLED_APPS =
|
||||||
@@ -98,10 +98,10 @@ else
|
|||||||
|
|
||||||
# INSTALLED_APPS is the list of currently available application directories. It
|
# INSTALLED_APPS is the list of currently available application directories. It
|
||||||
# is the same as CONFIGURED_APPS, but filtered to exclude any non-existent
|
# is the same as CONFIGURED_APPS, but filtered to exclude any non-existent
|
||||||
# application directory. namedapp is always in the list of applications to be
|
# application directory. builtin is always in the list of applications to be
|
||||||
# built.
|
# built.
|
||||||
|
|
||||||
INSTALLED_APPS = namedapp
|
INSTALLED_APPS = builtin
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Create the list of available applications (INSTALLED_APPS)
|
# Create the list of available applications (INSTALLED_APPS)
|
||||||
@@ -139,21 +139,16 @@ $(INSTALLED_APPS):
|
|||||||
|
|
||||||
$(BIN): $(INSTALLED_APPS)
|
$(BIN): $(INSTALLED_APPS)
|
||||||
|
|
||||||
.context:
|
context:
|
||||||
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||||
$(Q) for %%G in ($(INSTALLED_APPS)) do ( \
|
$(Q) for %%G in ($(INSTALLED_APPS)) do ( \
|
||||||
if exist %%G\.context del /f /q %%G\.context \
|
|
||||||
$(MAKE) -C %%G TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" context \
|
$(MAKE) -C %%G TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" context \
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
$(Q) for dir in $(INSTALLED_APPS) ; do \
|
$(Q) for dir in $(INSTALLED_APPS) ; do \
|
||||||
rm -f $$dir/.context ; \
|
|
||||||
$(MAKE) -C $$dir TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" context ; \
|
$(MAKE) -C $$dir TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" context ; \
|
||||||
done
|
done
|
||||||
endif
|
endif
|
||||||
$(Q) touch $@
|
|
||||||
|
|
||||||
context: .context
|
|
||||||
|
|
||||||
.depend: context Makefile $(SRCS)
|
.depend: context Makefile $(SRCS)
|
||||||
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||||
@@ -184,13 +179,12 @@ endif
|
|||||||
$(call DELFILE, $(BIN))
|
$(call DELFILE, $(BIN))
|
||||||
$(call CLEAN)
|
$(call CLEAN)
|
||||||
|
|
||||||
distclean: # clean
|
distclean:
|
||||||
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||||
$(Q) for %%G in ($(SUBDIRS)) do ( \
|
$(Q) for %%G in ($(SUBDIRS)) do ( \
|
||||||
$(MAKE) -C %%G distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" \
|
$(MAKE) -C %%G distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" \
|
||||||
)
|
)
|
||||||
$(call DELFILE, .config)
|
$(call DELFILE, .config)
|
||||||
$(call DELFILE, .context)
|
|
||||||
$(call DELFILE, .depend)
|
$(call DELFILE, .depend)
|
||||||
$(Q) ( if exist external ( \
|
$(Q) ( if exist external ( \
|
||||||
echo ********************************************************" \
|
echo ********************************************************" \
|
||||||
@@ -202,7 +196,6 @@ else
|
|||||||
$(MAKE) -C $$dir distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"; \
|
$(MAKE) -C $$dir distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"; \
|
||||||
done
|
done
|
||||||
$(call DELFILE, .config)
|
$(call DELFILE, .config)
|
||||||
$(call DELFILE, .context)
|
|
||||||
$(call DELFILE, .depend)
|
$(call DELFILE, .depend)
|
||||||
$(Q) ( if [ -e external ]; then \
|
$(Q) ( if [ -e external ]; then \
|
||||||
echo "********************************************************"; \
|
echo "********************************************************"; \
|
||||||
|
|||||||
+104
-42
@@ -6,26 +6,25 @@ Contents
|
|||||||
|
|
||||||
General
|
General
|
||||||
Directory Location
|
Directory Location
|
||||||
Named Applications
|
Built-In Applications
|
||||||
Named Startup main() function
|
|
||||||
NuttShell (NSH) Built-In Commands
|
NuttShell (NSH) Built-In Commands
|
||||||
Synchronous Built-In Commands
|
Synchronous Built-In Commands
|
||||||
Application Configuration File
|
Application Configuration File
|
||||||
Example Named Application
|
Example Built-In Application
|
||||||
Building NuttX with Board-Specific Pieces Outside the Source Tree
|
Building NuttX with Board-Specific Pieces Outside the Source Tree
|
||||||
|
|
||||||
General
|
General
|
||||||
-------
|
-------
|
||||||
This folder provides various applications found in sub-directories. These
|
This folder provides various applications found in sub-directories. These
|
||||||
applications are not inherently a part of NuttX but are provided you help
|
applications are not inherently a part of NuttX but are provided to help
|
||||||
you develop your own applications. The apps/ directory is a "break away"
|
you develop your own applications. The apps/ directory is a "break away"
|
||||||
part of the configuration that you may chose to use or not.
|
part of the configuration that you may choose to use or not.
|
||||||
|
|
||||||
Directory Location
|
Directory Location
|
||||||
------------------
|
------------------
|
||||||
The default application directory used by the NuttX build should be named
|
The default application directory used by the NuttX build should be named
|
||||||
apps/ (or apps-x.y/ where x.y is the NuttX version number). This apps/
|
apps/ (or apps-x.y/ where x.y is the NuttX version number). This apps/
|
||||||
directoy should appear in the directory tree at the same level as the
|
directory should appear in the directory tree at the same level as the
|
||||||
NuttX directory. Like:
|
NuttX directory. Like:
|
||||||
|
|
||||||
.
|
.
|
||||||
@@ -47,14 +46,14 @@ ways to do that:
|
|||||||
path to the application directory on the configuration command line
|
path to the application directory on the configuration command line
|
||||||
like: ./configure.sh -a <app-dir> <board-name>/<config-name>
|
like: ./configure.sh -a <app-dir> <board-name>/<config-name>
|
||||||
|
|
||||||
Named Applications
|
Built-In Applications
|
||||||
------------------
|
---------------------
|
||||||
NuttX also supports applications that can be started using a name string.
|
NuttX also supports applications that can be started using a name string.
|
||||||
In this case, application entry points with their requirements are gathered
|
In this case, application entry points with their requirements are gathered
|
||||||
together in two files:
|
together in two files:
|
||||||
|
|
||||||
- namedapp/namedapp_proto.h Entry points, prototype function
|
- builtin/builtin_proto.h Entry points, prototype function
|
||||||
- namedapp/namedapp_list.h Application specific information and requirements
|
- builtin/builtin_list.h Application specific information and requirements
|
||||||
|
|
||||||
The build occurs in several phases as different build targets are executed:
|
The build occurs in several phases as different build targets are executed:
|
||||||
(1) context, (2) depend, and (3) default (all). Application information is
|
(1) context, (2) depend, and (3) default (all). Application information is
|
||||||
@@ -62,18 +61,18 @@ collected during the make context build phase.
|
|||||||
|
|
||||||
To execute an application function:
|
To execute an application function:
|
||||||
|
|
||||||
exec_namedapp() is defined in the nuttx/include/apps/apps.h
|
exec_builtin() is defined in the nuttx/include/apps/builtin.h
|
||||||
|
|
||||||
NuttShell (NSH) Built-In Commands
|
NuttShell (NSH) Built-In Commands
|
||||||
---------------------------------
|
---------------------------------
|
||||||
One use of named applications is to provide a way of invoking your custom
|
One use of builtin applications is to provide a way of invoking your custom
|
||||||
application through the NuttShell (NSH) command line. NSH will support
|
application through the NuttShell (NSH) command line. NSH will support
|
||||||
a seamless method invoking the applications, when the following option is
|
a seamless method invoking the applications, when the following option is
|
||||||
enabled in the NuttX configuration file:
|
enabled in the NuttX configuration file:
|
||||||
|
|
||||||
CONFIG_NSH_BUILTIN_APPS=y
|
CONFIG_NSH_BUILTIN_APPS=y
|
||||||
|
|
||||||
Applications registered in the apps/namedapp/namedapp_list.h file will then
|
Applications registered in the apps/builtin/builtin_list.h file will then
|
||||||
be accessible from the NSH command line. If you type 'help' at the NSH
|
be accessible from the NSH command line. If you type 'help' at the NSH
|
||||||
prompt, you will see a list of the registered commands.
|
prompt, you will see a list of the registered commands.
|
||||||
|
|
||||||
@@ -96,11 +95,11 @@ after the NSH command.
|
|||||||
|
|
||||||
Application Configuration File
|
Application Configuration File
|
||||||
------------------------------
|
------------------------------
|
||||||
A special configuration file is used to configure which applications
|
The old-style NuttX configuration uses a special configuration file is
|
||||||
are to be included in the build. The source for this file is
|
used to configure which applications are to be included in the build.
|
||||||
configs/<board>/<configuration>/appconfig. The existence of the appconfig
|
The source for this file is configs/<board>/<configuration>/appconfig.
|
||||||
file in the board configuration directory is sufficient to enable building
|
The existence of the appconfig file in the board configuration directory\
|
||||||
of applications.
|
is sufficient to enable building of applications.
|
||||||
|
|
||||||
The appconfig file is copied into the apps/ directory as .config when
|
The appconfig file is copied into the apps/ directory as .config when
|
||||||
NuttX is configured. .config is included in the toplevel apps/Makefile.
|
NuttX is configured. .config is included in the toplevel apps/Makefile.
|
||||||
@@ -109,38 +108,101 @@ CONFIGURED_APPS list like:
|
|||||||
|
|
||||||
CONFIGURED_APPS += examples/hello system/poweroff
|
CONFIGURED_APPS += examples/hello system/poweroff
|
||||||
|
|
||||||
Named Start-Up main() function
|
The new NuttX configuration uses kconfig-frontends tools and only the
|
||||||
------------------------------
|
NuttX .config file. The new configuration is indicated by the existence
|
||||||
A named application can even be used as the main, start-up entry point
|
of the definition CONFIG_NUTTX_NEWCONFIG=y in the NuttX .config file.
|
||||||
into your embedded software. When the user defines this option in
|
If CONFIG_NUTTX_NEWCONFIG is defined, then the Makefile will:
|
||||||
the NuttX configuration file:
|
|
||||||
|
|
||||||
CONFIG_BUILTIN_APP_START=<application name>
|
- Assume that there is no apps/.config file and will instead
|
||||||
|
- Include Make.defs files from each of the subdirectories.
|
||||||
that application shall be invoked immediately after system starts
|
|
||||||
*instead* of the default "user_start" entry point.
|
|
||||||
Note that <application name> must be provided as: "hello",
|
|
||||||
will call:
|
|
||||||
|
|
||||||
int hello_main(int argc, char *argv[])
|
When an application is enabled using the kconfig-frontends tool, then
|
||||||
|
a new definition is added to the NuttX .config file. For example, if
|
||||||
|
you want to enable apps/examples/hello then the old apps/.config would
|
||||||
|
have had:
|
||||||
|
|
||||||
Example Named Application
|
CONFIGURED_APPS += examples/hello
|
||||||
-------------------------
|
|
||||||
|
But in the new configuration there will be no apps/.config file and,
|
||||||
|
instead, the NuttX .config will have:
|
||||||
|
|
||||||
|
CONFIG_EXAMPLES_HELLO=y
|
||||||
|
|
||||||
|
This will select the apps/examples/hello in the following way:
|
||||||
|
|
||||||
|
- The top-level make will include examples/Make.defs
|
||||||
|
- examples/Make.defs will set CONFIGURED_APPS += examples/hello
|
||||||
|
like this:
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_EXAMPLES_HELLO),y)
|
||||||
|
CONFIGURED_APPS += examples/hello
|
||||||
|
endif
|
||||||
|
|
||||||
|
Thus accomplishing the same thing with no apps/.config file.
|
||||||
|
|
||||||
|
Example Built-In Application
|
||||||
|
----------------------------
|
||||||
An example application skeleton can be found under the examples/hello
|
An example application skeleton can be found under the examples/hello
|
||||||
sub-directory. This example shows how a named application can be added
|
sub-directory. This example shows how a builtin application can be added
|
||||||
to the project. One must define:
|
to the project. One must define:
|
||||||
|
|
||||||
1. create sub-directory as: appname
|
Old configuration method:
|
||||||
2. provide entry point: appname_main()
|
|
||||||
3. set the requirements in the file: Makefile, specially the lines:
|
|
||||||
|
|
||||||
APPNAME = appname
|
1. Create sub-directory as: appname
|
||||||
PRIORITY = SCHED_PRIORITY_DEFAULT
|
|
||||||
STACKSIZE = 768
|
|
||||||
ASRCS = asm source file list as a.asm b.asm ...
|
|
||||||
CSRCS = C source file list as foo1.c foo2.c ..
|
|
||||||
|
|
||||||
4. add application in the apps/.config
|
2. In this directory there should be:
|
||||||
|
|
||||||
|
- A Makefile, and
|
||||||
|
- The application source code.
|
||||||
|
|
||||||
|
3. The application source code should provide the entry point:
|
||||||
|
appname_main()
|
||||||
|
|
||||||
|
4. Set the requirements in the file: Makefile, specially the lines:
|
||||||
|
|
||||||
|
APPNAME = appname
|
||||||
|
PRIORITY = SCHED_PRIORITY_DEFAULT
|
||||||
|
STACKSIZE = 768
|
||||||
|
ASRCS = asm source file list as a.asm b.asm ...
|
||||||
|
CSRCS = C source file list as foo1.c foo2.c ..
|
||||||
|
|
||||||
|
Look at some of the other Makefiles for examples. Note the
|
||||||
|
special registration logic needed for the context: target
|
||||||
|
|
||||||
|
5. Add the to the application to the CONFIGIURED_APPS in the
|
||||||
|
apps/.config file:
|
||||||
|
|
||||||
|
CONFIGURED_APPS += appname
|
||||||
|
|
||||||
|
New Configuration Method:
|
||||||
|
|
||||||
|
1. Create sub-directory as: appname
|
||||||
|
|
||||||
|
2. In this directory there should be:
|
||||||
|
|
||||||
|
- A Make.defs file that would be included by the apps/Makefile
|
||||||
|
- A Kconfig file that would be used by the configuration tool (see
|
||||||
|
misc/tools/kconfig-language.txt). This Kconfig file should be
|
||||||
|
included by the apps/Kconfig file
|
||||||
|
- A Makefile, and
|
||||||
|
- The application source code.
|
||||||
|
|
||||||
|
3. The application source code should provide the entry point:
|
||||||
|
appname_main()
|
||||||
|
|
||||||
|
4. Set the requirements in the file: Makefile, specially the lines:
|
||||||
|
|
||||||
|
APPNAME = appname
|
||||||
|
PRIORITY = SCHED_PRIORITY_DEFAULT
|
||||||
|
STACKSIZE = 768
|
||||||
|
ASRCS = asm source file list as a.asm b.asm ...
|
||||||
|
CSRCS = C source file list as foo1.c foo2.c ..
|
||||||
|
|
||||||
|
4b. The Make.defs file should include a line like:
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_APPNAME),y)
|
||||||
|
CONFIGURED_APPS += appname
|
||||||
|
endif
|
||||||
|
|
||||||
Building NuttX with Board-Specific Pieces Outside the Source Tree
|
Building NuttX with Board-Specific Pieces Outside the Source Tree
|
||||||
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#
|
||||||
|
# For a description of the syntax of this configuration file,
|
||||||
|
# see misc/tools/kconfig-language.txt.
|
||||||
|
#
|
||||||
|
|
||||||
|
if BUILTIN
|
||||||
|
|
||||||
|
config BUILTIN_PROXY_STACKSIZE
|
||||||
|
int "Builtin Proxy Stack Size"
|
||||||
|
default 1024
|
||||||
|
---help---
|
||||||
|
If exec_builtin uses I/O redirection options, then it will require
|
||||||
|
an intermediary/proxy task to muck with the file descriptors. This
|
||||||
|
configuration item specifies the stack size used for the proxy. Default:
|
||||||
|
1024 bytes.
|
||||||
|
|
||||||
|
endif
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
############################################################################
|
############################################################################
|
||||||
# apps/namedapps/Make.defs
|
# apps/builtin/Make.defs
|
||||||
# Adds selected applications to apps/ build
|
# Adds selected applications to apps/ build
|
||||||
#
|
#
|
||||||
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
#
|
#
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
ifeq ($(CONFIG_NAMEDAPP),y)
|
ifeq ($(CONFIG_BUILTIN),y)
|
||||||
CONFIGURED_APPS += namedapp
|
CONFIGURED_APPS += builtin
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
############################################################################
|
############################################################################
|
||||||
# apps/nshlib/Makefile
|
# apps/builtin/Makefile
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
@@ -33,20 +33,13 @@
|
|||||||
#
|
#
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
-include $(TOPDIR)/.config
|
|
||||||
-include $(TOPDIR)/Make.defs
|
-include $(TOPDIR)/Make.defs
|
||||||
include $(APPDIR)/Make.defs
|
include $(APPDIR)/Make.defs
|
||||||
|
|
||||||
# NSH Library
|
|
||||||
|
|
||||||
# Source and object files
|
# Source and object files
|
||||||
|
|
||||||
ASRCS =
|
ASRCS =
|
||||||
CSRCS = namedapp.c exec_namedapp.c
|
CSRCS = builtin.c exec_builtin.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_APPS_BINDIR),y)
|
|
||||||
CSRCS += binfs.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||||
@@ -70,7 +63,7 @@ VPATH =
|
|||||||
# Build Targets
|
# Build Targets
|
||||||
|
|
||||||
all: .built
|
all: .built
|
||||||
.PHONY: .context context depend clean distclean
|
.PHONY: context depend clean distclean
|
||||||
|
|
||||||
$(AOBJS): %$(OBJEXT): %.S
|
$(AOBJS): %$(OBJEXT): %.S
|
||||||
$(call ASSEMBLE, $<, $@)
|
$(call ASSEMBLE, $<, $@)
|
||||||
@@ -78,33 +71,60 @@ $(AOBJS): %$(OBJEXT): %.S
|
|||||||
$(COBJS): %$(OBJEXT): %.c
|
$(COBJS): %$(OBJEXT): %.c
|
||||||
$(call COMPILE, $<, $@)
|
$(call COMPILE, $<, $@)
|
||||||
|
|
||||||
.built: $(OBJS)
|
registry$(DELIM).updated:
|
||||||
|
$(V) $(MAKE) -C registry .updated TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
|
||||||
|
|
||||||
|
builtin_list.h: registry$(DELIM).updated
|
||||||
|
$(call DELFILE, builtin_list.h)
|
||||||
|
$(Q) touch builtin_list.h
|
||||||
|
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||||
|
$(Q) for /f %%G in ('dir /b registry\*.bdat`) do ( type registry\%%G >> builtin_list.h )
|
||||||
|
else
|
||||||
|
$(Q) ( \
|
||||||
|
filelist=`ls registry/*.bdat 2>/dev/null || echo ""`; \
|
||||||
|
for file in $$filelist; \
|
||||||
|
do cat $$file >> builtin_list.h; \
|
||||||
|
done; \
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
|
||||||
|
builtin_proto.h: registry$(DELIM).updated
|
||||||
|
$(call DELFILE, builtin_proto.h)
|
||||||
|
$(Q) touch builtin_proto.h
|
||||||
|
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||||
|
$(Q) for /f %%G in ('dir /b registry\*.pdat`) do ( type registry\%%G >> builtin_proto.h )
|
||||||
|
else
|
||||||
|
$(Q) ( \
|
||||||
|
filelist=`ls registry/*.pdat 2>/dev/null || echo ""`; \
|
||||||
|
for file in $$filelist; \
|
||||||
|
do cat $$file >> builtin_proto.h; \
|
||||||
|
done; \
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
|
||||||
|
.built: builtin_list.h builtin_proto.h $(OBJS)
|
||||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
$(Q) touch .built
|
$(Q) touch .built
|
||||||
|
|
||||||
.context:
|
context:
|
||||||
@echo "/* List of application requirements, generated during make context. */" > namedapp_list.h
|
$(Q) $(MAKE) -C registry context TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
|
||||||
@echo "/* List of application entry points, generated during make context. */" > namedapp_proto.h
|
|
||||||
$(Q) touch $@
|
|
||||||
|
|
||||||
context: .context
|
.depend: Makefile $(SRCS) builtin_list.h builtin_proto.h
|
||||||
|
|
||||||
.depend: Makefile $(SRCS)
|
|
||||||
$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||||
$(Q) touch $@
|
$(Q) touch $@
|
||||||
|
|
||||||
depend: .depend
|
depend: .depend
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
$(Q) $(MAKE) -C registry clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
|
||||||
$(call DELFILE, .built)
|
$(call DELFILE, .built)
|
||||||
$(call CLEAN)
|
$(call CLEAN)
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
$(call DELFILE, .context)
|
$(Q) $(MAKE) -C registry distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
|
||||||
$(call DELFILE, Make.dep)
|
$(call DELFILE, Make.dep)
|
||||||
$(call DELFILE, .depend)
|
$(call DELFILE, .depend)
|
||||||
$(call DELFILE, namedapp_list.h)
|
$(call DELFILE, builtin_list.h)
|
||||||
$(call DELFILE, namedapp_proto.h)
|
$(call DELFILE, builtin_proto.h)
|
||||||
|
|
||||||
-include Make.dep
|
-include Make.dep
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* apps/namedaps/namedapp.c
|
* apps/builtin/builtin.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||||
@@ -40,7 +40,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
#include <apps/apps.h>
|
|
||||||
|
#include <nuttx/binfmt/builtin.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
@@ -62,11 +63,11 @@ extern "C" {
|
|||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "namedapp_proto.h"
|
#include "builtin_proto.h"
|
||||||
|
|
||||||
const struct namedapp_s namedapps[] =
|
const struct builtin_s g_builtins[] =
|
||||||
{
|
{
|
||||||
# include "namedapp_list.h"
|
# include "builtin_list.h"
|
||||||
{ NULL, 0, 0, 0 }
|
{ NULL, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -88,9 +89,9 @@ const struct namedapp_s namedapps[] =
|
|||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int number_namedapps(void)
|
int number_builtins(void)
|
||||||
{
|
{
|
||||||
return sizeof(namedapps)/sizeof(struct namedapp_s) - 1;
|
return sizeof(g_builtins)/sizeof(struct builtin_s) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,423 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* apps/builtin/exec_builtin.c
|
||||||
|
*
|
||||||
|
* Originally by:
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||||
|
* Author: Uros Platise <uros.platise@isotel.eu>
|
||||||
|
*
|
||||||
|
* With subsequent updates, modifications, and general maintenance by:
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sched.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/binfmt/builtin.h>
|
||||||
|
#include <apps/builtin.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CONFIG_BUILTIN_PROXY_STACKSIZE
|
||||||
|
# define CONFIG_BUILTIN_PROXY_STACKSIZE 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct builtin_parms_s
|
||||||
|
{
|
||||||
|
/* Input values */
|
||||||
|
|
||||||
|
FAR const char *redirfile;
|
||||||
|
FAR const char **argv;
|
||||||
|
int oflags;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
/* Returned values */
|
||||||
|
|
||||||
|
pid_t result;
|
||||||
|
int errcode;
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static sem_t g_builtin_parmsem = SEM_INITIALIZER(1);
|
||||||
|
static sem_t g_builtin_execsem = SEM_INITIALIZER(0);
|
||||||
|
static struct builtin_parms_s g_builtin_parms;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bultin_semtake and builtin_semgive
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Give and take semaphores
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
*
|
||||||
|
* sem - The semaphore to act on.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void bultin_semtake(FAR sem_t *sem)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ret = sem_wait(sem);
|
||||||
|
ASSERT(ret == 0 || errno == EINTR);
|
||||||
|
}
|
||||||
|
while (ret != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define builtin_semgive(sem) sem_post(sem)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: builtin_taskcreate
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Execute the builtin task
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* On success, the task ID of the builtin task is returned; On failure, -1
|
||||||
|
* (ERROR) is returned and the errno is set appropriately.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int builtin_taskcreate(int index, FAR const char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Disable pre-emption. This means that although we start the builtin
|
||||||
|
* application here, it will not actually run until pre-emption is
|
||||||
|
* re-enabled below.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sched_lock();
|
||||||
|
|
||||||
|
/* Start the builtin application task */
|
||||||
|
|
||||||
|
ret = TASK_CREATE(g_builtins[index].name, g_builtins[index].priority,
|
||||||
|
g_builtins[index].stacksize, g_builtins[index].main,
|
||||||
|
(argv) ? &argv[1] : (FAR const char **)NULL);
|
||||||
|
|
||||||
|
/* If robin robin scheduling is enabled, then set the scheduling policy
|
||||||
|
* of the new task to SCHED_RR before it has a chance to run.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if CONFIG_RR_INTERVAL > 0
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
struct sched_param param;
|
||||||
|
|
||||||
|
/* Pre-emption is disabled so the task creation and the
|
||||||
|
* following operation will be atomic. The priority of the
|
||||||
|
* new task cannot yet have changed from its initial value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
param.sched_priority = g_builtins[index].priority;
|
||||||
|
(void)sched_setscheduler(ret, SCHED_RR, ¶m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Now let the builtin application run */
|
||||||
|
|
||||||
|
sched_unlock();
|
||||||
|
|
||||||
|
/* Return the task ID of the new task if the task was sucessfully
|
||||||
|
* started. Otherwise, ret will be ERROR (and the errno value will
|
||||||
|
* be set appropriately).
|
||||||
|
*/
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: builtin_proxy
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Perform output redirection, then execute the builtin task.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* Standard task start-up parameters
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Standard task return value.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int builtin_proxy(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int ret = ERROR;
|
||||||
|
|
||||||
|
/* Open the output file for redirection */
|
||||||
|
|
||||||
|
svdbg("Open'ing redirfile=%s oflags=%04x mode=0644\n",
|
||||||
|
g_builtin_parms.redirfile, g_builtin_parms.oflags);
|
||||||
|
|
||||||
|
fd = open(g_builtin_parms.redirfile, g_builtin_parms.oflags, 0644);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
/* Remember the errno value. ret is already set to ERROR */
|
||||||
|
|
||||||
|
g_builtin_parms.errcode = errno;
|
||||||
|
sdbg("ERROR: open of %s failed: %d\n",
|
||||||
|
g_builtin_parms.redirfile, g_builtin_parms.errcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Does the return file descriptor happen to match the required file
|
||||||
|
* desciptor number?
|
||||||
|
*/
|
||||||
|
|
||||||
|
else if (fd != 1)
|
||||||
|
{
|
||||||
|
/* No.. dup2 to get the correct file number */
|
||||||
|
|
||||||
|
svdbg("Dup'ing %d->1\n", fd);
|
||||||
|
|
||||||
|
ret = dup2(fd, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
g_builtin_parms.errcode = errno;
|
||||||
|
sdbg("ERROR: dup2 failed: %d\n", g_builtin_parms.errcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
svdbg("Closing fd=%d\n", fd);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Was the setup successful? */
|
||||||
|
|
||||||
|
if (ret == OK)
|
||||||
|
{
|
||||||
|
/* Yes.. Start the task. On success, the task ID of the builtin task
|
||||||
|
* is returned; On failure, -1 (ERROR) is returned and the errno
|
||||||
|
* is set appropriately.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = builtin_taskcreate(g_builtin_parms.index, g_builtin_parms.argv);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
g_builtin_parms.errcode = errno;
|
||||||
|
sdbg("ERROR: builtin_taskcreate failed: %d\n",
|
||||||
|
g_builtin_parms.errcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Post the semaphore to inform the parent task that we have completed
|
||||||
|
* what we need to do.
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_builtin_parms.result = ret;
|
||||||
|
builtin_semgive(&g_builtin_execsem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: builtin_startproxy
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Perform output redirection, then execute the builtin task.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* Standard task start-up parameters
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* On success, the task ID of the builtin task is returned; On failure, -1
|
||||||
|
* (ERROR) is returned and the errno is set appropriately.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline int builtin_startproxy(int index, FAR const char **argv,
|
||||||
|
FAR const char *redirfile, int oflags)
|
||||||
|
{
|
||||||
|
struct sched_param param;
|
||||||
|
pid_t proxy;
|
||||||
|
int errcode;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
// DEBUGASSERT(path);
|
||||||
|
|
||||||
|
svdbg("index=%d argv=%p redirfile=%s oflags=%04x\n",
|
||||||
|
index, argv, redirfile, oflags);
|
||||||
|
|
||||||
|
/* We will have to go through an intermediary/proxy task in order to
|
||||||
|
* perform the I/O redirection. This would be a natural place to fork().
|
||||||
|
* However, true fork() behavior requires an MMU and most implementations
|
||||||
|
* of vfork() are not capable of these operations.
|
||||||
|
*
|
||||||
|
* Even without fork(), we can still do the job, but parameter passing is
|
||||||
|
* messier. Unfortunately, there is no (clean) way to pass binary values
|
||||||
|
* as a task parameter, so we will use a semaphore-protected global
|
||||||
|
* structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Get exclusive access to the global parameter structure */
|
||||||
|
|
||||||
|
bultin_semtake(&g_builtin_parmsem);
|
||||||
|
|
||||||
|
/* Populate the parameter structure */
|
||||||
|
|
||||||
|
g_builtin_parms.redirfile = redirfile;
|
||||||
|
g_builtin_parms.argv = argv;
|
||||||
|
g_builtin_parms.result = ERROR;
|
||||||
|
g_builtin_parms.oflags = oflags;
|
||||||
|
g_builtin_parms.index = index;
|
||||||
|
|
||||||
|
/* Get the priority of this (parent) task */
|
||||||
|
|
||||||
|
ret = sched_getparam(0, ¶m);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
errcode = errno;
|
||||||
|
sdbg("ERROR: sched_getparam failed: %d\n", errcode);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start the intermediary/proxy task at the same priority as the parent task. */
|
||||||
|
|
||||||
|
proxy = TASK_CREATE("builtin_proxy", param.sched_priority,
|
||||||
|
CONFIG_BUILTIN_PROXY_STACKSIZE, (main_t)builtin_proxy,
|
||||||
|
(FAR const char **)NULL);
|
||||||
|
if (proxy < 0)
|
||||||
|
{
|
||||||
|
errcode = errno;
|
||||||
|
sdbg("ERROR: Failed to start builtin_proxy: %d\n", errcode);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the proxy to complete its job. We could use waitpid()
|
||||||
|
* for this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bultin_semtake(&g_builtin_execsem);
|
||||||
|
|
||||||
|
/* Get the result and relinquish our access to the parameter structure */
|
||||||
|
|
||||||
|
set_errno(g_builtin_parms.errcode);
|
||||||
|
builtin_semgive(&g_builtin_parmsem);
|
||||||
|
return g_builtin_parms.result;
|
||||||
|
|
||||||
|
errout:
|
||||||
|
set_errno(errcode);
|
||||||
|
builtin_semgive(&g_builtin_parmsem);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: exec_builtin
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Executes builtin applications registered during 'make context' time.
|
||||||
|
* New application is run in a separate task context (and thread).
|
||||||
|
*
|
||||||
|
* Input Parameter:
|
||||||
|
* filename - Name of the linked-in binary to be started.
|
||||||
|
* argv - Argument list
|
||||||
|
* redirfile - If output if redirected, this parameter will be non-NULL
|
||||||
|
* and will provide the full path to the file.
|
||||||
|
* oflags - If output is redirected, this parameter will provide the
|
||||||
|
* open flags to use. This will support file replacement
|
||||||
|
* of appending to an existing file.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* This is an end-user function, so it follows the normal convention:
|
||||||
|
* Returns the PID of the exec'ed module. On failure, it.returns
|
||||||
|
* -1 (ERROR) and sets errno appropriately.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int exec_builtin(FAR const char *appname, FAR const char **argv,
|
||||||
|
FAR const char *redirfile, int oflags)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
int ret = ERROR;
|
||||||
|
|
||||||
|
/* Verify that an application with this name exists */
|
||||||
|
|
||||||
|
index = builtin_isavail(appname);
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
/* Is output being redirected? */
|
||||||
|
|
||||||
|
if (redirfile)
|
||||||
|
{
|
||||||
|
ret = builtin_startproxy(index, argv, redirfile, oflags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Start the builtin application task */
|
||||||
|
|
||||||
|
ret = builtin_taskcreate(index, argv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the task ID of the new task if the task was sucessfully
|
||||||
|
* started. Otherwise, ret will be ERROR (and the errno value will
|
||||||
|
* be set appropriately).
|
||||||
|
*/
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
############################################################################
|
||||||
|
# apps/builtin/registry/Makefile
|
||||||
|
#
|
||||||
|
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||||
|
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
-include $(TOPDIR)/Make.defs
|
||||||
|
include $(APPDIR)/Make.defs
|
||||||
|
|
||||||
|
# NSH Library
|
||||||
|
|
||||||
|
all:
|
||||||
|
.PHONY: context depend clean distclean
|
||||||
|
|
||||||
|
.updated: $(DEPCONFIG)
|
||||||
|
$(call DELFILE, *.bdat)
|
||||||
|
$(call DELFILE, *.pdat)
|
||||||
|
$(Q) touch .updated
|
||||||
|
|
||||||
|
# This must run before any other context target
|
||||||
|
|
||||||
|
context: .updated
|
||||||
|
|
||||||
|
depend:
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(call CLEAN)
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
$(call DELFILE, *.bdat)
|
||||||
|
$(call DELFILE, *.pdat)
|
||||||
|
$(call DELFILE, .updated)
|
||||||
@@ -39,6 +39,7 @@ source "$APPSDIR/examples/pashello/Kconfig"
|
|||||||
source "$APPSDIR/examples/pipe/Kconfig"
|
source "$APPSDIR/examples/pipe/Kconfig"
|
||||||
source "$APPSDIR/examples/poll/Kconfig"
|
source "$APPSDIR/examples/poll/Kconfig"
|
||||||
source "$APPSDIR/examples/pwm/Kconfig"
|
source "$APPSDIR/examples/pwm/Kconfig"
|
||||||
|
source "$APPSDIR/examples/posix_spawn/Kconfig"
|
||||||
source "$APPSDIR/examples/qencoder/Kconfig"
|
source "$APPSDIR/examples/qencoder/Kconfig"
|
||||||
source "$APPSDIR/examples/relays/Kconfig"
|
source "$APPSDIR/examples/relays/Kconfig"
|
||||||
source "$APPSDIR/examples/rgmp/Kconfig"
|
source "$APPSDIR/examples/rgmp/Kconfig"
|
||||||
@@ -58,5 +59,4 @@ source "$APPSDIR/examples/usbterm/Kconfig"
|
|||||||
source "$APPSDIR/examples/watchdog/Kconfig"
|
source "$APPSDIR/examples/watchdog/Kconfig"
|
||||||
source "$APPSDIR/examples/wget/Kconfig"
|
source "$APPSDIR/examples/wget/Kconfig"
|
||||||
source "$APPSDIR/examples/wgetjson/Kconfig"
|
source "$APPSDIR/examples/wgetjson/Kconfig"
|
||||||
source "$APPSDIR/examples/wlan/Kconfig"
|
|
||||||
source "$APPSDIR/examples/xmlrpc/Kconfig"
|
source "$APPSDIR/examples/xmlrpc/Kconfig"
|
||||||
|
|||||||
@@ -182,6 +182,10 @@ ifeq ($(CONFIG_EXAMPLES_PWM),y)
|
|||||||
CONFIGURED_APPS += examples/pwm
|
CONFIGURED_APPS += examples/pwm
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_EXAMPLES_POSIXSPAWN),y)
|
||||||
|
CONFIGURED_APPS += examples/posix_spawn
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_EXAMPLES_QENCODER),y)
|
ifeq ($(CONFIG_EXAMPLES_QENCODER),y)
|
||||||
CONFIGURED_APPS += examples/qencoder
|
CONFIGURED_APPS += examples/qencoder
|
||||||
endif
|
endif
|
||||||
@@ -254,10 +258,6 @@ ifeq ($(CONFIG_EXAMPLES_WGETJSON),y)
|
|||||||
CONFIGURED_APPS += examples/wgetjson
|
CONFIGURED_APPS += examples/wgetjson
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_EXAMPLES_WLAN),y)
|
|
||||||
CONFIGURED_APPS += examples/wlan
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_EXAMPLES_XMLRPC),y)
|
ifeq ($(CONFIG_EXAMPLES_XMLRPC),y)
|
||||||
CONFIGURED_APPS += examples/xmlrpc
|
CONFIGURED_APPS += examples/xmlrpc
|
||||||
endif
|
endif
|
||||||
|
|||||||
+16
-12
@@ -37,12 +37,15 @@
|
|||||||
|
|
||||||
# Sub-directories
|
# Sub-directories
|
||||||
|
|
||||||
SUBDIRS = adc buttons can cdcacm composite cxxtest dhcpd discover elf ftpc
|
SUBDIRS = adc can cdcacm nsh
|
||||||
SUBDIRS += ftpd hello helloxx hidkbd igmp json keypadtest lcdrw mm modbus mount
|
SUBDIRS += math_demo control_demo kalman_demo px4_deamon_app
|
||||||
SUBDIRS += nettest nsh null nx nxconsole nxffs nxflat nxhello nximage
|
|
||||||
SUBDIRS += nxlines nxtext ostest pashello pipe poll pwm qencoder relays
|
#SUBDIRS = adc buttons can cdcacm composite cxxtest dhcpd discover elf ftpc
|
||||||
SUBDIRS += rgmp romfs serloop telnetd thttpd tiff touchscreen udp uip
|
#SUBDIRS += ftpd hello helloxx hidkbd igmp json keypadtest lcdrw mm modbus mount
|
||||||
SUBDIRS += usbserial sendmail usbstorage usbterm watchdog wget wgetjson wlan
|
#SUBDIRS += nettest nsh null nx nxconsole nxffs nxflat nxhello nximage
|
||||||
|
#SUBDIRS += nxlines nxtext ostest pashello pipe poll pwm posix_spawn qencoder
|
||||||
|
#SUBDIRS += relays rgmp romfs serloop telnetd thttpd tiff touchscreen udp uip
|
||||||
|
#SUBDIRS += usbserial sendmail usbstorage usbterm watchdog wget wgetjson
|
||||||
|
|
||||||
# Sub-directories that might need context setup. Directories may need
|
# Sub-directories that might need context setup. Directories may need
|
||||||
# context setup for a variety of reasons, but the most common is because
|
# context setup for a variety of reasons, but the most common is because
|
||||||
@@ -57,13 +60,14 @@ SUBDIRS += usbserial sendmail usbstorage usbterm watchdog wget wgetjson wlan
|
|||||||
CNTXTDIRS = pwm
|
CNTXTDIRS = pwm
|
||||||
|
|
||||||
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||||
CNTXTDIRS += adc can cdcacm composite cxxtest dhcpd discover ftpd json keypadtest
|
|
||||||
CNTXTDIRS += modbus nettest nxlines relays qencoder telnetd watchdog wgetjson
|
CNTXTDIRS += adc can cdcacm
|
||||||
|
|
||||||
|
#CNTXTDIRS += adc can cdcacm composite cxxtest dhcpd discover ftpd hello json
|
||||||
|
#CNTXTDIRS += keypadtestmodbus nettest nxlines relays qencoder telnetd watchdog
|
||||||
|
#CNTXTDIRS += wgetjson
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_EXAMPLES_HELLO_BUILTIN),y)
|
|
||||||
CNTXTDIRS += hello
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y)
|
ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y)
|
||||||
CNTXTDIRS += helloxx
|
CNTXTDIRS += helloxx
|
||||||
endif
|
endif
|
||||||
@@ -120,7 +124,7 @@ depend: $(foreach SDIR, $(SUBDIRS), $(SDIR)_depend)
|
|||||||
|
|
||||||
clean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_clean)
|
clean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_clean)
|
||||||
|
|
||||||
distclean: clean $(foreach SDIR, $(SUBDIRS), $(SDIR)_distclean)
|
distclean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_distclean)
|
||||||
|
|
||||||
-include Make.dep
|
-include Make.dep
|
||||||
|
|
||||||
|
|||||||
@@ -329,10 +329,10 @@ examples/elf
|
|||||||
each program in the ROMFS file system is executed. Requires CONFIG_ELF.
|
each program in the ROMFS file system is executed. Requires CONFIG_ELF.
|
||||||
Other configuration options:
|
Other configuration options:
|
||||||
|
|
||||||
CONFIG_EXAMPLES_ELF_DEVMINOR - The minor device number of the ROMFS block.
|
CONFIG_EXAMPLES_ELF_DEVMINOR - The minor device number of the ROMFS block
|
||||||
For example, the N in /dev/ramN. Used for registering the RAM block driver
|
driver. For example, the N in /dev/ramN. Used for registering the RAM
|
||||||
that will hold the ROMFS file system containing the ELF executables to be
|
block driver that will hold the ROMFS file system containing the ELF
|
||||||
tested. Default: 0
|
executables to be tested. Default: 0
|
||||||
|
|
||||||
CONFIG_EXAMPLES_ELF_DEVPATH - The path to the ROMFS block driver device. This
|
CONFIG_EXAMPLES_ELF_DEVPATH - The path to the ROMFS block driver device. This
|
||||||
must match EXAMPLES_ELF_DEVMINOR. Used for registering the RAM block driver
|
must match EXAMPLES_ELF_DEVMINOR. Used for registering the RAM block driver
|
||||||
@@ -348,7 +348,7 @@ examples/elf
|
|||||||
|
|
||||||
Similarly for C++ flags which must be provided in CXXELFFLAGS.
|
Similarly for C++ flags which must be provided in CXXELFFLAGS.
|
||||||
|
|
||||||
2. Your top-level nuttx/Make.defs file must alos include an approproate definition,
|
2. Your top-level nuttx/Make.defs file must also include an approproate definition,
|
||||||
LDELFFLAGS, to generate a relocatable ELF object. With GNU LD, this should
|
LDELFFLAGS, to generate a relocatable ELF object. With GNU LD, this should
|
||||||
include '-r' and '-e main' (or _main on some platforms).
|
include '-r' and '-e main' (or _main on some platforms).
|
||||||
|
|
||||||
@@ -491,7 +491,7 @@ examples/hello
|
|||||||
than examples/null with a single printf statement. Really useful only
|
than examples/null with a single printf statement. Really useful only
|
||||||
for bringing up new NuttX architectures.
|
for bringing up new NuttX architectures.
|
||||||
|
|
||||||
* CONFIG_EXAMPLES_HELLO_BUILTIN
|
* CONFIG_NSH_BUILTIN_APPS
|
||||||
Build the "Hello, World" example as an NSH built-in application.
|
Build the "Hello, World" example as an NSH built-in application.
|
||||||
|
|
||||||
examples/helloxx
|
examples/helloxx
|
||||||
@@ -540,9 +540,21 @@ examples/hidkbd
|
|||||||
This is a simple test to debug/verify the USB host HID keyboard class
|
This is a simple test to debug/verify the USB host HID keyboard class
|
||||||
driver.
|
driver.
|
||||||
|
|
||||||
CONFIG_EXAMPLES_HIDKBD_DEFPRIO - Priority of "waiter" thread.
|
CONFIG_EXAMPLES_HIDKBD_DEFPRIO - Priority of "waiter" thread. Default:
|
||||||
CONFIG_EXAMPLES_HIDKBD_STACKSIZE - Stacksize of "waiter" thread.
|
50
|
||||||
|
CONFIG_EXAMPLES_HIDKBD_STACKSIZE - Stacksize of "waiter" thread. Default
|
||||||
|
1024
|
||||||
|
CONFIG_EXAMPLES_HIDKBD_DEVNAME - Name of keyboard device to be used.
|
||||||
|
Default: "/dev/kbda"
|
||||||
|
CONFIG_EXAMPLES_HIDKBD_ENCODED - Decode special key press events in the
|
||||||
|
user buffer. In this case, the example coded will use the interfaces
|
||||||
|
defined in include/nuttx/input/kbd_codec.h to decode the returned
|
||||||
|
keyboard data. These special keys include such things as up/down
|
||||||
|
arrows, home and end keys, etc. If this not defined, only 7-bit print-
|
||||||
|
able and control ASCII characters will be provided to the user.
|
||||||
|
Requires CONFIG_HIDKBD_ENCODED && CONFIG_LIB_KBDCODEC
|
||||||
|
|
||||||
|
endif
|
||||||
examples/igmp
|
examples/igmp
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -1190,6 +1202,80 @@ examples/poll
|
|||||||
|
|
||||||
CONFIGURED_APPS += uiplib
|
CONFIGURED_APPS += uiplib
|
||||||
|
|
||||||
|
examples/posix_spawn
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This is a simple test of the posix_spawn() API. The example derives from
|
||||||
|
examples/elf. As a result, these tests are built using the relocatable
|
||||||
|
ELF format installed in a ROMFS file system. At run time, the test program
|
||||||
|
in the ROMFS file system is spawned using posix_spawn().
|
||||||
|
|
||||||
|
Requires:
|
||||||
|
|
||||||
|
CONFIG_BINFMT_DISABLE=n - Don't disable the binary loader
|
||||||
|
CONFIG_ELF=y - Enable ELF binary loader
|
||||||
|
CONFIG_LIBC_EXECFUNCS=y - Enable support for posix_spawn
|
||||||
|
CONFIG_EXECFUNCS_SYMTAB="exports" - The name of the symbol table
|
||||||
|
created by the test.
|
||||||
|
CONFIG_EXECFUNCS_NSYMBOLS=10 - Value does not matter, it will be
|
||||||
|
corrected at runtime.
|
||||||
|
CONFIG_POSIX_SPAWN_STACKSIZE=768 - This default setting.
|
||||||
|
|
||||||
|
Test-specific configuration options:
|
||||||
|
|
||||||
|
CONFIG_EXAMPLES_POSIXSPAWN_DEVMINOR - The minor device number of the ROMFS
|
||||||
|
block. driver. For example, the N in /dev/ramN. Used for registering the
|
||||||
|
RAM block driver that will hold the ROMFS file system containing the ELF
|
||||||
|
executables to be tested. Default: 0
|
||||||
|
|
||||||
|
CONFIG_EXAMPLES_POSIXSPAWN_DEVPATH - The path to the ROMFS block driver
|
||||||
|
device. This must match EXAMPLES_POSIXSPAWN_DEVMINOR. Used for
|
||||||
|
registering the RAM block driver that will hold the ROMFS file system
|
||||||
|
containing the ELF executables to be tested. Default: "/dev/ram0"
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
|
||||||
|
1. CFLAGS should be provided in CELFFLAGS. RAM and FLASH memory regions
|
||||||
|
may require long allcs. For ARM, this might be:
|
||||||
|
|
||||||
|
CELFFLAGS = $(CFLAGS) -mlong-calls
|
||||||
|
|
||||||
|
Similarly for C++ flags which must be provided in CXXELFFLAGS.
|
||||||
|
|
||||||
|
2. Your top-level nuttx/Make.defs file must also include an approproate
|
||||||
|
definition, LDELFFLAGS, to generate a relocatable ELF object. With GNU
|
||||||
|
LD, this should include '-r' and '-e main' (or _main on some platforms).
|
||||||
|
|
||||||
|
LDELFFLAGS = -r -e main
|
||||||
|
|
||||||
|
If you use GCC to link, you make also need to include '-nostdlib' or
|
||||||
|
'-nostartfiles' and '-nodefaultlibs'.
|
||||||
|
|
||||||
|
3. This example also requires genromfs. genromfs can be build as part of the
|
||||||
|
nuttx toolchain. Or can built from the genromfs sources that can be found
|
||||||
|
at misc/tools/genromfs-0.5.2.tar.gz. In any event, the PATH variable must
|
||||||
|
include the path to the genromfs executable.
|
||||||
|
|
||||||
|
4. ELF size: The ELF files in this example are, be default, quite large
|
||||||
|
because they include a lot of "build garbage". You can greatly reduce the
|
||||||
|
size of the ELF binaries are using the 'objcopy --strip-unneeded' command to
|
||||||
|
remove un-necessary information from the ELF files.
|
||||||
|
|
||||||
|
5. Simulator. You cannot use this example with the the NuttX simulator on
|
||||||
|
Cygwin. That is because the Cygwin GCC does not generate ELF file but
|
||||||
|
rather some Windows-native binary format.
|
||||||
|
|
||||||
|
If you really want to do this, you can create a NuttX x86 buildroot toolchain
|
||||||
|
and use that be build the ELF executables for the ROMFS file system.
|
||||||
|
|
||||||
|
6. Linker scripts. You might also want to use a linker scripts to combine
|
||||||
|
sections better. An example linker script is at nuttx/binfmt/libelf/gnu-elf.ld.
|
||||||
|
That example might have to be tuned for your particular linker output to
|
||||||
|
position additional sections correctly. The GNU LD LDELFFLAGS then might
|
||||||
|
be:
|
||||||
|
|
||||||
|
LDELFFLAGS = -r -e main -T$(TOPDIR)/binfmt/libelf/gnu-elf.ld
|
||||||
|
|
||||||
examples/pwm
|
examples/pwm
|
||||||
^^^^^^^^^^^^
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
|
|||||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
@touch .built
|
@touch .built
|
||||||
|
|
||||||
.context:
|
|
||||||
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||||
|
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
|
||||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||||
@touch $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
context: .context
|
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
|
||||||
|
else
|
||||||
|
context:
|
||||||
|
endif
|
||||||
|
|
||||||
.depend: Makefile $(SRCS)
|
.depend: Makefile $(SRCS)
|
||||||
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||||
|
|||||||
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
|
|||||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
@touch .built
|
@touch .built
|
||||||
|
|
||||||
.context:
|
|
||||||
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||||
|
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
|
||||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||||
@touch $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
context: .context
|
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
|
||||||
|
else
|
||||||
|
context:
|
||||||
|
endif
|
||||||
|
|
||||||
.depend: Makefile $(SRCS)
|
.depend: Makefile $(SRCS)
|
||||||
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||||
|
|||||||
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
|
|||||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
@touch .built
|
@touch .built
|
||||||
|
|
||||||
.context:
|
|
||||||
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||||
|
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
|
||||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||||
@touch $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
context: .context
|
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
|
||||||
|
else
|
||||||
|
context:
|
||||||
|
endif
|
||||||
|
|
||||||
.depend: Makefile $(SRCS)
|
.depend: Makefile $(SRCS)
|
||||||
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||||
|
|||||||
@@ -87,12 +87,17 @@ $(COBJS): %$(OBJEXT): %.c
|
|||||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
@touch .built
|
@touch .built
|
||||||
|
|
||||||
.context:
|
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||||
|
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME1)_main.bdat: $(DEPCONFIG) Makefile
|
||||||
$(call REGISTER,$(APPNAME1),$(PRIORITY1),$(STACKSIZE1),$(APPNAME1)_main)
|
$(call REGISTER,$(APPNAME1),$(PRIORITY1),$(STACKSIZE1),$(APPNAME1)_main)
|
||||||
$(call REGISTER,$(APPNAME2),$(PRIORITY2),$(STACKSIZE2),$(APPNAME2)_main)
|
|
||||||
@touch $@
|
|
||||||
|
|
||||||
context: .context
|
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME2)_main.bdat: $(DEPCONFIG) Makefile
|
||||||
|
$(call REGISTER,$(APPNAME2),$(PRIORITY2),$(STACKSIZE2),$(APPNAME2)_main)
|
||||||
|
|
||||||
|
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME1)_main.bdat $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME2)_main.bdat
|
||||||
|
else
|
||||||
|
context:
|
||||||
|
endif
|
||||||
|
|
||||||
.depend: Makefile $(SRCS)
|
.depend: Makefile $(SRCS)
|
||||||
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||||
|
|||||||
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
|
|||||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
@touch .built
|
@touch .built
|
||||||
|
|
||||||
.context:
|
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||||
ifeq ($(CONFIG_EXAMPLES_HELLO_BUILTIN),y)
|
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
|
||||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||||
@touch $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
context: .context
|
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
|
||||||
|
else
|
||||||
|
context:
|
||||||
|
endif
|
||||||
|
|
||||||
.depend: Makefile $(SRCS)
|
.depend: Makefile $(SRCS)
|
||||||
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||||
|
|||||||
@@ -100,13 +100,14 @@ $(CXXOBJS): %$(OBJEXT): %.cxx
|
|||||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
@touch .built
|
@touch .built
|
||||||
|
|
||||||
.context:
|
|
||||||
ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y)
|
ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y)
|
||||||
|
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
|
||||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||||
@touch $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
context: .context
|
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
|
||||||
|
else
|
||||||
|
context:
|
||||||
|
endif
|
||||||
|
|
||||||
.depend: Makefile $(SRCS)
|
.depend: Makefile $(SRCS)
|
||||||
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||||
|
|||||||
@@ -52,6 +52,10 @@ ifeq ($(CONFIG_ARCH_FPU),y)
|
|||||||
CSRCS += fpu.c
|
CSRCS += fpu.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_SCHED_WAITPID),y)
|
||||||
|
CSRCS += waitpid.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
|
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
|
||||||
CSRCS += cancel.c cond.c mutex.c sem.c barrier.c
|
CSRCS += cancel.c cond.c mutex.c sem.c barrier.c
|
||||||
ifneq ($(CONFIG_RR_INTERVAL),0)
|
ifneq ($(CONFIG_RR_INTERVAL),0)
|
||||||
@@ -84,6 +88,10 @@ ifneq ($(CONFIG_DISABLE_POSIX_TIMERS),y)
|
|||||||
CSRCS += posixtimer.c
|
CSRCS += posixtimer.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
|
||||||
|
CSRCS += vfork.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
||||||
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
|
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
|
||||||
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
|
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
|
||||||
@@ -127,13 +135,14 @@ $(COBJS): %$(OBJEXT): %.c
|
|||||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
@touch .built
|
@touch .built
|
||||||
|
|
||||||
.context:
|
|
||||||
ifeq ($(CONFIG_EXAMPLES_OSTEST_BUILTIN),y)
|
ifeq ($(CONFIG_EXAMPLES_OSTEST_BUILTIN),y)
|
||||||
|
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
|
||||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||||
@touch $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
context: .context
|
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
|
||||||
|
else
|
||||||
|
context:
|
||||||
|
endif
|
||||||
|
|
||||||
.depend: Makefile $(SRCS)
|
.depend: Makefile $(SRCS)
|
||||||
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||||
|
|||||||
@@ -105,71 +105,83 @@
|
|||||||
|
|
||||||
/* dev_null.c ***************************************************************/
|
/* dev_null.c ***************************************************************/
|
||||||
|
|
||||||
extern int dev_null(void);
|
int dev_null(void);
|
||||||
|
|
||||||
/* fpu.c ********************************************************************/
|
/* fpu.c ********************************************************************/
|
||||||
|
|
||||||
extern void fpu_test(void);
|
void fpu_test(void);
|
||||||
|
|
||||||
|
/* waitpid.c ****************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_WAITPID
|
||||||
|
int waitpid_test(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* mutex.c ******************************************************************/
|
/* mutex.c ******************************************************************/
|
||||||
|
|
||||||
extern void mutex_test(void);
|
void mutex_test(void);
|
||||||
|
|
||||||
/* rmutex.c ******************************************************************/
|
/* rmutex.c ******************************************************************/
|
||||||
|
|
||||||
extern void recursive_mutex_test(void);
|
void recursive_mutex_test(void);
|
||||||
|
|
||||||
/* sem.c ********************************************************************/
|
/* sem.c ********************************************************************/
|
||||||
|
|
||||||
extern void sem_test(void);
|
void sem_test(void);
|
||||||
|
|
||||||
/* cond.c *******************************************************************/
|
/* cond.c *******************************************************************/
|
||||||
|
|
||||||
extern void cond_test(void);
|
void cond_test(void);
|
||||||
|
|
||||||
/* mqueue.c *****************************************************************/
|
/* mqueue.c *****************************************************************/
|
||||||
|
|
||||||
extern void mqueue_test(void);
|
void mqueue_test(void);
|
||||||
|
|
||||||
/* timedmqueue.c ************************************************************/
|
/* timedmqueue.c ************************************************************/
|
||||||
|
|
||||||
extern void timedmqueue_test(void);
|
void timedmqueue_test(void);
|
||||||
|
|
||||||
/* cancel.c *****************************************************************/
|
/* cancel.c *****************************************************************/
|
||||||
|
|
||||||
extern void cancel_test(void);
|
void cancel_test(void);
|
||||||
|
|
||||||
/* timedwait.c **************************************************************/
|
/* timedwait.c **************************************************************/
|
||||||
|
|
||||||
extern void timedwait_test(void);
|
void timedwait_test(void);
|
||||||
|
|
||||||
/* sighand.c ****************************************************************/
|
/* sighand.c ****************************************************************/
|
||||||
|
|
||||||
extern void sighand_test(void);
|
void sighand_test(void);
|
||||||
|
|
||||||
/* posixtimers.c ************************************************************/
|
/* posixtimers.c ************************************************************/
|
||||||
|
|
||||||
extern void timer_test(void);
|
void timer_test(void);
|
||||||
|
|
||||||
/* roundrobin.c *************************************************************/
|
/* roundrobin.c *************************************************************/
|
||||||
|
|
||||||
extern void rr_test(void);
|
void rr_test(void);
|
||||||
|
|
||||||
/* barrier.c ****************************************************************/
|
/* barrier.c ****************************************************************/
|
||||||
|
|
||||||
extern void barrier_test(void);
|
void barrier_test(void);
|
||||||
|
|
||||||
/* prioinherit.c ************************************************************/
|
/* prioinherit.c ************************************************************/
|
||||||
|
|
||||||
extern void priority_inheritance(void);
|
void priority_inheritance(void);
|
||||||
|
|
||||||
|
/* vfork.c ******************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_HAVE_VFORK
|
||||||
|
int vfork_test(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* APIs exported (conditionally) by the OS specifically for testing of
|
/* APIs exported (conditionally) by the OS specifically for testing of
|
||||||
* priority inheritance
|
* priority inheritance
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_PRIORITY_INHERITANCE) && defined(CONFIG_SEM_PHDEBUG)
|
#if defined(CONFIG_DEBUG) && defined(CONFIG_PRIORITY_INHERITANCE) && defined(CONFIG_SEM_PHDEBUG)
|
||||||
extern void sem_enumholders(FAR sem_t *sem);
|
void sem_enumholders(FAR sem_t *sem);
|
||||||
extern int sem_nfreeholders(void);
|
int sem_nfreeholders(void);
|
||||||
#else
|
#else
|
||||||
# define sem_enumholders(sem)
|
# define sem_enumholders(sem)
|
||||||
# define sem_nfreeholders()
|
# define sem_nfreeholders()
|
||||||
|
|||||||
@@ -301,6 +301,14 @@ static int user_main(int argc, char *argv[])
|
|||||||
check_test_memory_usage();
|
check_test_memory_usage();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_WAITPID
|
||||||
|
/* Check waitpid() and friends */
|
||||||
|
|
||||||
|
printf("\nuser_main: waitpid test\n");
|
||||||
|
waitpid_test();
|
||||||
|
check_test_memory_usage();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_PTHREAD
|
#ifndef CONFIG_DISABLE_PTHREAD
|
||||||
/* Verify pthreads and pthread mutex */
|
/* Verify pthreads and pthread mutex */
|
||||||
|
|
||||||
@@ -409,6 +417,11 @@ static int user_main(int argc, char *argv[])
|
|||||||
check_test_memory_usage();
|
check_test_memory_usage();
|
||||||
#endif /* CONFIG_PRIORITY_INHERITANCE && !CONFIG_DISABLE_SIGNALS && !CONFIG_DISABLE_PTHREAD */
|
#endif /* CONFIG_PRIORITY_INHERITANCE && !CONFIG_DISABLE_SIGNALS && !CONFIG_DISABLE_PTHREAD */
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_HAVE_VFORK
|
||||||
|
printf("\nuser_main: vfork() test\n");
|
||||||
|
vfork_test();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Compare memory usage at time ostest_main started until
|
/* Compare memory usage at time ostest_main started until
|
||||||
* user_main exits. These should not be identical, but should
|
* user_main exits. These should not be identical, but should
|
||||||
* be similar enough that we can detect any serious OS memory
|
* be similar enough that we can detect any serious OS memory
|
||||||
@@ -428,6 +441,7 @@ static int user_main(int argc, char *argv[])
|
|||||||
show_memory_usage(&g_mmbefore, &g_mmafter);
|
show_memory_usage(&g_mmbefore, &g_mmafter);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("user_main: Exitting\n");
|
printf("user_main: Exitting\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,12 +54,37 @@ static sem_t sem;
|
|||||||
static bool sigreceived = false;
|
static bool sigreceived = false;
|
||||||
static bool threadexited = false;
|
static bool threadexited = false;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||||
|
static void death_of_child(int signo, siginfo_t *info, void *ucontext)
|
||||||
|
{
|
||||||
|
/* Use of printf in a signal handler is NOT safe! It can cause deadlocks!
|
||||||
|
* Also, signals are not queued by NuttX. As a consequence, some
|
||||||
|
* notifications will get lost (or the info data can be overwrittedn)!
|
||||||
|
* Because POSIX does not require signals to be queued, I do not think
|
||||||
|
* that this is a bug (the overwriting is a bug, however).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
printf("death_of_child: PID %d received signal=%d code=%d pid=%d status=%d\n",
|
||||||
|
getpid(), signo, info->si_code, info->si_pid, info->si_status);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("death_of_child: PID %d received signal=%d (no info?)\n",
|
||||||
|
getpid(), signo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void wakeup_action(int signo, siginfo_t *info, void *ucontext)
|
static void wakeup_action(int signo, siginfo_t *info, void *ucontext)
|
||||||
{
|
{
|
||||||
sigset_t oldset;
|
sigset_t oldset;
|
||||||
sigset_t allsigs;
|
sigset_t allsigs;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
/* Use of printf in a signal handler is NOT safe! It can cause deadlocks! */
|
||||||
|
|
||||||
printf("wakeup_action: Received signal %d\n" , signo);
|
printf("wakeup_action: Received signal %d\n" , signo);
|
||||||
|
|
||||||
sigreceived = true;
|
sigreceived = true;
|
||||||
@@ -186,6 +211,11 @@ static int waiter_main(int argc, char *argv[])
|
|||||||
|
|
||||||
void sighand_test(void)
|
void sighand_test(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||||
|
struct sigaction act;
|
||||||
|
struct sigaction oact;
|
||||||
|
sigset_t sigset;
|
||||||
|
#endif
|
||||||
struct sched_param param;
|
struct sched_param param;
|
||||||
union sigval sigvalue;
|
union sigval sigvalue;
|
||||||
pid_t waiterpid;
|
pid_t waiterpid;
|
||||||
@@ -195,6 +225,32 @@ void sighand_test(void)
|
|||||||
printf("sighand_test: Initializing semaphore to 0\n" );
|
printf("sighand_test: Initializing semaphore to 0\n" );
|
||||||
sem_init(&sem, 0, 0);
|
sem_init(&sem, 0, 0);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||||
|
printf("sighand_test: Unmasking SIGCHLD\n");
|
||||||
|
|
||||||
|
(void)sigemptyset(&sigset);
|
||||||
|
(void)sigaddset(&sigset, SIGCHLD);
|
||||||
|
status = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
||||||
|
if (status != OK)
|
||||||
|
{
|
||||||
|
printf("sighand_test: ERROR sigprocmask failed, status=%d\n",
|
||||||
|
status);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("sighand_test: Registering SIGCHLD handler\n" );
|
||||||
|
act.sa_sigaction = death_of_child;
|
||||||
|
act.sa_flags = SA_SIGINFO;
|
||||||
|
|
||||||
|
(void)sigfillset(&act.sa_mask);
|
||||||
|
(void)sigdelset(&act.sa_mask, SIGCHLD);
|
||||||
|
|
||||||
|
status = sigaction(SIGCHLD, &act, &oact);
|
||||||
|
if (status != OK)
|
||||||
|
{
|
||||||
|
printf("waiter_main: ERROR sigaction failed, status=%d\n" , status);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Start waiter thread */
|
/* Start waiter thread */
|
||||||
|
|
||||||
printf("sighand_test: Starting waiter task\n" );
|
printf("sighand_test: Starting waiter task\n" );
|
||||||
@@ -262,6 +318,13 @@ void sighand_test(void)
|
|||||||
printf("sighand_test: ERROR signal handler did not run\n" );
|
printf("sighand_test: ERROR signal handler did not run\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Detach the signal handler */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||||
|
act.sa_sigaction = SIG_DFL;
|
||||||
|
status = sigaction(SIGCHLD, &act, &oact);
|
||||||
|
#endif
|
||||||
|
|
||||||
printf("sighand_test: done\n" );
|
printf("sighand_test: done\n" );
|
||||||
FFLUSH();
|
FFLUSH();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* examples/ostest/vfork.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "ostest.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARCH_HAVE_VFORK) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||||
|
static volatile bool g_vforkchild;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int vfork_test(void)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_ARCH_HAVE_VFORK) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
g_vforkchild = false;
|
||||||
|
pid = vfork();
|
||||||
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
/* There is not very much that the child is permitted to do. Perhaps
|
||||||
|
* it can just set g_vforkchild.
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_vforkchild = true;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else if (pid < 0)
|
||||||
|
{
|
||||||
|
printf("vfork_test: vfork() failed: %d\n", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sleep(1);
|
||||||
|
if (g_vforkchild)
|
||||||
|
{
|
||||||
|
printf("vfork_test: Child %d ran successfully\n", pid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("vfork_test: ERROR Child %d did not run\n", pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,269 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* examples/ostest/waitpid.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "ostest.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_WAITPID
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define RETURN_STATUS 14
|
||||||
|
#define NCHILDREN 3
|
||||||
|
#define PRIORITY 100
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int g_waitpids[NCHILDREN];
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Priviate Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int waitpid_main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
pid_t me = getpid();
|
||||||
|
|
||||||
|
printf("waitpid_main: PID %d Started\n", me);
|
||||||
|
sleep(3);
|
||||||
|
printf("waitpid_main: PID %d exitting with result=%d\n", me, RETURN_STATUS);
|
||||||
|
return RETURN_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void waitpid_start_children(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NCHILDREN; i++)
|
||||||
|
{
|
||||||
|
ret = TASK_CREATE("waitpid", PRIORITY, STACKSIZE, waitpid_main, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
printf("waitpid_start_child: ERROR Failed to start user_main\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("waitpid_start_child: Started waitpid_main at PID=%d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_waitpids[i] = ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void waitpid_last(void)
|
||||||
|
{
|
||||||
|
int stat_loc;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
printf("waitpid_last: Waiting for PID=%d with waitpid()\n",
|
||||||
|
g_waitpids[NCHILDREN-1]);
|
||||||
|
|
||||||
|
ret = (int)waitpid(g_waitpids[NCHILDREN-1], &stat_loc, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = errno;
|
||||||
|
printf("waitpid_last: ERROR: PID %d waitpid failed: %d\n",
|
||||||
|
g_waitpids[NCHILDREN-1], errcode);
|
||||||
|
}
|
||||||
|
else if (stat_loc != RETURN_STATUS)
|
||||||
|
{
|
||||||
|
printf("waitpid_last: ERROR: PID %d return status is %d, expected %d\n",
|
||||||
|
g_waitpids[NCHILDREN-1], stat_loc, RETURN_STATUS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("waitpid_last: PID %d waitpid succeeded with stat_loc=%d\n",
|
||||||
|
g_waitpids[NCHILDREN-1], stat_loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int waitpid_test(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||||
|
siginfo_t info;
|
||||||
|
#endif
|
||||||
|
int stat_loc;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Start the children and wait for first one to complete */
|
||||||
|
|
||||||
|
printf("\nTest waitpid()\n");
|
||||||
|
waitpid_start_children();
|
||||||
|
|
||||||
|
printf("waitpid_test: Waiting for PID=%d with waitpid()\n", g_waitpids[0]);
|
||||||
|
ret = (int)waitpid(g_waitpids[0], &stat_loc, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = errno;
|
||||||
|
printf("waitpid_test: ERROR: PID %d waitpid failed: %d\n",
|
||||||
|
g_waitpids[0], errcode);
|
||||||
|
}
|
||||||
|
else if (ret != g_waitpids[0])
|
||||||
|
{
|
||||||
|
printf("waitpid_test: ERROR: PID %d wait returned PID %d\n",
|
||||||
|
g_waitpids[0], ret);
|
||||||
|
}
|
||||||
|
else if (stat_loc != RETURN_STATUS)
|
||||||
|
{
|
||||||
|
printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
|
||||||
|
g_waitpids[0], stat_loc, RETURN_STATUS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("waitpid_test: PID %d waitpid succeeded with stat_loc=%d\n",
|
||||||
|
g_waitpids[0], stat_loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait a big to make sure that the other threads complete */
|
||||||
|
|
||||||
|
waitpid_last();
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||||
|
/* Start the children and wait for first one to complete */
|
||||||
|
|
||||||
|
printf("\nTest waitid(P_PID)\n");
|
||||||
|
waitpid_start_children();
|
||||||
|
|
||||||
|
printf("waitpid_test: Waiting for PID=%d with waitid()\n", g_waitpids[0]);
|
||||||
|
ret = waitid(P_PID, (id_t)g_waitpids[0], &info, WEXITED);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = errno;
|
||||||
|
printf("waitpid_test: ERROR: PID %d waitid failed: %d\n",
|
||||||
|
g_waitpids[0], errcode);
|
||||||
|
}
|
||||||
|
else if (info.si_pid != g_waitpids[0])
|
||||||
|
{
|
||||||
|
printf("waitpid_test: ERROR: PID %d waitid returned PID %d\n",
|
||||||
|
g_waitpids[0], info.si_pid);
|
||||||
|
}
|
||||||
|
else if (info.si_status != RETURN_STATUS)
|
||||||
|
{
|
||||||
|
printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
|
||||||
|
info.si_pid, info.si_status, RETURN_STATUS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("waitpid_test: waitid PID %d succeeded with si_status=%d\n",
|
||||||
|
info.si_pid, info.si_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait a big to make sure that the other threads complete */
|
||||||
|
|
||||||
|
waitpid_last();
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
/* Start the children and wait for any one to complete */
|
||||||
|
|
||||||
|
printf("\nTest waitid(P_ALL)\n");
|
||||||
|
waitpid_start_children();
|
||||||
|
|
||||||
|
printf("waitpid_test: Waiting for any child with waitid()\n");
|
||||||
|
ret = waitid(P_ALL, 0, &info, WEXITED);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = errno;
|
||||||
|
printf("waitpid_test: ERROR: waitid failed: %d\n", errcode);
|
||||||
|
}
|
||||||
|
else if (info.si_status != RETURN_STATUS)
|
||||||
|
{
|
||||||
|
printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
|
||||||
|
info.si_pid, info.si_status, RETURN_STATUS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("waitpid_test: PID %d waitid succeeded with si_status=%d\n",
|
||||||
|
info.si_pid, info.si_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait a big to make sure that the other threads complete */
|
||||||
|
|
||||||
|
waitpid_last();
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
/* Start the children and wait for first one to complete */
|
||||||
|
|
||||||
|
printf("\nTest wait()\n");
|
||||||
|
waitpid_start_children();
|
||||||
|
|
||||||
|
printf("waitpid_test: Waiting for any child with wait()\n");
|
||||||
|
ret = (int)wait(&stat_loc);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = errno;
|
||||||
|
printf("waitpid_test: ERROR: wait failed: %d\n", errcode);
|
||||||
|
}
|
||||||
|
else if (stat_loc != RETURN_STATUS)
|
||||||
|
{
|
||||||
|
printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
|
||||||
|
ret, stat_loc, RETURN_STATUS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("waitpid_test: PID %d wait succeeded with stat_loc=%d\n",
|
||||||
|
ret, stat_loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait a big to make sure that the other threads complete */
|
||||||
|
|
||||||
|
waitpid_last();
|
||||||
|
sleep(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_SCHED_WAITPID */
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#
|
||||||
|
# For a description of the syntax of this configuration file,
|
||||||
|
# see misc/tools/kconfig-language.txt.
|
||||||
|
#
|
||||||
|
|
||||||
|
config EXAMPLES_POSIXSPAWN
|
||||||
|
bool "posix_spawn Unit Test"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Enable the posix_spawn() unit test
|
||||||
|
|
||||||
|
if EXAMPLES_POSIXSPAWN
|
||||||
|
config EXAMPLES_POSIXSPAWN_DEVMINOR
|
||||||
|
int "ROMFS Minor Device Number"
|
||||||
|
default 0
|
||||||
|
---help---
|
||||||
|
The minor device number of the ROMFS block. For example, the N in /dev/ramN.
|
||||||
|
Used for registering the RAM block driver that will hold the ROMFS file system
|
||||||
|
containing the ELF executables to be tested. Default: 0
|
||||||
|
|
||||||
|
config EXAMPLES_POSIXSPAWN_DEVPATH
|
||||||
|
string "ROMFS Devie Path"
|
||||||
|
default "/dev/ram0"
|
||||||
|
---help---
|
||||||
|
The path to the ROMFS block driver device. This must match EXAMPLES_POSIXSPAWN_DEVMINOR.
|
||||||
|
Used for registering the RAM block driver that will hold the ROMFS file system
|
||||||
|
containing the ELF executables to be tested. Default: "/dev/ram0"
|
||||||
|
|
||||||
|
endif
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
############################################################################
|
||||||
|
# apps/examples/posix_spawn/Makefile
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||||
|
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
-include $(TOPDIR)/.config
|
||||||
|
-include $(TOPDIR)/Make.defs
|
||||||
|
include $(APPDIR)/Make.defs
|
||||||
|
|
||||||
|
# ELF Example
|
||||||
|
|
||||||
|
ASRCS =
|
||||||
|
CSRCS = spawn_main.c symtab.c
|
||||||
|
|
||||||
|
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||||
|
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||||
|
|
||||||
|
SRCS = $(ASRCS) $(CSRCS)
|
||||||
|
OBJS = $(AOBJS) $(COBJS)
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||||
|
BIN = ..\..\libapps$(LIBEXT)
|
||||||
|
else
|
||||||
|
ifeq ($(WINTOOL),y)
|
||||||
|
BIN = ..\\..\\libapps$(LIBEXT)
|
||||||
|
else
|
||||||
|
BIN = ../../libapps$(LIBEXT)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ROOTDEPPATH = --dep-path . --dep-path filesystem
|
||||||
|
|
||||||
|
# Build targets
|
||||||
|
|
||||||
|
VPATH = filesystem
|
||||||
|
|
||||||
|
all: build
|
||||||
|
.PHONY: build clean_filesystem clean depend distclean
|
||||||
|
|
||||||
|
$(AOBJS): %$(OBJEXT): %.S
|
||||||
|
$(call ASSEMBLE, $<, $@)
|
||||||
|
|
||||||
|
$(COBJS): %$(OBJEXT): %.c
|
||||||
|
$(call COMPILE, $<, $@)
|
||||||
|
|
||||||
|
# This is a little messy. The build is broken into two pieces: (1) the
|
||||||
|
# filesystem/ subdir build that auto-generates several files, and (2) the library
|
||||||
|
# build. This is done because we need a fresh build context after auto-
|
||||||
|
# generating the source files.
|
||||||
|
|
||||||
|
build_lib: $(OBJS)
|
||||||
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
|
|
||||||
|
build:
|
||||||
|
@$(MAKE) -C filesystem TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV)
|
||||||
|
@$(MAKE) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" build_lib
|
||||||
|
|
||||||
|
context:
|
||||||
|
|
||||||
|
# We can't make dependencies in this directory because the required
|
||||||
|
# header files may not yet exist.
|
||||||
|
|
||||||
|
.depend:
|
||||||
|
@touch $@
|
||||||
|
|
||||||
|
depend: .depend
|
||||||
|
|
||||||
|
clean_filesystem:
|
||||||
|
@$(MAKE) -C filesystem TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV) clean
|
||||||
|
|
||||||
|
clean: clean_filesystem
|
||||||
|
$(call CLEAN)
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
$(call DELFILE, Make.dep)
|
||||||
|
$(call DELFILE, .depend)
|
||||||
|
|
||||||
|
# There are no dependencies in this directory. Some of more important
|
||||||
|
# and more obvious dependencies are hard-coded here:
|
||||||
|
|
||||||
|
spawn_main.o: spawn_main.c \
|
||||||
|
$(TOPDIR)/include/nuttx/config.h \
|
||||||
|
$(TOPDIR)/include/nuttx/compiler.h \
|
||||||
|
$(TOPDIR)/include/sys/mount.h \
|
||||||
|
$(TOPDIR)/include/stdio.h \
|
||||||
|
$(TOPDIR)/include/stdlib.h \
|
||||||
|
$(TOPDIR)/include/unistd.h \
|
||||||
|
$(TOPDIR)/include/string.h \
|
||||||
|
$(TOPDIR)/include/fcntl.h \
|
||||||
|
$(TOPDIR)/include/spawn.h \
|
||||||
|
$(TOPDIR)/include/debug.h \
|
||||||
|
$(TOPDIR)/include/errno.h \
|
||||||
|
$(TOPDIR)/include/nuttx/ramdisk.h \
|
||||||
|
$(TOPDIR)/include/nuttx/binfmt/elf.h \
|
||||||
|
$(TOPDIR)/include/nuttx/binfmt/symtab.h \
|
||||||
|
filesystem/romfs.h
|
||||||
|
|
||||||
|
symtab.o: filesystem/symtab.c \
|
||||||
|
$(TOPDIR)/include/nuttx/compiler.h \
|
||||||
|
$(TOPDIR)/include/nuttx/binfmt/symtab.h
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
############################################################################
|
||||||
|
# apps/examples/posix_spawn/filesystem/Makefile
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||||
|
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
-include $(TOPDIR)/Make.defs
|
||||||
|
include $(APPDIR)$(DELIM)Make.defs
|
||||||
|
|
||||||
|
SPAWN_DIR = $(APPDIR)$(DELIM)examples$(DELIM)posix_spawn
|
||||||
|
FILESYSTEM_DIR = $(SPAWN_DIR)$(DELIM)filesystem
|
||||||
|
ROMFS_DIR = $(FILESYSTEM_DIR)$(DELIM)romfs
|
||||||
|
ROMFS_IMG = $(FILESYSTEM_DIR)$(DELIM)romfs.img
|
||||||
|
ROMFS_HDR = $(FILESYSTEM_DIR)$(DELIM)romfs.h
|
||||||
|
SYMTAB_SRC = $(FILESYSTEM_DIR)$(DELIM)symtab.c
|
||||||
|
|
||||||
|
all: $(ROMFS_HDR) $(SYMTAB_SRC)
|
||||||
|
.PHONY: all hello/hello redirect/redirect clean populate
|
||||||
|
|
||||||
|
# Create the romfs directory
|
||||||
|
|
||||||
|
$(ROMFS_DIR):
|
||||||
|
$(Q) mkdir $(ROMFS_DIR)
|
||||||
|
|
||||||
|
# Build the hello test program
|
||||||
|
|
||||||
|
hello/hello:
|
||||||
|
$(Q) $(MAKE) -C hello hello TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
|
||||||
|
|
||||||
|
# Build the redirection test program
|
||||||
|
|
||||||
|
redirect/redirect:
|
||||||
|
$(Q) $(MAKE) -C redirect redirect TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
|
||||||
|
|
||||||
|
# Create the romfs.img file from the romfs directory
|
||||||
|
|
||||||
|
$(ROMFS_IMG): hello/hello redirect/redirect testdata.txt $(ROMFS_DIR)
|
||||||
|
$(Q) $(MAKE) -C hello install TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
|
||||||
|
$(Q) $(MAKE) -C redirect install TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
|
||||||
|
$(Q) install --mode=0644 testdata.txt $(ROMFS_DIR)/testdata.txt
|
||||||
|
$(Q) genromfs -f $@ -d $(ROMFS_DIR) -V "POSIXSPAWN"
|
||||||
|
|
||||||
|
# Create the romfs.h header file from the romfs.img file
|
||||||
|
|
||||||
|
$(ROMFS_HDR) : $(ROMFS_IMG)
|
||||||
|
$(Q) (cd $(FILESYSTEM_DIR); xxd -i romfs.img | sed -e "s/^unsigned/static const unsigned/g" >$@)
|
||||||
|
|
||||||
|
# Create the exported symbol table
|
||||||
|
|
||||||
|
$(SYMTAB_SRC): $(ROMFS_DIR)/hello $(ROMFS_DIR)/redirect $(ROMFS_DIR)/testdata.txt
|
||||||
|
$(Q) $(FILESYSTEM_DIR)$(DELIM)mksymtab.sh $(ROMFS_DIR) >$@
|
||||||
|
|
||||||
|
# Clean each subdirectory
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(Q) $(MAKE) -C hello clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
|
||||||
|
$(Q) $(MAKE) -C redirect clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
|
||||||
|
$(Q) rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB_SRC)
|
||||||
|
$(Q) rm -rf $(ROMFS_DIR)
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* examples/posix_spawn/filesystem/hello/hello.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Mandatory "Hello, world!" */
|
||||||
|
|
||||||
|
puts("Getting ready to say \"Hello, world\"\n");
|
||||||
|
printf("Hello, world!\n");
|
||||||
|
puts("It has been said.\n");
|
||||||
|
|
||||||
|
/* Print arguments */
|
||||||
|
|
||||||
|
printf("argc\t= %d\n", argc);
|
||||||
|
printf("argv\t= 0x%p\n", argv);
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
printf("argv[%d]\t= ", i);
|
||||||
|
if (argv[i])
|
||||||
|
{
|
||||||
|
printf("(0x%p) \"%s\"\n", argv[i], argv[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("NULL?\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("argv[%d]\t= 0x%p\n", argc, argv[argc]);
|
||||||
|
printf("Goodbye, world!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
usage="Usage: $0 <test-dir-path>"
|
||||||
|
|
||||||
|
# Check for the required ROMFS directory path
|
||||||
|
|
||||||
|
dir=$1
|
||||||
|
if [ -z "$dir" ]; then
|
||||||
|
echo "ERROR: Missing <test-dir-path>"
|
||||||
|
echo ""
|
||||||
|
echo $usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$dir" ]; then
|
||||||
|
echo "ERROR: Directory $dir does not exist"
|
||||||
|
echo ""
|
||||||
|
echo $usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract all of the undefined symbols from the ELF files and create a
|
||||||
|
# list of sorted, unique undefined variable names.
|
||||||
|
|
||||||
|
varlist=`find ${dir} -executable -type f | xargs nm | fgrep ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2 | sort | uniq`
|
||||||
|
|
||||||
|
# Now output the symbol table as a structure in a C source file. All
|
||||||
|
# undefined symbols are declared as void* types. If the toolchain does
|
||||||
|
# any kind of checking for function vs. data objects, then this could
|
||||||
|
# faile
|
||||||
|
|
||||||
|
echo "#include <nuttx/compiler.h>"
|
||||||
|
echo "#include <nuttx/binfmt/symtab.h>"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
for var in $varlist; do
|
||||||
|
echo "extern void *${var};"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "const struct symtab_s exports[] = "
|
||||||
|
echo "{"
|
||||||
|
|
||||||
|
for var in $varlist; do
|
||||||
|
echo " {\"${var}\", &${var}},"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "};"
|
||||||
|
echo ""
|
||||||
|
echo "const int nexports = sizeof(exports) / sizeof(struct symtab_s);"
|
||||||
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* examples/posix_spawn/filesystem/redirect/redirect.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
printf("Entering the stdin redirection test\n");
|
||||||
|
|
||||||
|
/* stdin should have been redirected to testdata.txt. Read and print until
|
||||||
|
* we hit the end of file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while ((ch = getchar()) != EOF)
|
||||||
|
{
|
||||||
|
putchar(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Exit-ing the stdin redirection test\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Now is the time for all good men to come to the aid of their party.
|
||||||
|
|
||||||
@@ -0,0 +1,460 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* examples/posix_spawn/spawn_main.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <nuttx/compiler.h>
|
||||||
|
|
||||||
|
#include <sys/mount.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <spawn.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/ramdisk.h>
|
||||||
|
#include <nuttx/binfmt/elf.h>
|
||||||
|
#include <nuttx/binfmt/symtab.h>
|
||||||
|
|
||||||
|
#include "filesystem/romfs.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Check configuration. This is not all of the configuration settings that
|
||||||
|
* are required -- only the more obvious.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS < 1
|
||||||
|
# error "You must provide file descriptors via CONFIG_NFILE_DESCRIPTORS in your configuration file"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BINFMT_DISABLE
|
||||||
|
# error "The binary loader is disabled (CONFIG_BINFMT_DISABLE)!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_ELF
|
||||||
|
# error "You must select CONFIG_ELF in your configuration file"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_FS_ROMFS
|
||||||
|
# error "You must select CONFIG_FS_ROMFS in your configuration file"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DISABLE_MOUNTPOINT
|
||||||
|
# error "You must not disable mountpoints via CONFIG_DISABLE_MOUNTPOINT in your configuration file"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BINFMT_DISABLE
|
||||||
|
# error "You must not disable loadable modules via CONFIG_BINFMT_DISABLE in your configuration file"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Describe the ROMFS file system */
|
||||||
|
|
||||||
|
#define SECTORSIZE 512
|
||||||
|
#define NSECTORS(b) (((b)+SECTORSIZE-1)/SECTORSIZE)
|
||||||
|
#define MOUNTPT "/mnt/romfs"
|
||||||
|
|
||||||
|
#ifndef CONFIG_EXAMPLES_ELF_DEVMINOR
|
||||||
|
# define CONFIG_EXAMPLES_ELF_DEVMINOR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_EXAMPLES_ELF_DEVPATH
|
||||||
|
# define CONFIG_EXAMPLES_ELF_DEVPATH "/dev/ram0"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If CONFIG_DEBUG is enabled, use dbg instead of printf so that the
|
||||||
|
* output will be synchronous with the debug output.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_CPP_HAVE_VARARGS
|
||||||
|
# ifdef CONFIG_DEBUG
|
||||||
|
# define message(format, arg...) dbg(format, ##arg)
|
||||||
|
# define err(format, arg...) dbg(format, ##arg)
|
||||||
|
# else
|
||||||
|
# define message(format, arg...) printf(format, ##arg)
|
||||||
|
# define err(format, arg...) fprintf(stderr, format, ##arg)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifdef CONFIG_DEBUG
|
||||||
|
# define message dbg
|
||||||
|
# define err dbg
|
||||||
|
# else
|
||||||
|
# define message printf
|
||||||
|
# define err printf
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static unsigned int g_mminitial; /* Initial memory usage */
|
||||||
|
static unsigned int g_mmstep; /* Memory Usage at beginning of test step */
|
||||||
|
|
||||||
|
static const char delimiter[] =
|
||||||
|
"****************************************************************************";
|
||||||
|
static const char g_redirect[] = "redirect";
|
||||||
|
static const char g_hello[] = "hello";
|
||||||
|
static const char g_data[] = "testdata.txt";
|
||||||
|
|
||||||
|
static char fullpath[128];
|
||||||
|
|
||||||
|
static char * const g_argv[4] =
|
||||||
|
{ "Argument 1", "Argument 2", "Argument 3", NULL };
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Symbols from Auto-Generated Code
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
extern const struct symtab_s exports[];
|
||||||
|
extern const int nexports;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_update
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void mm_update(FAR unsigned int *previous, FAR const char *msg)
|
||||||
|
{
|
||||||
|
struct mallinfo mmcurrent;
|
||||||
|
|
||||||
|
/* Get the current memory usage */
|
||||||
|
|
||||||
|
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||||
|
mmcurrent = mallinfo();
|
||||||
|
#else
|
||||||
|
(void)mallinfo(&mmcurrent);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Show the change from the previous time */
|
||||||
|
|
||||||
|
printf("\nMemory Usage %s:\n", msg);
|
||||||
|
printf(" Before: %8u After: %8u Change: %8d\n",
|
||||||
|
*previous, mmcurrent.uordblks, (int)mmcurrent.uordblks - (int)*previous);
|
||||||
|
|
||||||
|
/* Set up for the next test */
|
||||||
|
|
||||||
|
*previous = mmcurrent.uordblks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_initmonitor
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void mm_initmonitor(void)
|
||||||
|
{
|
||||||
|
struct mallinfo mmcurrent;
|
||||||
|
|
||||||
|
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||||
|
mmcurrent = mallinfo();
|
||||||
|
#else
|
||||||
|
(void)mallinfo(&mmcurrent);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_mminitial = mmcurrent.uordblks;
|
||||||
|
g_mmstep = mmcurrent.uordblks;
|
||||||
|
|
||||||
|
printf("Initial memory usage: %d\n", mmcurrent.uordblks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: testheader
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline void testheader(FAR const char *progname)
|
||||||
|
{
|
||||||
|
message("\n%s\n* Executing %s\n%s\n\n", delimiter, progname, delimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: spawn_main
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int spawn_main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
posix_spawn_file_actions_t file_actions;
|
||||||
|
posix_spawnattr_t attr;
|
||||||
|
FAR const char *filepath;
|
||||||
|
pid_t pid;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Initialize the memory monitor */
|
||||||
|
|
||||||
|
mm_initmonitor();
|
||||||
|
|
||||||
|
/* Initialize the ELF binary loader */
|
||||||
|
|
||||||
|
message("Initializing the ELF binary loader\n");
|
||||||
|
ret = elf_initialize();
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
err("ERROR: Initialization of the ELF loader failed: %d\n", ret);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_update(&g_mmstep, "after elf_initialize");
|
||||||
|
|
||||||
|
/* Create a ROM disk for the ROMFS filesystem */
|
||||||
|
|
||||||
|
message("Registering romdisk at /dev/ram%d\n", CONFIG_EXAMPLES_ELF_DEVMINOR);
|
||||||
|
ret = romdisk_register(CONFIG_EXAMPLES_ELF_DEVMINOR, (FAR uint8_t *)romfs_img,
|
||||||
|
NSECTORS(romfs_img_len), SECTORSIZE);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
err("ERROR: romdisk_register failed: %d\n", ret);
|
||||||
|
elf_uninitialize();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_update(&g_mmstep, "after romdisk_register");
|
||||||
|
|
||||||
|
/* Mount the file system */
|
||||||
|
|
||||||
|
message("Mounting ROMFS filesystem at target=%s with source=%s\n",
|
||||||
|
MOUNTPT, CONFIG_EXAMPLES_ELF_DEVPATH);
|
||||||
|
|
||||||
|
ret = mount(CONFIG_EXAMPLES_ELF_DEVPATH, MOUNTPT, "romfs", MS_RDONLY, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
err("ERROR: mount(%s,%s,romfs) failed: %s\n",
|
||||||
|
CONFIG_EXAMPLES_ELF_DEVPATH, MOUNTPT, errno);
|
||||||
|
elf_uninitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_update(&g_mmstep, "after mount");
|
||||||
|
|
||||||
|
/* Does the system support the PATH variable? Has the PATH variable
|
||||||
|
* already been set? If YES and NO, then set the PATH variable to
|
||||||
|
* the ROMFS mountpoint.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_BINFMT_EXEPATH) && !defined(CONFIG_PATH_INITIAL)
|
||||||
|
(void)setenv("PATH", MOUNTPT, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Make sure that we are using our symbol take */
|
||||||
|
|
||||||
|
exec_setsymtab(exports, nexports);
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Case 1: Simple program with arguments
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
/* Output a seperated so that we can clearly discriminate the output of
|
||||||
|
* this program from the others.
|
||||||
|
*/
|
||||||
|
|
||||||
|
testheader(g_hello);
|
||||||
|
|
||||||
|
/* Initialize the attributes file actions structure */
|
||||||
|
|
||||||
|
ret = posix_spawn_file_actions_init(&file_actions);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawn_file_actions_init failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
posix_spawn_file_actions_dump(&file_actions);
|
||||||
|
|
||||||
|
ret = posix_spawnattr_init(&attr);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawnattr_init failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
posix_spawnattr_dump(&attr);
|
||||||
|
|
||||||
|
mm_update(&g_mmstep, "after file_action/attr init");
|
||||||
|
|
||||||
|
/* If the binary loader does not support the PATH variable, then
|
||||||
|
* create the full path to the executable program. Otherwise,
|
||||||
|
* use the relative path so that the binary loader will have to
|
||||||
|
* search the PATH variable to find the executable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_BINFMT_EXEPATH
|
||||||
|
filepath = g_hello;
|
||||||
|
#else
|
||||||
|
snprintf(fullpath, 128, "%s/%s", MOUNTPT, g_hello);
|
||||||
|
filepath = fullpath;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Execute the program */
|
||||||
|
|
||||||
|
mm_update(&g_mmstep, "before posix_spawn");
|
||||||
|
|
||||||
|
ret = posix_spawn(&pid, filepath, &file_actions, &attr, NULL, (FAR char * const*)&g_argv);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawn failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(4);
|
||||||
|
mm_update(&g_mmstep, "after posix_spawn");
|
||||||
|
|
||||||
|
/* Free attibutes and file actions */
|
||||||
|
|
||||||
|
ret = posix_spawn_file_actions_destroy(&file_actions);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawn_file_actions_destroy failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
posix_spawn_file_actions_dump(&file_actions);
|
||||||
|
|
||||||
|
ret = posix_spawnattr_destroy(&attr);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawnattr_destroy failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
posix_spawnattr_dump(&attr);
|
||||||
|
|
||||||
|
mm_update(&g_mmstep, "after file_action/attr destruction");
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Case 2: Simple program with redirection of stdin to a file input
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
/* Output a seperated so that we can clearly discriminate the output of
|
||||||
|
* this program from the others.
|
||||||
|
*/
|
||||||
|
|
||||||
|
testheader(g_redirect);
|
||||||
|
|
||||||
|
/* Initialize the attributes file actions structure */
|
||||||
|
|
||||||
|
ret = posix_spawn_file_actions_init(&file_actions);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawn_file_actions_init failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
posix_spawn_file_actions_dump(&file_actions);
|
||||||
|
|
||||||
|
ret = posix_spawnattr_init(&attr);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawnattr_init failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
posix_spawnattr_dump(&attr);
|
||||||
|
|
||||||
|
mm_update(&g_mmstep, "after file_action/attr init");
|
||||||
|
|
||||||
|
/* Set up to close stdin (0) and open testdata.txt as the program input */
|
||||||
|
|
||||||
|
ret = posix_spawn_file_actions_addclose(&file_actions, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawn_file_actions_addclose failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
posix_spawn_file_actions_dump(&file_actions);
|
||||||
|
|
||||||
|
snprintf(fullpath, 128, "%s/%s", MOUNTPT, g_data);
|
||||||
|
ret = posix_spawn_file_actions_addopen(&file_actions, 0, fullpath, O_RDONLY, 0644);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawn_file_actions_addopen failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
posix_spawn_file_actions_dump(&file_actions);
|
||||||
|
|
||||||
|
mm_update(&g_mmstep, "after adding file_actions");
|
||||||
|
|
||||||
|
/* If the binary loader does not support the PATH variable, then
|
||||||
|
* create the full path to the executable program. Otherwise,
|
||||||
|
* use the relative path so that the binary loader will have to
|
||||||
|
* search the PATH variable to find the executable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_BINFMT_EXEPATH
|
||||||
|
filepath = g_redirect;
|
||||||
|
#else
|
||||||
|
snprintf(fullpath, 128, "%s/%s", MOUNTPT, g_redirect);
|
||||||
|
filepath = fullpath;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Execute the program */
|
||||||
|
|
||||||
|
mm_update(&g_mmstep, "before posix_spawn");
|
||||||
|
|
||||||
|
ret = posix_spawn(&pid, filepath, &file_actions, &attr, NULL, NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawn failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(2);
|
||||||
|
mm_update(&g_mmstep, "after posix_spawn");
|
||||||
|
|
||||||
|
/* Free attibutes and file actions */
|
||||||
|
|
||||||
|
ret = posix_spawn_file_actions_destroy(&file_actions);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawn_file_actions_destroy failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
posix_spawn_file_actions_dump(&file_actions);
|
||||||
|
|
||||||
|
ret = posix_spawnattr_destroy(&attr);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err("ERROR: posix_spawnattr_destroy failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
posix_spawnattr_dump(&attr);
|
||||||
|
|
||||||
|
mm_update(&g_mmstep, "after file_action/attr destruction");
|
||||||
|
|
||||||
|
/* Clean-up */
|
||||||
|
|
||||||
|
elf_uninitialize();
|
||||||
|
|
||||||
|
mm_update(&g_mmstep, "End-of-Test");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -83,11 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
|
|||||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
@touch .built
|
@touch .built
|
||||||
|
|
||||||
.context:
|
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||||
|
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
|
||||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||||
@touch $@
|
|
||||||
|
|
||||||
context: .context
|
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
|
||||||
|
else
|
||||||
|
context:
|
||||||
|
endif
|
||||||
|
|
||||||
.depend: Makefile $(SRCS)
|
.depend: Makefile $(SRCS)
|
||||||
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||||
|
|||||||
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
|
|||||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
@touch .built
|
@touch .built
|
||||||
|
|
||||||
.context:
|
|
||||||
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||||
|
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
|
||||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||||
@touch $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
context: .context
|
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
|
||||||
|
else
|
||||||
|
context:
|
||||||
|
endif
|
||||||
|
|
||||||
.depend: Makefile $(SRCS)
|
.depend: Makefile $(SRCS)
|
||||||
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||||
|
|||||||
@@ -83,11 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
|
|||||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||||
@touch .built
|
@touch .built
|
||||||
|
|
||||||
.context:
|
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||||
|
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
|
||||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||||
@touch $@
|
|
||||||
|
|
||||||
context: .context
|
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
|
||||||
|
else
|
||||||
|
context:
|
||||||
|
endif
|
||||||
|
|
||||||
.depend: Makefile $(SRCS)
|
.depend: Makefile $(SRCS)
|
||||||
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* apps/include/builtin.h
|
||||||
|
*
|
||||||
|
* Originally by:
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||||
|
* Author: Uros Platise <uros.platise@isotel.eu>
|
||||||
|
*
|
||||||
|
* With subsequent updates, modifications, and general maintenance by:
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __APPS_INCLUDE_BUILTIN_H
|
||||||
|
#define __APPS_INCLUDE_BUILTIN_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <nuttx/binfmt/builtin.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define EXTERN extern "C"
|
||||||
|
extern "C" {
|
||||||
|
#else
|
||||||
|
#define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: exec_builtin
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Executes builtin applications registered during 'make context' time.
|
||||||
|
* New application is run in a separate task context (and thread).
|
||||||
|
*
|
||||||
|
* Input Parameter:
|
||||||
|
* filename - Name of the linked-in binary to be started.
|
||||||
|
* argv - Argument list
|
||||||
|
* redirfile - If output if redirected, this parameter will be non-NULL
|
||||||
|
* and will provide the full path to the file.
|
||||||
|
* oflags - If output is redirected, this parameter will provide the
|
||||||
|
* open flags to use. This will support file replacement
|
||||||
|
* of appending to an existing file.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* This is an end-user function, so it follows the normal convention:
|
||||||
|
* Returns the PID of the exec'ed module. On failure, it.returns
|
||||||
|
* -1 (ERROR) and sets errno appropriately.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
EXTERN int exec_builtin(FAR const char *appname, FAR const char **argv,
|
||||||
|
FAR const char *redirfile, int oflags);
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __APPS_INCLUDE_BUILTIN_H */
|
||||||
@@ -73,4 +73,4 @@ depend: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_depend)
|
|||||||
|
|
||||||
clean: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_clean)
|
clean: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_clean)
|
||||||
|
|
||||||
distclean: clean $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_distclean)
|
distclean: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_distclean)
|
||||||
|
|||||||
@@ -108,7 +108,6 @@ context:
|
|||||||
depend: .depend
|
depend: .depend
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(call DELFILE, .context)
|
|
||||||
$(call DELFILE, .built)
|
$(call DELFILE, .built)
|
||||||
$(call CLEAN)
|
$(call CLEAN)
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
#
|
|
||||||
# For a description of the syntax of this configuration file,
|
|
||||||
# see misc/tools/kconfig-language.txt.
|
|
||||||
#
|
|
||||||
|
|
||||||
config NAMEDAPP
|
|
||||||
bool "Support named applications"
|
|
||||||
default n
|
|
||||||
---help---
|
|
||||||
Enable support for named applications. This features assigns a string
|
|
||||||
name to an application. This feature is also the underlying requirement
|
|
||||||
to support built-in applications in the NuttShell (NSH).
|
|
||||||
|
|
||||||
if NAMEDAPP
|
|
||||||
endif
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/* List of application requirements, generated during make context. */
|
||||||
|
{ "math_demo", SCHED_PRIORITY_DEFAULT, 8192, math_demo_main },
|
||||||
|
{ "control_demo", SCHED_PRIORITY_DEFAULT, 2048, control_demo_main },
|
||||||
|
{ "kalman_demo", SCHED_PRIORITY_MAX - 30, 2048, kalman_demo_main },
|
||||||
|
{ "reboot", SCHED_PRIORITY_DEFAULT, 2048, reboot_main },
|
||||||
|
{ "perf", SCHED_PRIORITY_DEFAULT, 2048, perf_main },
|
||||||
|
{ "top", SCHED_PRIORITY_DEFAULT - 10, 3000, top_main },
|
||||||
|
{ "boardinfo", SCHED_PRIORITY_DEFAULT, 2048, boardinfo_main },
|
||||||
|
{ "mixer", SCHED_PRIORITY_DEFAULT, 4096, mixer_main },
|
||||||
|
{ "eeprom", SCHED_PRIORITY_DEFAULT, 4096, eeprom_main },
|
||||||
|
{ "param", SCHED_PRIORITY_DEFAULT, 4096, param_main },
|
||||||
|
{ "bl_update", SCHED_PRIORITY_DEFAULT, 4096, bl_update_main },
|
||||||
|
{ "preflight_check", SCHED_PRIORITY_DEFAULT, 2048, preflight_check_main },
|
||||||
|
{ "delay_test", SCHED_PRIORITY_DEFAULT, 2048, delay_test_main },
|
||||||
|
{ "uorb", SCHED_PRIORITY_DEFAULT, 4096, uorb_main },
|
||||||
|
{ "mavlink", SCHED_PRIORITY_DEFAULT, 2048, mavlink_main },
|
||||||
|
{ "mavlink_onboard", SCHED_PRIORITY_DEFAULT, 2048, mavlink_onboard_main },
|
||||||
|
{ "gps", SCHED_PRIORITY_DEFAULT, 2048, gps_main },
|
||||||
|
{ "commander", SCHED_PRIORITY_MAX - 30, 2048, commander_main },
|
||||||
|
{ "sdlog", SCHED_PRIORITY_MAX - 30, 2048, sdlog_main },
|
||||||
|
{ "sensors", SCHED_PRIORITY_MAX-5, 4096, sensors_main },
|
||||||
|
{ "ardrone_interface", SCHED_PRIORITY_MAX - 15, 2048, ardrone_interface_main },
|
||||||
|
{ "multirotor_att_control", SCHED_PRIORITY_MAX - 15, 2048, multirotor_att_control_main },
|
||||||
|
{ "multirotor_pos_control", SCHED_PRIORITY_MAX - 25, 2048, multirotor_pos_control_main },
|
||||||
|
{ "fixedwing_att_control", SCHED_PRIORITY_MAX - 30, 2048, fixedwing_att_control_main },
|
||||||
|
{ "fixedwing_pos_control", SCHED_PRIORITY_MAX - 30, 2048, fixedwing_pos_control_main },
|
||||||
|
{ "position_estimator", SCHED_PRIORITY_DEFAULT, 4096, position_estimator_main },
|
||||||
|
{ "attitude_estimator_ekf", SCHED_PRIORITY_DEFAULT, 2048, attitude_estimator_ekf_main },
|
||||||
|
{ "ms5611", SCHED_PRIORITY_DEFAULT, 2048, ms5611_main },
|
||||||
|
{ "hmc5883", SCHED_PRIORITY_DEFAULT, 4096, hmc5883_main },
|
||||||
|
{ "mpu6000", SCHED_PRIORITY_DEFAULT, 4096, mpu6000_main },
|
||||||
|
{ "bma180", SCHED_PRIORITY_DEFAULT, 2048, bma180_main },
|
||||||
|
{ "l3gd20", SCHED_PRIORITY_DEFAULT, 2048, l3gd20_main },
|
||||||
|
{ "px4io", SCHED_PRIORITY_DEFAULT, 2048, px4io_main },
|
||||||
|
{ "blinkm", SCHED_PRIORITY_DEFAULT, 2048, blinkm_main },
|
||||||
|
{ "tone_alarm", SCHED_PRIORITY_DEFAULT, 2048, tone_alarm_main },
|
||||||
|
{ "adc", SCHED_PRIORITY_DEFAULT, 2048, adc_main },
|
||||||
|
{ "fmu", SCHED_PRIORITY_DEFAULT, 2048, fmu_main },
|
||||||
|
{ "hil", SCHED_PRIORITY_DEFAULT, 2048, hil_main },
|
||||||
|
{ "tests", SCHED_PRIORITY_DEFAULT, 12000, tests_main },
|
||||||
|
{ "sercon", SCHED_PRIORITY_DEFAULT, 2048, sercon_main },
|
||||||
|
{ "serdis", SCHED_PRIORITY_DEFAULT, 2048, serdis_main },
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/* List of application entry points, generated during make context. */
|
||||||
|
EXTERN int math_demo_main(int argc, char *argv[]);
|
||||||
|
EXTERN int control_demo_main(int argc, char *argv[]);
|
||||||
|
EXTERN int kalman_demo_main(int argc, char *argv[]);
|
||||||
|
EXTERN int reboot_main(int argc, char *argv[]);
|
||||||
|
EXTERN int perf_main(int argc, char *argv[]);
|
||||||
|
EXTERN int top_main(int argc, char *argv[]);
|
||||||
|
EXTERN int boardinfo_main(int argc, char *argv[]);
|
||||||
|
EXTERN int mixer_main(int argc, char *argv[]);
|
||||||
|
EXTERN int eeprom_main(int argc, char *argv[]);
|
||||||
|
EXTERN int param_main(int argc, char *argv[]);
|
||||||
|
EXTERN int bl_update_main(int argc, char *argv[]);
|
||||||
|
EXTERN int preflight_check_main(int argc, char *argv[]);
|
||||||
|
EXTERN int delay_test_main(int argc, char *argv[]);
|
||||||
|
EXTERN int uorb_main(int argc, char *argv[]);
|
||||||
|
EXTERN int mavlink_main(int argc, char *argv[]);
|
||||||
|
EXTERN int mavlink_onboard_main(int argc, char *argv[]);
|
||||||
|
EXTERN int gps_main(int argc, char *argv[]);
|
||||||
|
EXTERN int commander_main(int argc, char *argv[]);
|
||||||
|
EXTERN int sdlog_main(int argc, char *argv[]);
|
||||||
|
EXTERN int sensors_main(int argc, char *argv[]);
|
||||||
|
EXTERN int ardrone_interface_main(int argc, char *argv[]);
|
||||||
|
EXTERN int multirotor_att_control_main(int argc, char *argv[]);
|
||||||
|
EXTERN int multirotor_pos_control_main(int argc, char *argv[]);
|
||||||
|
EXTERN int fixedwing_att_control_main(int argc, char *argv[]);
|
||||||
|
EXTERN int fixedwing_pos_control_main(int argc, char *argv[]);
|
||||||
|
EXTERN int position_estimator_main(int argc, char *argv[]);
|
||||||
|
EXTERN int attitude_estimator_ekf_main(int argc, char *argv[]);
|
||||||
|
EXTERN int ms5611_main(int argc, char *argv[]);
|
||||||
|
EXTERN int hmc5883_main(int argc, char *argv[]);
|
||||||
|
EXTERN int mpu6000_main(int argc, char *argv[]);
|
||||||
|
EXTERN int bma180_main(int argc, char *argv[]);
|
||||||
|
EXTERN int l3gd20_main(int argc, char *argv[]);
|
||||||
|
EXTERN int px4io_main(int argc, char *argv[]);
|
||||||
|
EXTERN int blinkm_main(int argc, char *argv[]);
|
||||||
|
EXTERN int tone_alarm_main(int argc, char *argv[]);
|
||||||
|
EXTERN int adc_main(int argc, char *argv[]);
|
||||||
|
EXTERN int fmu_main(int argc, char *argv[]);
|
||||||
|
EXTERN int hil_main(int argc, char *argv[]);
|
||||||
|
EXTERN int tests_main(int argc, char *argv[]);
|
||||||
|
EXTERN int sercon_main(int argc, char *argv[]);
|
||||||
|
EXTERN int serdis_main(int argc, char *argv[]);
|
||||||
+4
-4
@@ -15,12 +15,12 @@ if NSH_LIBRARY
|
|||||||
config NSH_BUILTIN_APPS
|
config NSH_BUILTIN_APPS
|
||||||
bool "Enable built-in applications"
|
bool "Enable built-in applications"
|
||||||
default y
|
default y
|
||||||
depends on NAMEDAPP
|
depends on BUILTIN
|
||||||
---help---
|
---help---
|
||||||
Support external registered, "named" applications that can be
|
Support external registered, "built-in" applications that can be
|
||||||
executed from the NSH command line (see apps/README.txt for
|
executed from the NSH command line (see apps/README.txt for
|
||||||
more information). This options requires support for named applications
|
more information). This options requires support for builtin
|
||||||
(NAMEDAPP).
|
applications (BUILTIN).
|
||||||
|
|
||||||
menu "Disable Individual commands"
|
menu "Disable Individual commands"
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ CSRCS = nsh_init.c nsh_parse.c nsh_console.c nsh_fscmds.c nsh_ddcmd.c \
|
|||||||
nsh_proccmds.c nsh_mmcmds.c nsh_envcmds.c nsh_dbgcmds.c
|
nsh_proccmds.c nsh_mmcmds.c nsh_envcmds.c nsh_dbgcmds.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||||
CSRCS += nsh_apps.c
|
CSRCS += nsh_builtin.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_NSH_ROMFSETC),y)
|
ifeq ($(CONFIG_NSH_ROMFSETC),y)
|
||||||
@@ -130,7 +130,6 @@ clean:
|
|||||||
$(call CLEAN)
|
$(call CLEAN)
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
$(call DELFILE, .context)
|
|
||||||
$(call DELFILE, Make.dep)
|
$(call DELFILE, Make.dep)
|
||||||
$(call DELFILE, .depend)
|
$(call DELFILE, .depend)
|
||||||
|
|
||||||
|
|||||||
@@ -945,7 +945,7 @@ NSH-Specific Configuration Settings
|
|||||||
the configs/<board-name>/defconfig file:
|
the configs/<board-name>/defconfig file:
|
||||||
|
|
||||||
* CONFIG_NSH_BUILTIN_APPS
|
* CONFIG_NSH_BUILTIN_APPS
|
||||||
Support external registered, "named" applications that can be
|
Support external registered, "builtin" applications that can be
|
||||||
executed from the NSH command line (see apps/README.txt for
|
executed from the NSH command line (see apps/README.txt for
|
||||||
more information).
|
more information).
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -491,7 +491,8 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline);
|
|||||||
/* Application interface */
|
/* Application interface */
|
||||||
|
|
||||||
#ifdef CONFIG_NSH_BUILTIN_APPS
|
#ifdef CONFIG_NSH_BUILTIN_APPS
|
||||||
int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, FAR char **argv);
|
int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||||
|
FAR char **argv, FAR const char *redirfile, int oflags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Working directory support */
|
/* Working directory support */
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* apps/nshlib/nsh_apps.c
|
* apps/nshlib/nsh_builtin.c
|
||||||
|
*
|
||||||
|
* Originally by:
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
|
||||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||||
* Author: Uros Platise <uros.platise@isotel.eu>
|
* Author: Uros Platise <uros.platise@isotel.eu>
|
||||||
*
|
*
|
||||||
|
* With subsequent updates, modifications, and general maintenance by:
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011-2013 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
@@ -48,7 +54,8 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <apps/apps.h>
|
#include <nuttx/binfmt/builtin.h>
|
||||||
|
#include <apps/builtin.h>
|
||||||
|
|
||||||
#include "nsh.h"
|
#include "nsh.h"
|
||||||
#include "nsh_console.h"
|
#include "nsh_console.h"
|
||||||
@@ -84,13 +91,13 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nsh_execapp
|
* Name: nsh_builtin
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Attempt to execute the application task whose name is 'cmd'
|
* Attempt to execute the application task whose name is 'cmd'
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* <0 If exec_namedapp() fails, then the negated errno value
|
* <0 If exec_builtin() fails, then the negated errno value
|
||||||
* is returned.
|
* is returned.
|
||||||
* -1 (ERROR) if the application task corresponding to 'cmd' could not
|
* -1 (ERROR) if the application task corresponding to 'cmd' could not
|
||||||
* be started (possibly because it doesn not exist).
|
* be started (possibly because it doesn not exist).
|
||||||
@@ -104,8 +111,8 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||||
FAR char **argv)
|
FAR char **argv, FAR const char *redirfile, int oflags)
|
||||||
{
|
{
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
@@ -119,7 +126,7 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
|||||||
* applications.
|
* applications.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = exec_namedapp(cmd, (FAR const char **)argv);
|
ret = exec_builtin(cmd, (FAR const char **)argv, redirfile, oflags);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
/* The application was successfully started (but still blocked because
|
/* The application was successfully started (but still blocked because
|
||||||
@@ -191,7 +198,7 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
|||||||
#if !defined(CONFIG_SCHED_WAITPID) || !defined(CONFIG_NSH_DISABLEBG)
|
#if !defined(CONFIG_SCHED_WAITPID) || !defined(CONFIG_NSH_DISABLEBG)
|
||||||
{
|
{
|
||||||
struct sched_param param;
|
struct sched_param param;
|
||||||
sched_getparam(0, ¶m);
|
sched_getparam(ret, ¶m);
|
||||||
nsh_output(vtbl, "%s [%d:%d]\n", cmd, ret, param.sched_priority);
|
nsh_output(vtbl, "%s [%d:%d]\n", cmd, ret, param.sched_priority);
|
||||||
|
|
||||||
/* Backgrounded commands always 'succeed' as long as we can start
|
/* Backgrounded commands always 'succeed' as long as we can start
|
||||||
@@ -205,13 +212,13 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
|||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
|
|
||||||
/* If exec_namedapp() or waitpid() failed, then return the negated errno
|
/* If exec_builtin() or waitpid() failed, then return -1 (ERROR) with the
|
||||||
* value.
|
* errno value set appropriately.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
return -errno;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user