Merge NuttX r5527

This commit is contained in:
px4dev
2013-01-17 01:00:46 -08:00
228 changed files with 15512 additions and 1913 deletions
+50
View File
@@ -435,3 +435,53 @@
logic to find the absolute path to the program using the PATH variable.
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
View File
@@ -3,8 +3,8 @@
# see misc/tools/kconfig-language.txt.
#
menu "Named Applications"
source "$APPSDIR/namedapp/Kconfig"
menu "Built-In Applications"
source "$APPSDIR/builtin/Kconfig"
endmenu
menu "Examples"
+12 -3
View File
@@ -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
@echo "Register: $1"
@echo "{ \"$1\", $2, $3, $4 }," >> "$(APPDIR)/namedapp/namedapp_list.h"
@echo "EXTERN int $4(int argc, char *argv[]);" >> "$(APPDIR)/namedapp/namedapp_proto.h"
$(Q) echo "Register: $1"
$(Q) echo "{ \"$1\", $2, $3, $4 }," > "$(BUILTIN_REGISTRY)$(DELIM)$4.bdat"
$(Q) echo "int $4(int argc, char *argv[]);" > "$(BUILTIN_REGISTRY)$(DELIM)$4.pdat"
$(Q) touch "$(BUILTIN_REGISTRY)$(DELIM).updated"
endef
+16 -26
View File
@@ -45,14 +45,11 @@ APPDIR = ${shell pwd}
# action. It is created by the configured appconfig file (a copy of which
# appears in this directory as .config)
# 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.
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 graphics interpreters modbus builtin nshlib netutils system
# There are two different mechanisms for obtaining the list of configured
# directories:
@@ -73,20 +70,20 @@ SUBDIRS = namedapp/ $(filter-out ./ ./namedapp/ ./examples/,$(ALL_SUBDIRS))
ifeq ($(CONFIG_NUTTX_NEWCONFIG),y)
# namedapp/Make.defs must be included first
# builtin/Make.defs must be included first
-include namedapp/Make.defs
-include examples/Make.defs
-include graphics/Make.defs
-include interpreters/Make.defs
-include modbus/Make.defs
-include netutils/Make.defs
-include nshlib/Make.defs
-include system/Make.defs
include builtin/Make.defs
include examples/Make.defs
include graphics/Make.defs
include interpreters/Make.defs
include modbus/Make.defs
include netutils/Make.defs
include nshlib/Make.defs
include system/Make.defs
# INSTALLED_APPS is the list of currently available application directories. It
# 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.
INSTALLED_APPS =
@@ -98,10 +95,10 @@ else
# INSTALLED_APPS is the list of currently available application directories. It
# 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.
INSTALLED_APPS = namedapp
INSTALLED_APPS = builtin
endif
# Create the list of available applications (INSTALLED_APPS)
@@ -139,21 +136,16 @@ $(INSTALLED_APPS):
$(BIN): $(INSTALLED_APPS)
.context:
context:
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
$(Q) for %%G in ($(INSTALLED_APPS)) do ( \
if exist %%G\.context del /f /q %%G\.context \
$(MAKE) -C %%G TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" context \
)
else
$(Q) for dir in $(INSTALLED_APPS) ; do \
rm -f $$dir/.context ; \
$(MAKE) -C $$dir TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" context ; \
done
endif
$(Q) touch $@
context: .context
.depend: context Makefile $(SRCS)
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
@@ -184,13 +176,12 @@ endif
$(call DELFILE, $(BIN))
$(call CLEAN)
distclean: # clean
distclean:
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
$(Q) for %%G in ($(SUBDIRS)) do ( \
$(MAKE) -C %%G distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" \
)
$(call DELFILE, .config)
$(call DELFILE, .context)
$(call DELFILE, .depend)
$(Q) ( if exist external ( \
echo ********************************************************" \
@@ -202,7 +193,6 @@ else
$(MAKE) -C $$dir distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"; \
done
$(call DELFILE, .config)
$(call DELFILE, .context)
$(call DELFILE, .depend)
$(Q) ( if [ -e external ]; then \
echo "********************************************************"; \
+104 -42
View File
@@ -6,26 +6,25 @@ Contents
General
Directory Location
Named Applications
Named Startup main() function
Built-In Applications
NuttShell (NSH) Built-In Commands
Synchronous Built-In Commands
Application Configuration File
Example Named Application
Example Built-In Application
Building NuttX with Board-Specific Pieces Outside the Source Tree
General
-------
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"
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
------------------
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/
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:
.
@@ -47,14 +46,14 @@ ways to do that:
path to the application directory on the configuration command line
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.
In this case, application entry points with their requirements are gathered
together in two files:
- namedapp/namedapp_proto.h Entry points, prototype function
- namedapp/namedapp_list.h Application specific information and requirements
- builtin/builtin_proto.h Entry points, prototype function
- builtin/builtin_list.h Application specific information and requirements
The build occurs in several phases as different build targets are executed:
(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:
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
---------------------------------
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
a seamless method invoking the applications, when the following option is
enabled in the NuttX configuration file:
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
prompt, you will see a list of the registered commands.
@@ -96,11 +95,11 @@ after the NSH command.
Application Configuration File
------------------------------
A special configuration file is used to configure which applications
are to be included in the build. The source for this file is
configs/<board>/<configuration>/appconfig. The existence of the appconfig
file in the board configuration directory is sufficient to enable building
of applications.
The old-style NuttX configuration uses a special configuration file is
used to configure which applications are to be included in the build.
The source for this file is configs/<board>/<configuration>/appconfig.
The existence of the appconfig file in the board configuration directory\
is sufficient to enable building of applications.
The appconfig file is copied into the apps/ directory as .config when
NuttX is configured. .config is included in the toplevel apps/Makefile.
@@ -109,38 +108,101 @@ CONFIGURED_APPS list like:
CONFIGURED_APPS += examples/hello system/poweroff
Named Start-Up main() function
------------------------------
A named application can even be used as the main, start-up entry point
into your embedded software. When the user defines this option in
the NuttX configuration file:
The new NuttX configuration uses kconfig-frontends tools and only the
NuttX .config file. The new configuration is indicated by the existence
of the definition CONFIG_NUTTX_NEWCONFIG=y in the NuttX .config file.
If CONFIG_NUTTX_NEWCONFIG is defined, then the Makefile will:
CONFIG_BUILTIN_APP_START=<application name>
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:
- Assume that there is no apps/.config file and will instead
- Include Make.defs files from each of the subdirectories.
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
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:
1. create sub-directory as: appname
2. provide entry point: appname_main()
3. set the requirements in the file: Makefile, specially the lines:
Old configuration method:
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 ..
1. Create sub-directory as: appname
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
-----------------------------------------------------------------
+17
View File
@@ -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
#
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
@@ -34,7 +34,7 @@
#
############################################################################
ifeq ($(CONFIG_NAMEDAPP),y)
CONFIGURED_APPS += namedapp
ifeq ($(CONFIG_BUILTIN),y)
CONFIGURED_APPS += builtin
endif
@@ -1,5 +1,5 @@
############################################################################
# apps/nshlib/Makefile
# apps/builtin/Makefile
#
# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
@@ -33,20 +33,13 @@
#
############################################################################
-include $(TOPDIR)/.config
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
# NSH Library
# Source and object files
ASRCS =
CSRCS = namedapp.c exec_namedapp.c
ifeq ($(CONFIG_APPS_BINDIR),y)
CSRCS += binfs.c
endif
CSRCS = builtin.c exec_builtin.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
@@ -70,7 +63,7 @@ VPATH =
# Build Targets
all: .built
.PHONY: .context context depend clean distclean
.PHONY: context depend clean distclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
@@ -78,33 +71,60 @@ $(AOBJS): %$(OBJEXT): %.S
$(COBJS): %$(OBJEXT): %.c
$(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))
$(Q) touch .built
.context:
@echo "/* List of application requirements, generated during make context. */" > namedapp_list.h
@echo "/* List of application entry points, generated during make context. */" > namedapp_proto.h
$(Q) touch $@
context:
$(Q) $(MAKE) -C registry context TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
context: .context
.depend: Makefile $(SRCS)
.depend: Makefile $(SRCS) builtin_list.h builtin_proto.h
$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
$(Q) touch $@
depend: .depend
clean:
$(Q) $(MAKE) -C registry clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
$(call DELFILE, .built)
$(call CLEAN)
distclean: clean
$(call DELFILE, .context)
$(Q) $(MAKE) -C registry distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
$(call DELFILE, namedapp_list.h)
$(call DELFILE, namedapp_proto.h)
$(call DELFILE, builtin_list.h)
$(call DELFILE, builtin_proto.h)
-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 Gregory Nutt. All rights reserved.
@@ -40,7 +40,8 @@
****************************************************************************/
#include <nuttx/config.h>
#include <apps/apps.h>
#include <nuttx/binfmt/builtin.h>
/****************************************************************************
* Private Types
@@ -62,11 +63,11 @@ extern "C" {
#define EXTERN extern
#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 }
};
@@ -88,9 +89,9 @@ const struct namedapp_s namedapps[] =
* 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;
}
+423
View File
@@ -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, &param);
}
#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, &param);
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;
}
+61
View File
@@ -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)
+1 -1
View File
@@ -39,6 +39,7 @@ source "$APPSDIR/examples/pashello/Kconfig"
source "$APPSDIR/examples/pipe/Kconfig"
source "$APPSDIR/examples/poll/Kconfig"
source "$APPSDIR/examples/pwm/Kconfig"
source "$APPSDIR/examples/posix_spawn/Kconfig"
source "$APPSDIR/examples/qencoder/Kconfig"
source "$APPSDIR/examples/relays/Kconfig"
source "$APPSDIR/examples/rgmp/Kconfig"
@@ -58,5 +59,4 @@ source "$APPSDIR/examples/usbterm/Kconfig"
source "$APPSDIR/examples/watchdog/Kconfig"
source "$APPSDIR/examples/wget/Kconfig"
source "$APPSDIR/examples/wgetjson/Kconfig"
source "$APPSDIR/examples/wlan/Kconfig"
source "$APPSDIR/examples/xmlrpc/Kconfig"
+4 -4
View File
@@ -182,6 +182,10 @@ ifeq ($(CONFIG_EXAMPLES_PWM),y)
CONFIGURED_APPS += examples/pwm
endif
ifeq ($(CONFIG_EXAMPLES_POSIXSPAWN),y)
CONFIGURED_APPS += examples/posix_spawn
endif
ifeq ($(CONFIG_EXAMPLES_QENCODER),y)
CONFIGURED_APPS += examples/qencoder
endif
@@ -254,10 +258,6 @@ ifeq ($(CONFIG_EXAMPLES_WGETJSON),y)
CONFIGURED_APPS += examples/wgetjson
endif
ifeq ($(CONFIG_EXAMPLES_WLAN),y)
CONFIGURED_APPS += examples/wlan
endif
ifeq ($(CONFIG_EXAMPLES_XMLRPC),y)
CONFIGURED_APPS += examples/xmlrpc
endif
+7 -9
View File
@@ -40,9 +40,9 @@
SUBDIRS = adc buttons can cdcacm composite cxxtest dhcpd discover elf ftpc
SUBDIRS += ftpd hello helloxx hidkbd igmp json keypadtest lcdrw mm modbus mount
SUBDIRS += nettest nsh null nx nxconsole nxffs nxflat nxhello nximage
SUBDIRS += nxlines nxtext ostest pashello pipe poll pwm qencoder relays
SUBDIRS += rgmp romfs serloop telnetd thttpd tiff touchscreen udp uip
SUBDIRS += usbserial sendmail usbstorage usbterm watchdog wget wgetjson wlan
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
# context setup for a variety of reasons, but the most common is because
@@ -57,13 +57,11 @@ SUBDIRS += usbserial sendmail usbstorage usbterm watchdog wget wgetjson wlan
CNTXTDIRS = pwm
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 composite cxxtest dhcpd discover ftpd hello json
CNTXTDIRS += keypadtestmodbus nettest nxlines relays qencoder telnetd watchdog
CNTXTDIRS += wgetjson
endif
ifeq ($(CONFIG_EXAMPLES_HELLO_BUILTIN),y)
CNTXTDIRS += hello
endif
ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y)
CNTXTDIRS += helloxx
endif
@@ -120,7 +118,7 @@ depend: $(foreach SDIR, $(SUBDIRS), $(SDIR)_depend)
clean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_clean)
distclean: clean $(foreach SDIR, $(SUBDIRS), $(SDIR)_distclean)
distclean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_distclean)
-include Make.dep
+94 -8
View File
@@ -329,10 +329,10 @@ examples/elf
each program in the ROMFS file system is executed. Requires CONFIG_ELF.
Other configuration options:
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
that will hold the ROMFS file system containing the ELF executables to be
tested. Default: 0
CONFIG_EXAMPLES_ELF_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_ELF_DEVPATH - The path to the ROMFS block driver device. This
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.
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
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
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.
examples/helloxx
@@ -540,9 +540,21 @@ examples/hidkbd
This is a simple test to debug/verify the USB host HID keyboard class
driver.
CONFIG_EXAMPLES_HIDKBD_DEFPRIO - Priority of "waiter" thread.
CONFIG_EXAMPLES_HIDKBD_STACKSIZE - Stacksize of "waiter" thread.
CONFIG_EXAMPLES_HIDKBD_DEFPRIO - Priority of "waiter" thread. Default:
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
^^^^^^^^^^^^^
@@ -1190,6 +1202,80 @@ examples/poll
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
^^^^^^^^^^^^
+5 -4
View File
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
endif
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+5 -4
View File
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
endif
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+5 -4
View File
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
endif
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+9 -4
View File
@@ -87,12 +87,17 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@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,$(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)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+6 -5
View File
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
.context:
ifeq ($(CONFIG_EXAMPLES_HELLO_BUILTIN),y)
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
endif
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+5 -4
View File
@@ -100,13 +100,14 @@ $(CXXOBJS): %$(OBJEXT): %.cxx
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
.context:
ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
endif
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+13 -4
View File
@@ -52,6 +52,10 @@ ifeq ($(CONFIG_ARCH_FPU),y)
CSRCS += fpu.c
endif
ifeq ($(CONFIG_SCHED_WAITPID),y)
CSRCS += waitpid.c
endif
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
CSRCS += cancel.c cond.c mutex.c sem.c barrier.c
ifneq ($(CONFIG_RR_INTERVAL),0)
@@ -84,6 +88,10 @@ ifneq ($(CONFIG_DISABLE_POSIX_TIMERS),y)
CSRCS += posixtimer.c
endif
ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
CSRCS += vfork.c
endif
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
@@ -127,13 +135,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
.context:
ifeq ($(CONFIG_EXAMPLES_OSTEST_BUILTIN),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
endif
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+29 -17
View File
@@ -105,71 +105,83 @@
/* dev_null.c ***************************************************************/
extern int dev_null(void);
int dev_null(void);
/* fpu.c ********************************************************************/
extern void fpu_test(void);
void fpu_test(void);
/* waitpid.c ****************************************************************/
#ifdef CONFIG_SCHED_WAITPID
int waitpid_test(void);
#endif
/* mutex.c ******************************************************************/
extern void mutex_test(void);
void mutex_test(void);
/* rmutex.c ******************************************************************/
extern void recursive_mutex_test(void);
void recursive_mutex_test(void);
/* sem.c ********************************************************************/
extern void sem_test(void);
void sem_test(void);
/* cond.c *******************************************************************/
extern void cond_test(void);
void cond_test(void);
/* mqueue.c *****************************************************************/
extern void mqueue_test(void);
void mqueue_test(void);
/* timedmqueue.c ************************************************************/
extern void timedmqueue_test(void);
void timedmqueue_test(void);
/* cancel.c *****************************************************************/
extern void cancel_test(void);
void cancel_test(void);
/* timedwait.c **************************************************************/
extern void timedwait_test(void);
void timedwait_test(void);
/* sighand.c ****************************************************************/
extern void sighand_test(void);
void sighand_test(void);
/* posixtimers.c ************************************************************/
extern void timer_test(void);
void timer_test(void);
/* roundrobin.c *************************************************************/
extern void rr_test(void);
void rr_test(void);
/* barrier.c ****************************************************************/
extern void barrier_test(void);
void barrier_test(void);
/* 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
* priority inheritance
*/
#if defined(CONFIG_DEBUG) && defined(CONFIG_PRIORITY_INHERITANCE) && defined(CONFIG_SEM_PHDEBUG)
extern void sem_enumholders(FAR sem_t *sem);
extern int sem_nfreeholders(void);
void sem_enumholders(FAR sem_t *sem);
int sem_nfreeholders(void);
#else
# define sem_enumholders(sem)
# define sem_nfreeholders()
+14
View File
@@ -301,6 +301,14 @@ static int user_main(int argc, char *argv[])
check_test_memory_usage();
#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
/* Verify pthreads and pthread mutex */
@@ -409,6 +417,11 @@ static int user_main(int argc, char *argv[])
check_test_memory_usage();
#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
* user_main exits. These should not be identical, but should
* 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);
#endif
}
printf("user_main: Exitting\n");
return 0;
}
+63
View File
@@ -54,12 +54,37 @@ static sem_t sem;
static bool sigreceived = 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)
{
sigset_t oldset;
sigset_t allsigs;
int status;
/* Use of printf in a signal handler is NOT safe! It can cause deadlocks! */
printf("wakeup_action: Received signal %d\n" , signo);
sigreceived = true;
@@ -186,6 +211,11 @@ static int waiter_main(int argc, char *argv[])
void sighand_test(void)
{
#ifdef CONFIG_SCHED_HAVE_PARENT
struct sigaction act;
struct sigaction oact;
sigset_t sigset;
#endif
struct sched_param param;
union sigval sigvalue;
pid_t waiterpid;
@@ -195,6 +225,32 @@ void sighand_test(void)
printf("sighand_test: Initializing semaphore to 0\n" );
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 */
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" );
}
/* 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" );
FFLUSH();
}
+103
View File
@@ -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;
}
+269
View File
@@ -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 */
+29
View File
@@ -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
+130
View File
@@ -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
View File
@@ -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.
+460
View File
@@ -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;
}
+6 -3
View File
@@ -83,11 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+5 -4
View File
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
endif
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+6 -3
View File
@@ -83,11 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+111
View File
@@ -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 */
+1 -1
View File
@@ -73,4 +73,4 @@ depend: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_depend)
clean: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_clean)
distclean: clean $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_distclean)
distclean: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_distclean)
-1
View File
@@ -108,7 +108,6 @@ context:
depend: .depend
clean:
$(call DELFILE, .context)
$(call DELFILE, .built)
$(call CLEAN)
-15
View File
@@ -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
+4 -4
View File
@@ -15,12 +15,12 @@ if NSH_LIBRARY
config NSH_BUILTIN_APPS
bool "Enable built-in applications"
default y
depends on NAMEDAPP
depends on BUILTIN
---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
more information). This options requires support for named applications
(NAMEDAPP).
more information). This options requires support for builtin
applications (BUILTIN).
menu "Disable Individual commands"
+1 -2
View File
@@ -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
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
CSRCS += nsh_apps.c
CSRCS += nsh_builtin.c
endif
ifeq ($(CONFIG_NSH_ROMFSETC),y)
@@ -130,7 +130,6 @@ clean:
$(call CLEAN)
distclean: clean
$(call DELFILE, .context)
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
+1 -1
View File
@@ -945,7 +945,7 @@ NSH-Specific Configuration Settings
the configs/<board-name>/defconfig file:
* 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
more information).
+2 -1
View File
@@ -491,7 +491,8 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline);
/* Application interface */
#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
/* 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.
* 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
* modification, are permitted provided that the following conditions
* are met:
@@ -48,7 +54,8 @@
#include <errno.h>
#include <string.h>
#include <apps/apps.h>
#include <nuttx/binfmt/builtin.h>
#include <apps/builtin.h>
#include "nsh.h"
#include "nsh_console.h"
@@ -84,13 +91,13 @@
****************************************************************************/
/****************************************************************************
* Name: nsh_execapp
* Name: nsh_builtin
*
* Description:
* Attempt to execute the application task whose name is 'cmd'
*
* Returned Value:
* <0 If exec_namedapp() fails, then the negated errno value
* <0 If exec_builtin() fails, then the negated errno value
* is returned.
* -1 (ERROR) if the application task corresponding to 'cmd' could not
* 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,
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)
{
int ret = OK;
@@ -119,7 +126,7 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
* applications.
*/
ret = exec_namedapp(cmd, (FAR const char **)argv);
ret = exec_builtin(cmd, (FAR const char **)argv, redirfile, oflags);
if (ret >= 0)
{
/* 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)
{
struct sched_param param;
sched_getparam(0, &param);
sched_getparam(ret, &param);
nsh_output(vtbl, "%s [%d:%d]\n", cmd, ret, param.sched_priority);
/* 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();
/* If exec_namedapp() or waitpid() failed, then return the negated errno
* value.
/* If exec_builtin() or waitpid() failed, then return -1 (ERROR) with the
* errno value set appropriately.
*/
if (ret < 0)
{
return -errno;
return ERROR;
}
return ret;
File diff suppressed because it is too large Load Diff
+56 -23
View File
@@ -45,10 +45,13 @@
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/fs/nfs.h>
#include "nsh.h"
#include "nsh_console.h"
@@ -128,9 +131,9 @@ static int mount_handler(FAR const char *mountpoint,
break;
#endif
#ifdef CONFIG_APPS_BINDIR
#ifdef CONFIG_FS_BINFS
case BINFS_MAGIC:
fstype = "bindir";
fstype = "binfs";
break;
#endif
@@ -195,9 +198,11 @@ int cmd_df(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
defined(CONFIG_FS_READABLE) && !defined(CONFIG_NSH_DISABLE_MOUNT)
int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
FAR char *source;
FAR char *target;
FAR char *filesystem = NULL;
FAR const char *source;
FAR char *fullsource;
FAR const char *target;
FAR char *fulltarget;
FAR const char *filesystem = NULL;
bool badarg = false;
int option;
int ret;
@@ -245,21 +250,34 @@ int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
return ERROR;
}
/* There are two required arguments after the options: the source and target
* paths.
/* There may be one or two required arguments after the options: the source
* and target paths. Some file systems do not require the source parameter
* so if there is only one parameter left, it must be the target.
*/
if (optind + 2 < argc)
{
nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
return ERROR;
}
else if (optind + 2 > argc)
if (optind >= argc)
{
nsh_output(vtbl, g_fmtargrequired, argv[0]);
return ERROR;
}
source = NULL;
target = argv[optind];
optind++;
if (optind < argc)
{
source = target;
target = argv[optind];
optind++;
if (optind < argc)
{
nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
return ERROR;
}
}
/* While the above parsing for the -t argument looks nice, the -t argument
* not really optional.
*/
@@ -274,29 +292,44 @@ int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
* working directory.
*/
source = nsh_getfullpath(vtbl, argv[optind]);
if (!source)
fullsource = NULL;
fulltarget = NULL;
if (source)
{
return ERROR;
fullsource = nsh_getfullpath(vtbl, source);
if (!fullsource)
{
return ERROR;
}
}
target = nsh_getfullpath(vtbl, argv[optind+1]);
if (!target)
fulltarget = nsh_getfullpath(vtbl, target);
if (!fulltarget)
{
nsh_freefullpath(source);
return ERROR;
ret = ERROR;
goto errout;
}
/* Perform the mount */
ret = mount(source, target, filesystem, 0, NULL);
ret = mount(fullsource, fulltarget, filesystem, 0, NULL);
if (ret < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
}
nsh_freefullpath(source);
nsh_freefullpath(target);
errout:
if (fullsource)
{
nsh_freefullpath(fullsource);
}
if (fulltarget)
{
nsh_freefullpath(fulltarget);
}
return ret;
}
#endif
+1
View File
@@ -67,6 +67,7 @@
#if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \
!defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS)
# include <apps/netutils/uiplib.h>
# include <apps/netutils/resolv.h>
#endif
#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0

Some files were not shown because too many files have changed in this diff Show More