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

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.

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"

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

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 "********************************************************"; \

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
apps/builtin/Kconfig Normal file
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

View File

@@ -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

View File

@@ -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

View File

@@ -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
apps/builtin/exec_builtin.c Normal file
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;
}

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)

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"

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

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

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
^^^^^^^^^^^^

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

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

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

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

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

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

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

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()

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;
}

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();
}

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;
}

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 */

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

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

View File

@@ -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)

View File

@@ -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;
}

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);"

View File

@@ -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;
}

View File

@@ -0,0 +1,2 @@
Now is the time for all good men to come to the aid of their party.

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;
}

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

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

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
apps/include/builtin.h Normal file
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 */

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)

View File

@@ -108,7 +108,6 @@ context:
depend: .depend
clean:
$(call DELFILE, .context)
$(call DELFILE, .built)
$(call CLEAN)

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

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"

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)

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).

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 */

View File

@@ -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;

538
apps/nshlib/nsh_codeccmd.c Normal file
View File

@@ -0,0 +1,538 @@
/****************************************************************************
* apps/nshlib/nsh_codeccmd.c
*
* This file is part of NuttX, contributed by Darcy Gong
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Author: Darcy Gong 2012-10-30
*
* 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>
#ifdef CONFIG_NETUTILS_CODECS
#include <sys/stat.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sched.h>
#include <fcntl.h>
#include <libgen.h>
#include <errno.h>
#include <debug.h>
#if defined(CONFIG_NSH_DISABLE_URLENCODE) && defined(CONFIG_NSH_DISABLE_URLDECODE)
# undef CONFIG_CODECS_URLCODE
#endif
#ifdef CONFIG_CODECS_URLCODE
#include <apps/netutils/urldecode.h>
#endif
#if defined(CONFIG_NSH_DISABLE_BASE64ENC) && defined(CONFIG_NSH_DISABLE_BASE64ENC)
# undef CONFIG_CODECS_BASE64
#endif
#ifdef CONFIG_CODECS_BASE64
#include <apps/netutils/base64.h>
#endif
#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
#include <apps/netutils/md5.h>
#endif
#include "nsh.h"
#include "nsh_console.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_NSH_CODECS_BUFSIZE
# define CONFIG_NSH_CODECS_BUFSIZE 128
#endif
#define CODEC_MODE_URLENCODE 1
#define CODEC_MODE_URLDECODE 2
#define CODEC_MODE_BASE64ENC 3
#define CODEC_MODE_BASE64DEC 4
#define CODEC_MODE_HASH_MD5 5
/****************************************************************************
* Private Types
****************************************************************************/
typedef void (*codec_callback_t)(FAR char *src_buff, int src_buff_len,
FAR char *dst_buff, FAR int *dst_buff_len,
int mode);
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: urlencode_cb
****************************************************************************/
#if defined(CONFIG_CODECS_URLCODE) && !defined(CONFIG_NSH_DISABLE_URLENCODE)
static void urlencode_cb(FAR char *src_buff, int src_buff_len,
FAR char *dst_buff, FAR int *dst_buff_len, int mode)
{
urlencode(src_buff,src_buff_len,dst_buff,dst_buff_len);
}
#endif
/****************************************************************************
* Name: urldecode_cb
****************************************************************************/
#if defined(CONFIG_CODECS_URLCODE) && !defined(CONFIG_NSH_DISABLE_URLDECODE)
static void urldecode_cb(FAR char *src_buff, int src_buff_len, FAR char *dst_buff,
FAR int *dst_buff_len, int mode)
{
urldecode(src_buff,src_buff_len,dst_buff,dst_buff_len);
}
#endif
/****************************************************************************
* Name: b64enc_cb
****************************************************************************/
#if defined(CONFIG_CODECS_BASE64) && !defined(CONFIG_NSH_DISABLE_BASE64ENC)
static void b64enc_cb(FAR char *src_buff, int src_buff_len, FAR char *dst_buff,
FAR int *dst_buff_len, int mode)
{
if (mode == 0)
{
//dst_buff =
base64_encode((unsigned char *)src_buff, src_buff_len,
(unsigned char *)dst_buff, (size_t *)dst_buff_len);
}
else
{
//dst_buff =
base64w_encode((unsigned char *)src_buff, src_buff_len,
(unsigned char *)dst_buff, (size_t *)dst_buff_len);
}
}
#endif
/****************************************************************************
* Name: b64dec_cb
****************************************************************************/
#if defined(CONFIG_CODECS_BASE64) && !defined(CONFIG_NSH_DISABLE_BASE64DEC)
static void b64dec_cb(FAR char *src_buff, int src_buff_len, FAR char *dst_buff,
FAR int *dst_buff_len, int mode)
{
if (mode == 0)
{
//dst_buff =
base64_decode((unsigned char *)src_buff, src_buff_len,
(unsigned char *)dst_buff, (size_t *)dst_buff_len);
}
else
{
//dst_buff =
base64w_decode((unsigned char *)src_buff, src_buff_len,
(unsigned char *)dst_buff,(size_t *)dst_buff_len);
}
}
#endif
/****************************************************************************
* Name: md5_cb
****************************************************************************/
#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
static void md5_cb(FAR char *src_buff, int src_buff_len, FAR char *dst_buff,
FAR int *dst_buff_len, int mode)
{
MD5Update((MD5_CTX *)dst_buff, (unsigned char *)src_buff, src_buff_len);
}
#endif
/****************************************************************************
* Name: calc_codec_buffsize
****************************************************************************/
static int calc_codec_buffsize(int src_buffsize, uint8_t mode)
{
switch (mode)
{
case CODEC_MODE_URLENCODE:
return src_buffsize*3+1;
case CODEC_MODE_URLDECODE:
return src_buffsize+1;
case CODEC_MODE_BASE64ENC:
return ((src_buffsize + 2)/ 3 * 4)+1;
case CODEC_MODE_BASE64DEC:
return (src_buffsize / 4 * 3 + 2)+1;
case CODEC_MODE_HASH_MD5:
return 32+1;
default:
return src_buffsize+1;
}
}
/****************************************************************************
* Name: cmd_codecs_proc
****************************************************************************/
static int cmd_codecs_proc(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv,
uint8_t mode, codec_callback_t func)
{
#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
static const unsigned char hex_chars[] = "0123456789abcdef";
MD5_CTX ctx;
unsigned char mac[16];
char *pSrc;
char *pDest;
#endif
char *localfile = NULL;
char *src_buffer = NULL;
char *buffer = NULL;
char *fullpath = NULL;
const char *fmt;
char *s_data;
bool badarg = false;
bool is_file = false;
bool is_websafe=false;
int option;
int fd = -1;
int buff_len = 0;
int src_buff_len = 0;
int i = 0;
int ret = OK;
/* Get the command options */
while ((option = getopt(argc, argv, ":fw")) != ERROR)
{
switch (option)
{
case 'f':
is_file = true;
break;
#ifdef CONFIG_CODECS_BASE64
case 'w':
is_websafe = true;
if (!(mode == CODEC_MODE_BASE64ENC || mode == CODEC_MODE_BASE64DEC))
{
badarg = true;
}
break;
#endif
case ':':
nsh_output(vtbl, g_fmtargrequired, argv[0]);
badarg = true;
break;
case '?':
default:
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
badarg = true;
break;
}
}
/* If a bad argument was encountered, then return without processing the command */
if (badarg)
{
return ERROR;
}
/* There should be exactly on parameter left on the command-line */
if (optind == argc-1)
{
s_data = argv[optind];
}
else if (optind >= argc)
{
fmt = g_fmttoomanyargs;
goto errout;
}
else
{
fmt = g_fmtargrequired;
goto errout;
}
#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
if (mode == CODEC_MODE_HASH_MD5)
{
MD5Init(&ctx);
}
#endif
if (is_file)
{
/* Get the local file name */
localfile = s_data;
/* Get the full path to the local file */
fullpath = nsh_getfullpath(vtbl, localfile);
/* Open the local file for writing */
fd = open(fullpath, O_RDONLY|O_TRUNC, 0644);
if (fd < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
ret = ERROR;
goto exit;
}
src_buffer = malloc(CONFIG_NSH_CODECS_BUFSIZE+2);
#if defined(CONFIG_CODECS_BASE64) && !defined(CONFIG_NSH_DISABLE_BASE64ENC)
if (mode == CODEC_MODE_BASE64ENC)
{
src_buff_len = CONFIG_NSH_CODECS_BUFSIZE / 3 * 3;
}
else
#endif
{
src_buff_len = CONFIG_NSH_CODECS_BUFSIZE;
}
buff_len = calc_codec_buffsize(src_buff_len+2, mode);
buffer = malloc(buff_len);
while(true)
{
memset(src_buffer, 0, src_buff_len+2);
ret=read(fd, src_buffer, src_buff_len);
if (ret < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
ret = ERROR;
goto exit;
}
else if(ret==0)
{
break;
}
#if defined(CONFIG_CODECS_URLCODE) && !defined(CONFIG_NSH_DISABLE_URLDECODE)
if (mode == CODEC_MODE_URLDECODE)
{
if (src_buffer[src_buff_len-1]=='%')
{
ret += read(fd,&src_buffer[src_buff_len],2);
}
else if (src_buffer[src_buff_len-2]=='%')
{
ret += read(fd,&src_buffer[src_buff_len],1);
}
}
#endif
memset(buffer, 0, buff_len);
if (func)
{
#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
if (mode == CODEC_MODE_HASH_MD5)
{
func(src_buffer, ret, (char *)&ctx, &buff_len,0);
}
else
#endif
{
func(src_buffer, ret, buffer, &buff_len,(is_websafe)?1:0);
nsh_output(vtbl, "%s", buffer);
}
}
buff_len = calc_codec_buffsize(src_buff_len+2, mode);
}
#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
if (mode == CODEC_MODE_HASH_MD5)
{
MD5Final(mac, &ctx);
pSrc = (char *)&mac;
pDest = buffer;
for(i=0;i<16;i++,pSrc++)
{
*pDest++ = hex_chars[(*pSrc) >> 4];
*pDest++ = hex_chars[(*pSrc) & 0x0f];
}
*pDest='\0';
nsh_output(vtbl, "%s\n", buffer);
}
#endif
ret = OK;
goto exit;
}
else
{
src_buffer = s_data;
src_buff_len = strlen(s_data);
buff_len = calc_codec_buffsize(src_buff_len, mode);
buffer = malloc(buff_len);
buffer[0]=0;
if (!buffer)
{
fmt = g_fmtcmdoutofmemory;
goto errout;
}
memset(buffer, 0, buff_len);
if (func)
{
#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
if (mode == CODEC_MODE_HASH_MD5)
{
func(src_buffer, src_buff_len, (char *)&ctx, &buff_len, 0);
MD5Final(mac, &ctx);
pSrc = (char *)&mac;
pDest = buffer;
for(i=0;i<16;i++,pSrc++)
{
*pDest++ = hex_chars[(*pSrc) >> 4];
*pDest++ = hex_chars[(*pSrc) & 0x0f];
}
*pDest='\0';
}
else
#endif
{
func(src_buffer, src_buff_len, buffer, &buff_len,(is_websafe)?1:0);
}
}
nsh_output(vtbl, "%s\n",buffer);
src_buffer = NULL;
goto exit;
}
exit:
if (fd >= 0)
{
close(fd);
}
if (fullpath)
{
free(fullpath);
}
if (src_buffer)
{
free(src_buffer);
}
if (buffer)
{
free(buffer);
}
return ret;
errout:
nsh_output(vtbl, fmt, argv[0]);
ret = ERROR;
goto exit;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: cmd_urlencode
****************************************************************************/
#if defined(CONFIG_CODECS_URLCODE) && !defined(CONFIG_NSH_DISABLE_URLENCODE)
int cmd_urlencode(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
return cmd_codecs_proc(vtbl, argc, argv, CODEC_MODE_URLENCODE, urlencode_cb);
}
#endif
/****************************************************************************
* Name: cmd_urldecode
****************************************************************************/
#if defined(CONFIG_CODECS_URLCODE) && !defined(CONFIG_NSH_DISABLE_URLDECODE)
int cmd_urldecode(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
return cmd_codecs_proc(vtbl, argc, argv, CODEC_MODE_URLDECODE, urldecode_cb);
}
#endif
/****************************************************************************
* Name: cmd_base64encode
****************************************************************************/
#if defined(CONFIG_CODECS_BASE64) && !defined(CONFIG_NSH_DISABLE_BASE64ENC)
int cmd_base64encode(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
return cmd_codecs_proc(vtbl, argc, argv, CODEC_MODE_BASE64ENC, b64enc_cb);
}
#endif
/****************************************************************************
* Name: cmd_base64decode
****************************************************************************/
#if defined(CONFIG_CODECS_BASE64) && !defined(CONFIG_NSH_DISABLE_BASE64DEC)
int cmd_base64decode(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
return cmd_codecs_proc(vtbl, argc, argv, CODEC_MODE_BASE64DEC, b64dec_cb);
}
#endif
/****************************************************************************
* Name: cmd_md5
****************************************************************************/
#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
int cmd_md5(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
return cmd_codecs_proc(vtbl,argc,argv,CODEC_MODE_HASH_MD5,md5_cb);
}
#endif
#endif /* CONFIG_NETUTILS_CODECS */

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

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

View File

@@ -1,7 +1,7 @@
/****************************************************************************
* apps/nshlib/nsh_parse.c
*
* Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -59,7 +59,7 @@
#endif
#ifdef CONFIG_NSH_BUILTIN_APPS
# include <apps/apps.h>
# include <nuttx/binfmt/builtin.h>
#endif
#include <apps/nsh.h>
@@ -72,7 +72,7 @@
/* Argument list size
*
* argv[0]: The command name.
* argv[0]: The command name.
* argv[1]: The beginning of argument (up to CONFIG_NSH_MAXARGUMENTS)
* argv[argc-3]: Possibly '>' or '>>'
* argv[argc-2]: Possibly <file>
@@ -226,7 +226,7 @@ static const struct cmdmap_s g_cmdmap[] =
{ "help", cmd_help, 1, 3, "[-v] [<cmd>]" },
# endif
#endif
#if CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_NSH_DISABLE_HEXDUMP
{ "hexdump", cmd_hexdump, 2, 2, "<file or device>" },
@@ -301,7 +301,7 @@ static const struct cmdmap_s g_cmdmap[] =
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE)
# ifndef CONFIG_NSH_DISABLE_MOUNT
{ "mount", cmd_mount, 1, 5, "[-t <fstype> <block-device> <mount-point>]" },
{ "mount", cmd_mount, 1, 5, "[-t <fstype> [<block-device>] <mount-point>]" },
# endif
#endif
@@ -605,7 +605,7 @@ static inline void help_builtins(FAR struct nsh_vtbl_s *vtbl)
/* List the set of available built-in commands */
nsh_output(vtbl, "\nBuiltin Apps:\n");
for (i = 0; (name = namedapp_getname(i)) != NULL; i++)
for (i = 0; (name = builtin_getname(i)) != NULL; i++)
{
nsh_output(vtbl, " %s\n", name);
}
@@ -723,15 +723,11 @@ static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
* Name: nsh_execute
*
* Description:
* Exectue the command in argv[0]
* Execute the command in argv[0]
*
* Returned Value:
* <0 If exec_namedapp() fails, then the negated errno value
* is returned.
* -1 (ERRROR) if the command was unsuccessful
* 0 (OK) if the command was successful
* 1 if an application task was spawned successfully, but
* returned failure exit status.
*
****************************************************************************/
@@ -751,21 +747,6 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl, int argc, char *argv[])
*/
cmd = argv[0];
/* Try to find a command in the application library. */
#ifdef CONFIG_NSH_BUILTIN_APPS
ret = nsh_execapp(vtbl, cmd, argv);
/* If the built-in application was successfully started, return OK
* or 1 (if the application returned a non-zero exit status).
*/
if (ret >= 0)
{
return ret;
}
#endif
/* See if the command is one that we understand */
@@ -1352,7 +1333,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
/* Parse all of the arguments following the command name. The form
* of argv is:
*
* argv[0]: The command name.
* argv[0]: The command name.
* argv[1]: The beginning of argument (up to CONFIG_NSH_MAXARGUMENTS)
* argv[argc-3]: Possibly '>' or '>>'
* argv[argc-2]: Possibly <file>
@@ -1410,6 +1391,47 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
}
}
/* Check if the maximum number of arguments was exceeded */
if (argc > CONFIG_NSH_MAXARGUMENTS)
{
nsh_output(vtbl, g_fmttoomanyargs, cmd);
}
/* Does this command correspond to a builtin command?
* nsh_builtin() returns:
*
* -1 (ERROR) if the application task corresponding to 'argv[0]' could not
* be started (possibly because it doesn not exist).
* 0 (OK) if the application task corresponding to 'argv[0]' was
* and successfully started. If CONFIG_SCHED_WAITPID is
* defined, this return value also indicates that the
* application returned successful status (EXIT_SUCCESS)
* 1 If CONFIG_SCHED_WAITPID is defined, then this return value
* indicates that the application task was spawned successfully
* but returned failure exit status.
*
* Note the priority if not effected by nice-ness.
*/
#ifdef CONFIG_NSH_BUILTIN_APPS
ret = nsh_builtin(vtbl, argv[0], argv, redirfile, oflags);
if (ret >= 0)
{
/* nsh_builtin() returned 0 or 1. This means that the builtin
* command was successfully started (although it may not have ran
* successfully). So certainly it is not an NSH command.
*/
return nsh_saveresult(vtbl, ret != OK);
}
/* No, not a built in command (or, at least, we were unable to start a
* builtin command of that name). Treat it like an NSH command.
*/
#endif
/* Redirected output? */
if (vtbl->np.np_redirect)
@@ -1431,23 +1453,13 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
}
}
/* Check if the maximum number of arguments was exceeded */
if (argc > CONFIG_NSH_MAXARGUMENTS)
{
nsh_output(vtbl, g_fmttoomanyargs, cmd);
}
/* Handle the case where the command is executed in background.
* However is app is to be started as namedapp new process will
* be created anyway, so skip this step. */
* However is app is to be started as builtin new process will
* be created anyway, so skip this step.
*/
#ifndef CONFIG_NSH_DISABLEBG
if (vtbl->np.np_bg
#ifdef CONFIG_NSH_BUILTIN_APPS
&& namedapp_isavail(argv[0]) < 0
#endif
)
if (vtbl->np.np_bg)
{
struct sched_param param;
struct nsh_vtbl_s *bkgvtbl;
@@ -1514,6 +1526,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
priority = min_priority;
}
}
param.sched_priority = priority;
}
@@ -1553,8 +1566,6 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
*
* -1 (ERRROR) if the command was unsuccessful
* 0 (OK) if the command was successful
* 1 if an application task was spawned successfully, but
* returned failure exit status.
*/
ret = nsh_execute(vtbl, argc, argv);
@@ -1568,11 +1579,11 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
nsh_undirect(vtbl, save);
}
/* Treat both errors and non-zero return codes as "errors" so that
* it is possible to test for non-zero returns in nsh scripts.
/* Mark errors so that it is possible to test for non-zero return values
* in nsh scripts.
*/
if (ret != OK)
if (ret < 0)
{
goto errout;
}

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)

View File

@@ -92,11 +92,14 @@ $(COBJS): %$(OBJEXT): %.c
# Register application
.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
$(Q) touch $@
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
# Create dependencies
@@ -111,7 +114,6 @@ clean:
$(call CLEAN)
distclean: clean
$(call DELFILE, .context)
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)

View File

@@ -68,7 +68,7 @@ STACKSIZE = 2048
# Build targets
all: .built
.PHONY: .context context .depend depend clean distclean
.PHONY: context .depend depend clean distclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
@@ -80,11 +80,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
$(Q) touch .built
.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
$(Q) touch $@
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
.depend: Makefile $(SRCS)
$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
@@ -97,7 +100,6 @@ clean:
$(call CLEAN)
distclean: clean
$(call DELFILE, .context)
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)

View File

@@ -93,11 +93,14 @@ $(COBJS): %$(OBJEXT): %.c
# Register application
.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
$(Q) touch $@
context: .context
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
# Create dependencies
@@ -112,7 +115,6 @@ clean:
$(call CLEAN)
distclean: clean
$(call DELFILE, .context)
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)

View File

@@ -100,7 +100,6 @@ clean:
$(call CLEAN)
distclean: clean
$(call DELFILE, .context)
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)

View File

@@ -1452,7 +1452,7 @@
complex: 'uname -o 2>/dev/null || echo "Other"'
* drivers/usbhost/usbhost_enumerate.c: Add logic to get the VID and PID. This
is necessary in order to support vendor-specific USB devices.
* examplex/wlan, configs/olimex-lpc1766stk/wlan, drivers/usbhost/usbhost_rtl8187.c,
* examples/wlan, configs/olimex-lpc1766stk/wlan, drivers/usbhost/usbhost_rtl8187.c,
Add infrastructure to support RTL18187 wireless USB.
* configs/nucleus2g: backed out USB host changes... wrong board.
* Renamed arc/hc/include/mc9s12ne64 and src/mc9s12ne64 to m9s12. That name is
@@ -1920,7 +1920,7 @@
CONFIG_FAT_LCNAMES is not selected, all filenames are strictly upper
case.
* configs/stm3210e-eval/nsh2: Console is back on UART1; Added
examplex/nx as an NSH "built-in" command as a demonstration.
examples/nx as an NSH "built-in" command as a demonstration.
* fs/fat/fs_fat32dirent.c: Fix an important bug in the directory
allocation (fat_allocatedirentry()). I looks like it could be
initializing the wrong sectors! NOTE: This function was in
@@ -3801,3 +3801,170 @@
to find executables using a relative path.
6.25 2013-xx-xx Gregory Nutt <gnutt@nuttx.org>
* graphics/: Adds 5x8 monospace font. This tiny font is useful for graph
labels and for small bitmapped display. Contributed by Petteri
Aimonen.
* configs/stm3220g-eval/nxwm: Converted to use the kconfig-frontends
configuration tool.
* configs/sim/nxwm: Converted to use the kconfig-frontends configuration
tool.
* include/pthread.h: In sys/prctl.h because it is needed by
pthread_[set|get]name_np()
* tools/kconfig.bat: Kludge to run kconfig-frontends from a DOS shell.
* sched/sig_timedwait.c: Should always move the time up to the next
largest number of system ticks. The logic was rounding. Noted by
Petteri Aimonen.
* arch/arm/src/up_head.S: Fix backward conditional compilation. NOTE
there is a issue of ARM9 systems with low vectors and large memories
that will have to be addressed in the future.
* libc/misc/lib_kbdencode.c and lib_kbddecode.c: Add logic to marshal
and serialized "out-of-band" keyboard commands intermixed with normal
ASCII data (not yet hooked into anything).
* drivers/usbhost/usbhost_hidkbd.c: If CONFIG_HIDKBD_ENCODED is
defined, this driver will now use libc/misc/lib_kbdencode.c to
encode special function keys.
* configs/olimex-lpc1766stk/hidkbd: This configuration has been
converted to use the kconfig-frontends configuration tool.
* drivers/lcd/ug-2864hsweg01.c and include/nuttx/lcd/ug-2864hsweg01.h:
Driver for UG-2864HSWEG01 OLED contributed by Darcy Gong.
* configs/stm32f4discovery/src/up_ug2864hsweg01.c: Support for the
UG-2864HSWEG01 OLED for the STM32F4Discovery board.
* drivers/usbhost/usbhost_hidkbd.c: Correct a logic error in how
tasks waiting for read data are awakened.
* libc/misc/lib_kbdencode.c and lib_kbddecode.c: Now handles keypress
events too. 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.
* configs/mcu123-214x/nsh: Converted to use the kconfig-frontends
configuration tool.
* configs/zp214xpa: Add basic support for the The0.net ZP213x/4xPA
board (with the LPC2148 and the UG_2864AMBAG01).
* configs/sim/nxlines: Add an nxlines configuration for the
simulator.
* configs/zp214xpa/nxlines: Add an nxlines configuration for the
ZP213x/4xPA (with the LPC2148 and the UG_2864AMBAG01). Working
as of 2012-12-30.
* configs/olimex-lpc1766stk/wlan: Remove non-functional
configuration.
* configs/stm32f4discovery/src and nuttx/drivers/lcd/ug-2864hsweg01.c:
Updates and correctinos for the UG-2864HSWEG01 from Darcy Gong.
* configs/lm326965-ek: All configurations converted to use the
kconfig-frontends configuration tool.
* configs/Kconfig: NSH_MMCSDSPIPORTNO should depend on MMCSD_SPI,
not just SPI (from Jose Pablo Carballo).
* arch/arm/src/arm/Kconfig and armv7m/Kconfig: Add an option for
buildroot toolchains: They may be EABI or OABI.
* include/nuttx/progmem and arch/arm/src/stm32/stm32_flash.c:
Fix a counting bug plus change interface to use either relative
or absolut FLASH addressing (from Freddie Chopin).
* libc/misc/Make.defs: Fix error in conditional for KBD CODEC.
* libc/Kconfig and configs/*/defconfig (several): The default
setting should be CONFIG_LIB_KBDCODEC=n
* tools/configure.c: configure.c can be used to build a work-alike
program as a replacement for configure.sh. This work-alike
program would be used in environments that do not support Bash
scripting (such as the Windows native environment).
* tools/configure.bat: configure.bat is a small Windows batch
file that can be used as a replacement for configure.sh in a
Windows native environment. configure.bat is actually just a
thin layer that execuates configure.exe if it is available. If
configure.exe is not available, then configure.bat will attempt
to build it first.
* arch/arm/src/lpc17xx/lpc17_syscon.h: Correct some typos in bit
definitions (from Rommel Marcelo).
* libc/string/lib_strndup.c: strndup() should use strnlen(), not
strlen(), to determine the size of the string.
* sched/os_bringup.c: Remove support for CONFIG_BUILTIN_APP_START.
This is not really a useful feature and creates a violation of the
OS layered architecture.
* include/unistd.h, arch/arch/src/*: Implement a simple vfork().
On initial checkin, this API is available only for ARM platforms.
* binfmt/binfmt_exec.c: exec() now sets the priority of the new task
to the same priority as the current task (instead of the arbirtrary
value of 50).
* libc/unisted/lib_execv.c and lib_execl.c: New, somewhat flawed,
implementations of execv() and execl().
* tools/cfgdefine.c: Strips quotes from CONFIG_EXECFUNCS_SYMTAB
value.
* arch/arm/include/lm3s/chip.h: Move chip definitions into
public include area for compatibility with other architectures.
* arch/arm/src/lm3s/chip: Move register definition header files
into a new chip/ sub-directory.
* arch/arm/src/lm3s/lm3s_internal.h: Broke up into several
smaller header files.
* arch/arm/src/lm: Rename the arch/arm/src/lm3s directory to
arch/arm/src/lm so that is can support other members of the
Stellaris family.
* libc/spawn: Add file action interfaces needed by posix_spawn().
* sched/clock_time2ticks.c: Another case where time was being
rounded down instead of up (from Mike Smith).
* libc/spawn: Implementation of posix_spawn() is complete but
untested and undocumented.
* drivers/usbdev/pl2303.c: Fix typols in the PL2303 driver
(from Max Holtzberg).
* configs/stm32f4discovery/posix_spawn: Added a configuration
that can be used for testing posix_spawn().
* arch/arm/src/stm32: Bring F1 support for general DMA and serial
DMA in paricular up to parity with F2/F4 (from Mike Smith).
* libc/stdio/lib_libfread.c: Correct some error handling when
lib_fread() was passed a bad stream. Needed to move the
releasing of a semaphore inside of some conditional logic
(cosmetic).
* include/nuttx/sched.h, sched/task_setup.c, and sched/task_exithook.c:
Add support for remembering the parent task and sending
SIGCHLD to the parent when the task exists.
* sched/task_exithook.c: Fixed a *critical* bug. Here is
the scenario: (1) sched_lock() is called increments the lockcount
on the current TCB (i.e., the one at the head of the ready to run
list), (2) sched_mergepending is called which may change the task
at the head of the readytorun list, then (2) sched_unlock() is called
which decrements the lockcount on the wrong TCB. The failure case
that I saw was that pre-emption got disabled in the IDLE thread,
locking up the whole system.
* sched/sched_waitpid.c: Use SIGCHLD instead of a semaphore. This
is a much more spec-compliant implemenation. However, there are
some issues with overruning signals because NuttX does not support
queueing of signals (POSIX does not require it). I think it may
need to.
* sched/sched_waitid.c and sched_wait.c: Add support for waitid()
and wait(). See issues with waitpid() above.
* include/nuttx/fs/fs.h and fs/fs_files.c: Add a dup() method to
the struct mountpt_operations. When dup'ing a file that resides
on a mounted volume, let the file system's dup() method do the
work.
* fs/romfs/fs_romfs.c: Implemented the dup() method for the ROMFS
file system.
* fs/fat/fs_fat32.c, fs/nxffs/nxffs_initialize, and
fs/nfs/nfs_vfsops.c: Add hooks for dup() method (not yet
implemented).
* fs/romfs: Remove the rf_open flag. It looks good, but actually
does nothing.
* fs/fat: Remove the ff_open flag. Same story as for the ROMFS
rf_open flag.
* fs/fat/fs_fat32.c, fs/nxffs/nxffs_initialize, and
fs/nfs/nfs_vfsops.c: Completed implementation of the dup() methods.
There is still no good test available.
* sched/sig_timedwait.c: sigtimedwait() would return a bad signal
number if the signal was already pending when the function was
called.
* configs/ubw32/scripts: All common linker scripts moved to this
scripts sub-directory
* configs/ubw32/ostest: Configuration configured to use the
kconfig-frontends tools.
* arch/mips/src/mips32/up_vfork.c, up_vfork.h, and vfork.S:
Implement vfork() for MIPS32 (no floating point support)
* configs/ubw32/ostest: Enable the vfork() test.
* fs/binfs: Move apps/builtin/binfs.c to fs/binfs/fs_binfs.c
CONFIG_APPS_BINDIR rename CONFIG_FS_BINFS
* include/nuttx/binfmt/builtin.h: Some of the content of
apps/include/apps.h moved to include/nuttx/binfmt/builtin.h
* binfmt/libbuiltin/libbuiltin_utils.c: Move utility builtin
utility functions from apps/builtin/exec_builtins.c to
binfmt/libbuiltin/libbuiltin_utils.c
* binfmt/builtin.c and binfmt/libbuiltin: Add a binary "loader"
that can be used to execute builtin programs from the BINFS
file system.
* configs/sim/nsh: Convert to use kconfig-frontends configuration
tool.

View File

@@ -642,13 +642,13 @@ pass2dep: context tools/mkdeps$(HOSTEXEEXT)
# misc/tools/README.txt for additional information.
config:
$(Q) APPSDIR=${CONFIG_APPS_DIR} conf Kconfig
$(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf Kconfig
oldconfig:
$(Q) APPSDIR=${CONFIG_APPS_DIR} conf --oldconfig Kconfig
$(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf --oldconfig Kconfig
menuconfig:
$(Q) APPSDIR=${CONFIG_APPS_DIR} mconf Kconfig
$(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-mconf Kconfig
# export
#

View File

@@ -252,7 +252,7 @@ LINKLIBS = $(patsubst lib\\%,%,$(NUTTXLIBS))
BIN = nuttx$(EXEEXT)
all: $(BIN)
.PHONY: context clean_context check_context export subdir_clean clean subdir_distclean distclean apps_clean apps_distclean
.PHONY: context clean_context check_context configenv config oldconfig menuconfig export subdir_clean clean subdir_distclean distclean apps_clean apps_distclean
# Target used to copy include\nuttx\math.h. If CONFIG_ARCH_MATH_H is
# defined, then there is an architecture specific math.h header file
@@ -452,7 +452,7 @@ clean_context:
# check_context
#
# This target checks if NuttX has been configured. NuttX is configured using
# the script tools\configure.sh. That script will install certain files in
# the script tools\configure.bat. That script will install certain files in
# the top-level NuttX build directory. This target verifies that those
# configuration files have been installed and that NuttX is ready to be built.
@@ -647,14 +647,17 @@ pass2dep: context tools\mkdeps$(HOSTEXEEXT)
# location: http://ymorin.is-a-geek.org/projects/kconfig-frontends. See
# misc\tools\README.txt for additional information.
config:
$(Q) APPSDIR=${CONFIG_APPS_DIR} conf Kconfig
configenv:
$(Q) set APPSDIR=${CONFIG_APPS_DIR}
oldconfig:
$(Q) APPSDIR=${CONFIG_APPS_DIR} conf --oldconfig Kconfig
config: configenv
$(Q) kconfig-conf Kconfig
menuconfig:
$(Q) APPSDIR=${CONFIG_APPS_DIR} mconf Kconfig
oldconfig: configenv
$(Q) kconfig-conf --oldconfig Kconfig
menuconfig: configenv
$(Q) kconfig-mconf Kconfig
# export
#

View File

@@ -10,6 +10,9 @@ README
o Configuring NuttX
- Instantiating "Canned" Configurations
- NuttX Configuration Tool
- Incompatibilities with Older Configurations
- Converting Older Configurations to use the Configuration Tool
- NuttX Configuration Tool under DOS
o Toolchains
- Cross-Development Toolchains
- NuttX Buildroot Toolchain
@@ -38,6 +41,10 @@ Installing Cygwin
tiny setup.exe program and it does the real, internet installation
for you.
NOTE: NuttX can also be installed and built on a native Windows
system, but with some loss of tool functionality (see the
discussion "Native Windows Build" below).
Some Cygwin installation tips:
1. Install at C:\cygwin
@@ -58,8 +65,9 @@ Installing Cygwin
After installing Cygwin, you will get lots of links for installed
tools and shells. I use the RXVT native shell. It is fast and reliable
and does not require you to run the Cygwin X server (which is neither
fast nor reliable). The rest of these instructions assume that you
are at a bash command line prompt in either Linux or in Cygwin shell.
fast nor reliable). Unless otherwise noted, the rest of these
instructions assume that you are at a bash command line prompt in
either Linux or in Cygwin shell.
Download and Unpack
-------------------
@@ -235,8 +243,8 @@ additional file to the directory the NuttX application package (APPSDIR)):
The appconfig file describes the applications that need to be
built in the appliction directory (APPSDIR). Not all configurations
have an appconfig file. This file is deprecated and will not be
used with new defconfig files produced with the mconf configuration
tool.
used with new defconfig files produced with the kconfig-mconf
configuration tool.
General information about configuring NuttX can be found in:
@@ -249,6 +257,13 @@ easier. It is used as follows:
cd ${TOPDIR}/tools
./configure.sh <board-name>/<config-dir>
There is an alternative Windows batch file that can be used in the
windows native enironment like:
cd ${TOPDIR}\tools
configure.bat <board-name>\<config-dir>
See tools/README.txt for more information about these scripts.
NuttX Configuration Tool
------------------------
@@ -292,6 +307,162 @@ NuttX Configuration Tool
install 'mconf', make certain that your PATH variable includes
a path to that installation directory.
The basic configuration order is "bottom-up":
- Select the build environment,
- Select the processor,
- Select the board,
- Select the supported peripherals
- Configure the device drivers,
- Configure the application options on top of this.
This is pretty straight forward for creating new configurations
but may be less intuitive for modifying existing configurations.
Incompatibilities with Older Configurations
-------------------------------------------
***** WARNING *****
The old legacy, manual configurations and the new kconfig-frontends
configurations are not 100% compatible. Old legacy configurations
can *not* be used with the kconfig-frontends tool: If you run
'make menuconfig' with a legacy configuration the resulting
configuration will probably not be functional.
Q: How can I tell if a configuration is a new kconfig-frontends
configuration or an older, manual configuration?
A: a) New kcondfig-frontends configurations will have this setting
within the defconfig/.config file":
CONFIG_NUTTX_NEWCONFIG=y
b) Only old, manual configurations will have an appconfig file
Converting Older Configurations to use the Configuration Tool
-------------------------------------------------------------
Q: How can I convert a older, manual configuration into a new,
kconfig-frontends toolchain.
A: 1) Look at the appconfig file: Each application path there
will now have to have an enabling setting. For example,
if the old appconfig file had:
CONFIGURED_APPS = examples/ostest
Then the new configuration will need:
CONFIG_EXAMPLES_OSTEST=y
The appconfig file can then be deleted because it will not
be needed after the conversion.
2) Build the cmpconfig utility at tools:
cd tools
make -f Makefile.host cmpconfig
3) Perform these steps repeatedly until you are convinced that
the configurations are the same:
a) Repeat the following until you have account for all of the differences:
cp configs/<board>/<condfiguration>/defconfig .config
make menuconfig (Just exit and save the new .config file)
tools/cmpconfig configs/<board>/<condfiguration>/defconfig .config | grep file1
The final grep will show settings in the old defconfig file that
do not appear in the new .config file (or have a different value
in the new .config file). In the new configuration, you will
probably have to enable certain groups of features. Such
hierarachical enabling options were not part of the older
configuration.
b) Then make sure these all make sense:
tools/cmpconfig configs/<board>/<condfiguration>/defconfig .config | grep file2
The final grep will show settings in the new .config file that
do not appear in the older defconfig file (or have a different value
in the new .config file). Here you should see only the new
hierarachical enabling options (such as CONFIG_SPI or CONFIG_MMCSD)
plus some other internal configuration settings (like CONFIG_ARCH_HAVE_UART0).
You will have to convince yourself that these new settings all make sense.
4) Finally, update the configuration:
cp .config configs/<board>/<condfiguration>/defconfig
rm configs/<board>/<condfiguration>/appconfig
NOTE: You should comment out the line containing the CONFIG_APPS_DIR
in the new defconfig file. Why? Because the application directory
may reside at a different location when the configuration is installed
at some later time.
# CONFIG_APPS_DIR="../apps"
5) The updated configuration can then be instantiated in the normal
fashion:
cd tools
./configure.sh <board>/<condfiguration>
(or configure.bat for the case of the Windows native build).
NOTE: If CONFIG_APPS_DIR is not defined in the defconfig file,
the configure.sh script will find and add the new, correct path to
the application directory (CONFIG_APPS_DIR) when it copies the
defconfig file to the .config file. This is the setting that was
commented out in step 4.
NuttX Configuration Tool under DOS
----------------------------------
Recent versions of NuttX support building NuttX from a native Windows
console window (see "Native Windows Build" below). But kconfig-frontends
is a Linux tool. There have been some successes building a Windows
native version of the kconfig-frontends tool, but that is not ready
for prime time.
At this point, there are only a few options for the Windows user:
1. You can run the configuration tool using Cygwin. However, the
Cygwin Makefile.win will complain so to do this will, you have
to manually edit the .config file:
a. Delete the line: CONFIG_WINDOWS_NATIVE=y
b. Change the apps/ directory path, CONFIG_APPS_DIR to use Unix
style delimiters. For example, change "..\apps" to "../apps"
And of course, after you use the configuration tool you need to
restore CONFIG_WINDOWS_NATIVE=y and the correct CONFIG_APPS_DIR.
2) You can, with some effort, run the the Cygwin kconfig-mconf tool
directly in the Windows console window. In this case, you do not
have to modify the .config file, but there are other complexities:
a. You need to temporarily set the Cgywin directories in the PATH
variable then run kconfig-mconf manually like:
kconfig-mconf Kconfig
There is a Windows bacht file at tools/kconfig.bat that automates
these steps:
tools/kconfig menuconfig
b. There is an issue with accessing DOS environment variables from
the Cygwin kconfig-mconf running in the Windows console. The
following change to the top-level Kconfig file seems to work
around these problems:
config APPSDIR
string
- option env="APPSDIR"
+ default "../apps"
TOOLCHAINS
^^^^^^^^^^
@@ -509,82 +680,93 @@ Native Windows Build
- A few extensions from GNUWin32
In this build, you cannot use a Cygwin or MSYS shell. Rather the build must
be performed in a Windows CMD shell. Here is a better shell than than the
standard issue, CMD shell: ConEmu which can be downloaded from:
be performed in a Windows console window. Here is a better terminal than the
standard issue, CMD.exe terminal: ConEmu which can be downloaded from:
http://code.google.com/p/conemu-maximus5/
Build Tools. The build still relies on some Unix-like commands. I use
the GNUWin32 tools that can be downloaded from http://gnuwin32.sourceforge.net/.
Host Compiler: I use the MingGW compiler which can be downloaded from
Host Compiler: I use the MingGW GCC compiler which can be downloaded from
http://www.mingw.org/. If you are using GNUWin32, then it is recommended
the you not install the optional MSYS components as there may be conflicts.
This capability should still be considered a work in progress because:
(1) It has not been verfied on all targets and tools, and
(2) it still lacks some of the creature-comforts of the more mature environments
(like 'make menuconfig' support. See the section "NuttX Configuration Tool
under DOS" above).
There is an alternative to the setenv.sh script available for the Windows
native environment: tools/configure.bat. See tools/README.txt for additional
information.
Installing GNUWin32
-------------------
The Windows native build will depend upon a few Unix-like tools that can be
provided either by MSYS or GNUWin32. The GNUWin32 are available from
http://gnuwin32.sourceforge.net/. GNUWin32 provides ports of tools with a
GPL or similar open source license to modern MS-Windows (Microsoft Windows
2000 / XP / 2003 / Vista / 2008 / 7). See
http://gnuwin32.sourceforge.net/packages.html for a list of all of the tools
available in the GNUWin32 package.
The Windows native build will depend upon a few Unix-like tools that can be
provided either by MSYS or GNUWin32. The GNUWin32 are available from
http://gnuwin32.sourceforge.net/. GNUWin32 provides ports of tools with a
GPL or similar open source license to modern MS-Windows (Microsoft Windows
2000 / XP / 2003 / Vista / 2008 / 7). See
http://gnuwin32.sourceforge.net/packages.html for a list of all of the tools
available in the GNUWin32 package.
The SourceForge project is located here:
http://sourceforge.net/projects/gnuwin32/. The project is still being
actively supported (although some of the Windows ports have gotten very old).
The SourceForge project is located here:
http://sourceforge.net/projects/gnuwin32/. The project is still being
actively supported (although some of the Windows ports have gotten very old).
Some commercial toolchains include a subset of the GNUWin32 tools in the
installation. My recommendation is that you download the GNUWin32 tools
directly from the sourceforge.net website so that you will know what you are
using and can reproduce your build environment.
Some commercial toolchains include a subset of the GNUWin32 tools in the
installation. My recommendation is that you download the GNUWin32 tools
directly from the sourceforge.net website so that you will know what you are
using and can reproduce your build environment.
GNUWin32 Installation Steps:
GNUWin32 Installation Steps:
The following steps will download and execute the GNUWin32 installer.
The following steps will download and execute the GNUWin32 installer.
1. Download GetGNUWin32-x.x.x.exe from
http://sourceforge.net/projects/getgnuwin32/files/. This is the
installer. The current version as of this writing is 0.6.3.
1. Download GetGNUWin32-x.x.x.exe from
http://sourceforge.net/projects/getgnuwin32/files/. This is the
installer. The current version as of this writing is 0.6.3.
2. Run the installer.
2. Run the installer.
3. Accept the license.
3. Accept the license.
4. Select the installation directory. My recommendation is the
directory that contains this README file (<this-directory>).
4. Select the installation directory. My recommendation is the
directory that contains this README file (<this-directory>).
5. After running GetGNUWin32-0.x.x.exe, you will have a new directory
<this-directory>/GetGNUWin32
5. After running GetGNUWin32-0.x.x.exe, you will have a new directory
<this-directory>/GetGNUWin32
Note the the GNUWin32 installer didn't install GNUWin32. Instead, it
installed another, smarter downloader. That downloader is the GNUWin32
package management tool developed by the Open SSL project.
Note the the GNUWin32 installer didn't install GNUWin32. Instead, it
installed another, smarter downloader. That downloader is the GNUWin32
package management tool developed by the Open SSL project.
The following steps probably should be performed from inside a DOS shell.
The following steps probably should be performed from inside a DOS shell.
6. Change to the directory created by GetGNUWin32-x.x.x.exe
6. Change to the directory created by GetGNUWin32-x.x.x.exe
cd GetGNUWin32
cd GetGNUWin32
7. Execute the download.bat script. The download.bat script will download
about 446 packages! Enough to have a very complete Linux-like environment
under the DOS shell. This will take awhile. This step only downloads
the packages and the next step will install the packages.
7. Execute the download.bat script. The download.bat script will download
about 446 packages! Enough to have a very complete Linux-like environment
under the DOS shell. This will take awhile. This step only downloads
the packages and the next step will install the packages.
download
download
8. This step will install the downloaded packages. The argument of the
install.bat script is the installation location. C:\gnuwin32 is the
standard install location:
8. This step will install the downloaded packages. The argument of the
install.bat script is the installation location. C:\gnuwin32 is the
standard install location:
install C:\gnuwin32
install C:\gnuwin32
NOTE: This installation step will install *all* GNUWin32 packages... far
more than you will ever need. If disc space is a problem for you, you might
need to perform a manual installation of the individual ZIP files that you
will find in the <this directory>/GetGNUWin32/packages directory.
NOTE: This installation step will install *all* GNUWin32 packages... far
more than you will ever need. If disc space is a problem for you, you might
need to perform a manual installation of the individual ZIP files that you
will find in the <this directory>/GetGNUWin32/packages directory.
CYGWIN BUILD PROBLEMS
^^^^^^^^^^^^^^^^^^^^^

View File

@@ -1,4 +1,4 @@
NuttX TODO List (Last updated November 25, 2012)
NuttX TODO List (Last updated January 14, 2013)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This file summarizes known NuttX bugs, limitations, inconsistencies with
@@ -6,21 +6,20 @@ standards, things that could be improved, and ideas for enhancements.
nuttx/
(6) Task/Scheduler (sched/)
(1) On-demand paging (sched/)
(10) Task/Scheduler (sched/)
(1) Memory Managment (mm/)
(2) Signals (sched/, arch/)
(3) Signals (sched/, arch/)
(2) pthreads (sched/)
(2) C++ Support
(6) Binary loaders (binfmt/)
(17) Network (net/, drivers/net)
(4) USB (drivers/usbdev, drivers/usbhost)
(11) Libraries (libc/, )
(12) Libraries (libc/, )
(9) File system/Generic drivers (fs/, drivers/)
(5) Graphics subystem (graphics/)
(1) Pascal add-on (pcode/)
(1) Documentation (Documentation/)
(8) Build system / Toolchains
(7) Build system / Toolchains
(5) Linux/Cywgin simulation (arch/sim)
(6) ARM (arch/arm/)
(1) ARM/C5471 (arch/arm/src/c5471/)
@@ -31,8 +30,8 @@ nuttx/
(2) ARM/LPC313x (arch/arm/src/lpc313x/)
(0) ARM/LPC43x (arch/arm/src/lpc43xx/)
(3) ARM/STR71x (arch/arm/src/str71x/)
(3) ARM/LM3S6918 (arch/arm/src/lm3s/)
(4) ARM/STM32 (arch/arm/src/stm32/)
(3) ARM/LM3S6918 (arch/arm/src/lm/)
(5) ARM/STM32 (arch/arm/src/stm32/)
(3) AVR (arch/avr)
(0) Intel x86 (arch/x86)
(5) 8051 / MCS51 (arch/8051/)
@@ -56,33 +55,9 @@ o Task/Scheduler (sched/)
Title: CHILD PTHREAD TERMINATION
Description: When a tasks exits, shouldn't all of its child pthreads also be
terminated?
Status: Open
Status: Closed. No, this behavior will not be implemented.
Priority: Medium, required for good emulation of process/pthread model.
Title: MMAN.H
Description: Implement sys/mman.h and functions
Status: Open
Priority: Low
Title: WAIT.H
Description: Implement sys/wait.h and functions. Consider implementing wait,
waitpid, waitid. At present, a parent has no information about
child tasks.
Update: A simple but usable version of waitpid() has been included.
This version is not compliant with all specifications and can be
enabled with CONFIG_SCHED_WAITPID.
Status: Open
Priority: Low
Title: MISSING ERRNO SETTINGS
Description: Several APIs do not set errno. Need to review all APIs.
Update: These are being fixed as they are encountered. There is
no accounting of how many interfaces have this problem.
Status: Open
Priority: Medium, required for standard compliance (but makes the
code bigger)
Title: TICKLESS OS
Description: On a side note, I have thought about a tick-less timer for the OS
for a long time. Basically we could replace the periodic system
@@ -107,18 +82,22 @@ o Task/Scheduler (sched/)
3) sched_process_timeslice(). Then there is round-robin time-slicing.
Status: Open
The primary advantage of a tickless OS is that is would allow for
reduce power consumptions. That is because timer interrupts will
usually awaken CPUs from reduced power consumption states.
Status: Open. There will probably be no tickless OS implementation unless
someone gets motivated and drives the change.
Priority: Low
Title: posix_spawn()
Description: This would be a good interface to add to NuttX. It is really
just a re-packaging of the existing, non-standard NuttX exec()
function.
Status: Open
Priority: Medium low.
o On-demand paging (sched/)
^^^^^^^^^^^^^^^^^^^^^^^^^
Title: pause() NON-COMPLIANCE
Description: In the POSIX description of this function is the pause() function
will suspend the calling thread until delivery of a signal whose
action is either to execute a signal-catching function or to
terminate the process. The current implementation only waits for
any non-blocked signal to be received. It should only wake up if
the signal is delivered to a handler.
Status: Open.
Priority: Medium Low.
Title: ON-DEMAND PAGE INCOMPLETE
Description: On-demand paging has recently been incorporated into the RTOS.
@@ -130,19 +109,16 @@ o On-demand paging (sched/)
configs/ea3131/pgnsh and locked directories). There are
some limitations of this testing so I still cannot say that
the feature is fully functional.
Status: Open
Status: Open. This has been put on the shelf for some time.
Priority: Medium-Low
o Other core OS logic
^^^^^^^^^^^^^^^^^^^
Title: GET_ENVIRON_PTR()
Description: get_environ_ptr() (sched/sched_getenvironptr.c) is not implemented.
The representation of the the environment strings selected for
NutX is not compatible with the operation. Some significant
re-design would be required to implement this funcion and that
effort is thought to be not worth the result.
Status: Open
Status: Open. No change is planned.
Priority: Low -- There is no plan to implement this.
Title: TIMER_GETOVERRUN()
@@ -150,6 +126,91 @@ o Other core OS logic
Status: Open
Priority: Low -- There is no plan to implement this.
Title: USER-SPACE WORK QUEUES
Description: There has been some use of work queues that has crept into some
user code. I am thinking of NxWidgets::CNxTimer. That timer
logic was originally implemented (correctly) using POSIX timers,
but was re-implemented using timed work.
The issue is that NxWidgets::CNxTimer is a user-space application
but the work queues are an OS internal feature. This will be a
problem for KERNEL builds. Hooks and definitions have been added
in include/nuttx/wqueue.h to support a user-space work queue, but
the corresponding logic has not been implemented.
The work queue logic will need to be moved from sched/ to libc/wqueue/
Status: Open. No work will probably be done until a functional KERNEL build
that includes NxWisges::CNxTimer is needed.
Priority: Medium Low for now
Title: INCOMPATIBILITES WITH execv() AND execl()
Description: Simplified 'execl()' and 'execv()' functions are provided by
NuttX. NuttX does not support processes and hence the concept
of overlaying a tasks process image with a new process image
does not make any sense. In NuttX, these functions are
wrapper functions that:
1. Call the non-standard binfmt function 'exec', and then
2. exit(0).
As a result, the current implementations of 'execl()' and
'execv()' suffer from some incompatibilities, the most
serious of these is that the exec'ed task will not have
the same task ID as the vfork'ed function. So the parent
function cannot know the ID of the exec'ed task.
Status: Open
Priority: Medium Low for now
Title: RETAINING TASK EXIT STATUS
Description: When a task exists, its exit status should be retained in
so data structure until it is reaped (via waitpid(), or
similar interface) or until the parent thread exists.
You would think that this should be a clone of the existing
pthread join logic. Howver there is no need for zombies
in NuttX so no need to keep the status if the parent has
already exit'ed. Other simplifications:
1. Keep the array/list of return status in the parent
tasks TCB.
2. Use a fixed size array of return status (perhaps the
the enire array is allocated so that that is con
penalty for tasks that have no childre.
At present, exit status is not retained. If waitpid()
is called after the child task has exit'ed it simpley
returns with the ECHLD error. That is not too bad, but
does not tell you what the exit status was.
A work-around is to:
1) Call sched_lock() to disable pre-emption.
2) Start the task (it cannot run because pre-emption is
disbled.
3) Call waitpid();
4) Call sched_unlock() to re-enable pre-emption.
Status: Open
Priority: Low
Title: IMPROVED TASK CONTROL BLOCK STRUCTURE
All task resources that are shared amongst threads have
their own "break-away", reference-counted structure. The
Task Control Block (TCB) of each thread holds a reference
to each breakaway structure (see include/nuttx/sched.h).
It would be more efficent to have one reference counted
structure that holds all of the shared resources.
These are the current shared structures:
- Environment varaibles (struct environ_s)
- PIC data space and address environments (struct dspace_s)
- File descriptors (struct filelist)
- FILE streams (struct streamlist)
- Sockets (struct socketlist)
Status: Open
Priority: Low. This is an enhancement. It would slight reduce
memory usage but would also increase coupling. These
resources are nicely modular now.
o Memory Managment (mm/)
^^^^^^^^^^^^^^^^^^^^^^
@@ -212,7 +273,7 @@ o Memory Managment (mm/)
be required to keep this memory on the correct list (or on
no list at all).
Status: Open
Status: Open. No changes are planned.
Priority: Medium/Low, a good feature to prevent memory leaks but would
have negative impact on memory usage and code size.
@@ -221,8 +282,10 @@ o Signals (sched/, arch/)
Title: STANDARD SIGNALS
Description: 'Standard' signals and signal actions are not supported.
(e.g., SIGINT, SIGCHLD, SIGSEGV, etc).
Status: Open
(e.g., SIGINT, SIGSEGV, etc).
Update: SIG_CHLD is support if configured.
Status: Open. No changes are planned.
Priority: Low, required by standards but not so critical for an
embedded system.
@@ -234,17 +297,25 @@ o Signals (sched/, arch/)
are required by the POSIX standard.
Priority: Low for now
Title: SIGNAL NUMBERING
Description: In signal.h, the range of valid signals is listed as 0-31. However,
in many interfaces, 0 is not a valid signal number. The valid
signal number should be 1-32. The signal set operations would need
to map bits appropriately.
Status: Open
Priority: Low. Even if there are only 31 usable signals, that is still a lot.
o pthreads (sched/)
^^^^^^^^^^^^^^^^^
Title: CANCELLATION POINTS
Description: pthread_cancel(): Should implement cancellation points and
pthread_testcancel()
Status: Open
Status: Open. No changes are planned.
Priority: Low, probably not that useful
Title: PTHREAD_PRIO_PROTECT
Description: Extended pthread_mutexattr_setprotocol() suport PTHREAD_PRIO_PROTECT:
Description: Extended pthread_mutexattr_setprotocol() suport PTHREAD_PRIO_PROTECT:
"When a thread owns one or more mutexes initialized with the
PTHREAD_PRIO_PROTECT protocol, it shall execute at the higher of its
priority or the highest of the priority ceilings of all the mutexes
@@ -260,7 +331,7 @@ o pthreads (sched/)
PTHREAD_PRIO_PROTECT protocol attributes, it shall not be subject to
being moved to the tail of the scheduling queue at its priority in the
event that its original priority is changed."
Status: Open
Status: Open. No changes planned.
Priority: Low -- about zero, probably not that useful. Priority inheritance is
already supported and is a much better solution. And it turns out
that priority protection is just about as complex as priority inheritance.
@@ -442,21 +513,25 @@ o Network (net/, drivers/net)
Title: SOCK_RAW/SOCK_PACKET
Description: Should implement SOCK_RAW, SOCK_PACKET
Status: Open
Status: Open. No changes are planned.
Priority: Low
Tile: MULTIPLE NETWORK INTERFACE SUPPORT
Description: uIP polling issues / Multiple network interface support:
(1) Current logic will not support multiple ethernet drivers.
Each driver should poll on TCP connections connect on the
network supported by the driver; UDP polling should respond
with TX data only if the UDP packet is intended for the
the network supported by the driver.
(2) If there were multiple drivers, polling would occur at
double the rate. Fix by using bound IP address in TCP
connection (lipaddr) and verifying that it is in the subnet
served by the driver.
Status: Open
Status: Open. Nothing will probably be done until I have a platform
with two network interfaces that I need to support.
Priority: Medium, The feature is not important, but it is important
for NuttX to resolve the architectural issues.
@@ -464,7 +539,7 @@ o Network (net/, drivers/net)
Description: sendto() and multiple network interface support:
When polled, would have to assure that the destination IP
is on the subnet served by the polling driver.
Status: Open
Status: Open. This is really part of the above issue.
Priority: Medium, The feature is not important, but it is important
for NuttX to resolve the architectural issues.
@@ -472,7 +547,8 @@ o Network (net/, drivers/net)
Description: IPv6 support is incomplete. Adam Dunkels has recently announced
IPv6 support for uIP (currently only as part of Contiki). Those
changes need to be ported to NuttX.
Status: Open
Status: Open. No work will probably be done until there is a specific
requirement for IPv6.
Priority: Medium
Title: LISTENING FOR UDP BROADCASTS
@@ -488,7 +564,7 @@ o Network (net/, drivers/net)
driver should be throttled. Perhaps the driver should disable
RX interrupts when throttled and re-anable on each poll time.
recvfrom would, of course, have to un-throttle.
Status: Open
Status: Open. This is just a thought experiment. No changes are planned.
Priority: Medium
Title: STANDARDIZE ETHERNET DRIVER STATISTICS
@@ -637,6 +713,15 @@ o USB (drivers/usbdev, drivers/usbhost)
o Libraries (libc/)
^^^^^^^^^^^^^^^^^
Title: SIGNED time_t
Description: The NuttX time_t is type uint32_t. I think this is consistent
with all standards and with normal usage of time_t. However,
according to Wikipedia, time_t is usually implemented as a
signed 32-bit value.
Status: Open
Priority: Very low unless there is some compelling issue that I do not
know about.
Title: ENVIRON
Description: The definition of environ in stdlib.h is bogus and will not
work as it should. This is because the underlying
@@ -1002,20 +1087,6 @@ o Build system
Status: Open, there are some workarounds, but none are good.
Priority: High
Title: configure.sh NOT AVAILABLE IN NATIVE WINDOWS BUILD
Description: configure.sh is a Bash script and cannot be used from a Windows
CMD.exe window. I started a configure.bat script, but I do
not have the batch file programming skills to duplicate some
of the more complex operations.
I also considered adding a configure.c file that could be
compiled and then executed by configure.bat (and configure.sh?).
But I have not gone down that path yet.
The current work-around is to configure under Cygwin.
Status: Open
Priority: High
o Linux/Cywgin simulation (arch/sim)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1370,7 +1441,7 @@ o ARM/STR71x (arch/arm/src/str71x/)
Status: Open
Priority: Medium -- Will be very high if you do SPI access from multiple threads.
o ARM/LM3S6918 (arch/arm/src/lm3s/)
o ARM/LM3S6918 (arch/arm/src/lm/)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Title: I2C DRIVER
@@ -1460,6 +1531,11 @@ o ARM/STM32 (arch/arm/src/stm32/)
Status: Open
Priority: Low
Title: STM32 F4 USB OTG FS DEVICE-SIDE DRIVER
Description: This driver is reported to be buggy and to need some TLC.
Status: Open
Priority: High
o AVR (arch/avr)
^^^^^^^^^^^^^^

View File

@@ -16,6 +16,7 @@ config ARCH_8051
config ARCH_ARM
bool "ARM"
select ARCH_HAVE_INTERRUPTSTACK
select ARCH_HAVE_VFORK
---help---
The ARM architectures
@@ -108,6 +109,10 @@ config ARCH_NOINTC
bool
default n
config ARCH_VECNOTIRQ
bool
default n
config ARCH_DMA
bool
default n
@@ -124,6 +129,10 @@ config ADDRENV
bool
default n
config ARCH_HAVE_VFORK
bool
default n
config ARCH_STACKDUMP
bool "Dump stack on assertions"
default n
@@ -136,6 +145,20 @@ config ENDIAN_BIG
---help---
Select if architecture operates using big-endian byte ordering.
config ARCH_HAVE_RAMFUNCS
bool
default n
config ARCH_RAMFUNCS
bool "Copy functions to RAM on startup"
default n
depends on ARCH_HAVE_RAMFUNCS
---help---
Copy some functions to RAM at boot time. This is done in some
architectures to improve performance. In other cases, it is done
so that FLASH can be reconfigured while the MCU executes out of
SRAM.
comment "Board Settings"
config BOARD_LOOPSPERMSEC

View File

@@ -170,12 +170,12 @@ arch/arm - ARM-based micro-controllers
STATUS: This port has stalled because of development tool issues. Coding
is complete on the basic port (timer, serial console, SPI).
arch/arm/include/lm3s and arch/arm/src/lm3s
These directories contain support for the Luminary LMS family, particularly
for the LM3S6918. The initial, release of this port was included in NuttX version
0.4.6. The current port includes timer, serial console, Ethernet, SSI, and microSD
support. There are working configurations the NuttX OS test, to run the NuttShell
(NSH), the NuttX networking test, and the uIP web server.
arch/arm/include/lm and arch/arm/src/lm
These directories contain support for the Luminary LM3S/4F family. The
initial, release of this port was included in NuttX version 0.4.6. The
current port includes timer, serial console, Ethernet, SSI, and microSD
support. There are working configurations the NuttX OS test, to run the
NuttShell (NSH), the NuttX networking test, and the uIP web server.
arch/arm/include/lpc214x and arch/arm/src/lpc214x
These directories provide support for NXP LPC214x family of

View File

@@ -47,12 +47,13 @@ config ARCH_CHIP_KINETIS
select ARCH_CORTEXM4
select ARCH_HAVE_MPU
select ARCH_IRQPRIO
select ARCH_HAVE_RAMFUNCS
select ARCH_RAMFUNCS
---help---
Freescale Kinetis Architectures (ARM Cortex-M4)
config ARCH_CHIP_LM3S
config ARCH_CHIP_LM
bool "TI Stellaris"
select ARCH_CORTEXM3
select ARCH_HAVE_MPU
select ARCH_IRQPRIO
---help---
@@ -151,7 +152,7 @@ config ARCH_CHIP
default "dm320" if ARCH_CHIP_DM320
default "imx" if ARCH_CHIP_IMX
default "kinetis" if ARCH_CHIP_KINETIS
default "lm3s" if ARCH_CHIP_LM3S
default "lm" if ARCH_CHIP_LM
default "lpc17xx" if ARCH_CHIP_LPC17XX
default "lpc214x" if ARCH_CHIP_LPC214X
default "lpc2378" if ARCH_CHIP_LPC2378
@@ -274,8 +275,8 @@ endif
if ARCH_CHIP_KINETIS
source arch/arm/src/kinetis/Kconfig
endif
if ARCH_CHIP_LM3S
source arch/arm/src/lm3s/Kconfig
if ARCH_CHIP_LM
source arch/arm/src/lm/Kconfig
endif
if ARCH_CHIP_LPC17XX
source arch/arm/src/lpc17xx/Kconfig

View File

@@ -49,3 +49,11 @@ config ARMV7M_TOOLCHAIN_RAISONANCE
depends on HOST_WINDOWS
endchoice
config ARMV7M_OABI_TOOLCHAIN
bool "OABI (vs EABI)"
default y
depends on ARMV7M_TOOLCHAIN_BUILDROOT
---help---
Most of the older buildroot toolchains are OABI and are named arm-nuttx-elf- vs. arm-nuttx-eabi-

View File

@@ -53,7 +53,7 @@ ifeq ($(filter y, \
endif
ifeq ($(filter y, \
$(CONFIG_KINETIS_BUILDROOT) \
$(CONFIG_LM3S_BUILDROOT) \
$(CONFIG_LM_BUILDROOT) \
$(CONFIG_LPC17_BUILDROOT) \
$(CONFIG_LPC43_BUILDROOT) \
$(CONFIG_SAM3U_BUILDROOT) \
@@ -77,7 +77,7 @@ ifeq ($(filter y, \
endif
ifeq ($(filter y, \
$(CONFIG_KINETIS_CODESOURCERYL) \
$(CONFIG_LM3S_CODESOURCERYL) \
$(CONFIG_LM_CODESOURCERYL) \
$(CONFIG_LPC17_CODESOURCERYL) \
$(CONFIG_LPC43_CODESOURCERYL) \
$(CONFIG_SAM3U_CODESOURCERYL) \
@@ -88,7 +88,7 @@ ifeq ($(filter y, \
endif
ifeq ($(filter y, \
$(CONFIG_KINETIS_CODESOURCERYW) \
$(CONFIG_LM3S_CODESOURCERYW) \
$(CONFIG_LM_CODESOURCERYW) \
$(CONFIG_LPC17_CODESOURCERYW) \
$(CONFIG_LPC43_CODESOURCERYW) \
$(CONFIG_SAM3U_CODESOURCERYW) \
@@ -99,7 +99,7 @@ ifeq ($(filter y, \
endif
ifeq ($(filter y, \
$(CONFIG_KINETIS_DEVKITARM) \
$(CONFIG_LM3S_DEVKITARM) \
$(CONFIG_LM_DEVKITARM) \
$(CONFIG_LPC17_DEVKITARM) \
$(CONFIG_LPC43_DEVKITARM) \
$(CONFIG_SAM3U_DEVKITARM) \
@@ -160,14 +160,15 @@ endif
# NuttX buildroot under Linux or Cygwin
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),BUILDROOT)
# OABI
# CROSSDEV = arm-nuttx-elf-
# ARCROSSDEV = arm-nuttx-elf-
# ARCHCPUFLAGS = -mtune=cortex-m3 -march=armv7-m -mfloat-abi=soft
# EABI
ifeq ($(CONFIG_ARMV7M_OABI_TOOLCHAIN),y)
CROSSDEV = arm-nuttx-elf-
ARCROSSDEV = arm-nuttx-elf-
ARCHCPUFLAGS = -mtune=cortex-m3 -march=armv7-m -mfloat-abi=soft
else
CROSSDEV = arm-nuttx-eabi-
ARCROSSDEV = arm-nuttx-eabi-
ARCHCPUFLAGS = -mcpu=cortex-m3 -mthumb -mfloat-abi=soft
endif
MAXOPTIMIZATION = -Os
endif

View File

@@ -79,9 +79,11 @@ uint32_t *up_doirq(int irq, uint32_t *regs)
uint32_t *savestate;
/* Nested interrupts are not supported in this implementation. If you want
* implemented nested interrupts, you would have to (1) change the way that
* current regs is handled and (2) the design associated with
* CONFIG_ARCH_INTERRUPTSTACK.
* to implement nested interrupts, you would have to (1) change the way that
* current_regs is handled and (2) the design associated with
* CONFIG_ARCH_INTERRUPTSTACK. The savestate variable will not work for
* that purpose as implemented here because only the outermost nested
* interrupt can result in a context switch (it can probably be deleted).
*/
/* Current regs non-zero indicates that we are processing an interrupt;

View File

@@ -0,0 +1,142 @@
/************************************************************************************
* arch/arm/src/armv7-m/vfork.S
*
* 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 "up_vfork.h"
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/************************************************************************************
* Global Symbols
************************************************************************************/
.syntax unified
.thumb
.file "vfork.S"
.globl up_vfork
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: vfork
*
* Description:
* The vfork() function has the same effect as fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns
* from the function in which vfork() was called, or calls any other function before
* successfully calling _exit() or one of the exec family of functions.
*
* This thin layer implements vfork by simply calling up_vfork() with the vfork()
* context as an argument. The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork()and calls task_vforksetup().
* 3) task_vforksetup() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
* - Setup the intput parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must:
* - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls task_vforkstart()
* 6) task_vforkstart() then executes the child thread.
*
* Input Paremeters:
* None
*
* Return:
* Upon successful completion, vfork() returns 0 to the child process and returns
* the process ID of the child process to the parent process. Otherwise, -1 is
* returned to the parent, no child process is created, and errno is set to
* indicate the error.
*
************************************************************************************/
.thumb_func
.globl vfork
.type vfork, function
vfork:
/* Create a stack frame */
mov r0, sp /* Save the value of the stack on entry */
sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */
/* CPU registers */
/* Save the volatile registers */
str r4, [sp, #VFORK_R4_OFFSET]
str r5, [sp, #VFORK_R5_OFFSET]
str r6, [sp, #VFORK_R6_OFFSET]
str r7, [sp, #VFORK_R7_OFFSET]
str r8, [sp, #VFORK_R8_OFFSET]
str r9, [sp, #VFORK_R9_OFFSET]
str r10, [sp, #VFORK_R10_OFFSET]
/* Save the frame pointer, stack pointer, and return address */
str fp, [sp, #VFORK_FP_OFFSET]
str r0, [sp, #VFORK_SP_OFFSET]
str lr, [sp, #VFORK_LR_OFFSET]
/* Floating point registers (not yet) */
/* Then, call up_vfork(), passing it a pointer to the stack structure */
mov r0, sp
bl up_vfork
/* Release the stack data and return the value returned by up_vfork */
ldr lr, [sp, #VFORK_LR_OFFSET]
add sp, sp, #VFORK_SIZEOF
bx lr
.size vfork, .-vfork
.end

View File

@@ -188,7 +188,7 @@ extern uint32_t _ebss; /* End+1 of .bss */
* will create a function named foo that will execute from RAM.
*/
#ifdef CONFIG_BOOT_RAMFUNCS
#ifdef CONFIG_ARCH_RAMFUNCS
# define __ramfunc__ __attribute__ ((section(".ramfunc")))
@@ -204,7 +204,7 @@ extern const uint32_t _framfuncs; /* Copy source address in FLASH */
extern uint32_t _sramfuncs; /* Copy destination start address in RAM */
extern uint32_t _eramfuncs; /* Copy destination start address in RAM */
#endif /* CONFIG_BOOT_RAMFUNCS */
#endif /* CONFIG_ARCH_RAMFUNCS */
#endif /* __ASSEMBLY__ */
/****************************************************************************

View File

@@ -0,0 +1,233 @@
/****************************************************************************
* arch/arm/src/common/up_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 <stdint.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/sched.h>
#include <nuttx/arch.h>
#include <arch/irq.h>
#include "up_vfork.h"
#include "os_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* ARM requires at least a 4-byte stack alignment. For use with EABI and
* floating point, the stack must be aligned to 8-byte addresses.
*/
#ifndef CONFIG_STACK_ALIGNMENT
/* The symbol __ARM_EABI__ is defined by GCC if EABI is being used. If you
* are not using GCC, make sure that CONFIG_STACK_ALIGNMENT is set correctly!
*/
# ifdef __ARM_EABI__
# define CONFIG_STACK_ALIGNMENT 8
# else
# define CONFIG_STACK_ALIGNMENT 4
# endif
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_vfork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* any data other than a variable of type pid_t used to store the return
* value from vfork(), or returns from the function in which vfork() was
* called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions.
*
* The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork()and calls task_vforksetup().
* 3) task_vforksetup() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
* - Setup the intput parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must:
* - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls task_vforkstart()
* 6) task_vforkstart() then executes the child thread.
*
* task_vforkabort() may be called if an error occurs between steps 3 and 6.
*
* Input Paremeters:
* context - Caller context information saved by vfork()
*
* Return:
* Upon successful completion, vfork() returns 0 to the child process and
* returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
*
****************************************************************************/
pid_t up_vfork(const struct vfork_s *context)
{
_TCB *parent = (FAR _TCB *)g_readytorun.head;
_TCB *child;
size_t stacksize;
uint32_t newsp;
uint32_t newfp;
uint32_t stackutil;
int ret;
svdbg("r4:%08x r5:%08x r6:%08x r7:%08x\n",
context->r4, context->r5, context->r6, context->r7);
svdbg("r8:%08x r9:%08x r10:%08x\n",
context->r8, context->r9, context->r10);
svdbg("fp:%08x sp:%08x lr:%08x\n",
context->fp, context->sp, context->lr);
/* Allocate and initialize a TCB for the child task. */
child = task_vforksetup((start_t)(context->lr & ~1));
if (!child)
{
sdbg("task_vforksetup failed\n");
return (pid_t)ERROR;
}
svdbg("Parent=%p Child=%p\n", parent, child);
/* Get the size of the parent task's stack. Due to alignment operations,
* the adjusted stack size may be smaller than the stack size originally
* requrested.
*/
stacksize = parent->adj_stack_size + CONFIG_STACK_ALIGNMENT - 1;
/* Allocate the stack for the TCB */
ret = up_create_stack(child, stacksize);
if (ret != OK)
{
sdbg("up_create_stack failed: %d\n", ret);
task_vforkabort(child, -ret);
return (pid_t)ERROR;
}
/* How much of the parent's stack was utilized? The ARM uses
* a push-down stack so that the current stack pointer should
* be lower than the initial, adjusted stack pointer. The
* stack usage should be the difference between those two.
*/
DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp);
stackutil = (uint32_t)parent->adj_stack_ptr - context->sp;
svdbg("stacksize:%d stackutil:%d\n", stacksize, stackutil);
/* Make some feeble effort to perserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the
* user follows all of the caveats of vfor() usage, even this feeble
* effort is overkill.
*/
newsp = (uint32_t)child->adj_stack_ptr - stackutil;
memcpy((void *)newsp, (const void *)context->sp, stackutil);
/* Was there a frame pointer in place before? */
if (context->fp <= (uint32_t)parent->adj_stack_ptr &&
context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize)
{
uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp;
newfp = (uint32_t)child->adj_stack_ptr - frameutil;
}
else
{
newfp = context->fp;
}
svdbg("Old stack base:%08x SP:%08x FP:%08x\n",
parent->adj_stack_ptr, context->sp, context->fp);
svdbg("New stack base:%08x SP:%08x FP:%08x\n",
child->adj_stack_ptr, newsp, newfp);
/* Update the stack pointer, frame pointer, and volatile registers. When
* the child TCB was initialized, all of the values were set to zero.
* up_initial_state() altered a few values, but the return value in R0
* should be cleared to zero, providing the indication to the newly started
* child thread.
*/
child->xcp.regs[REG_R4] = context->r4; /* Volatile register r4 */
child->xcp.regs[REG_R5] = context->r5; /* Volatile register r5 */
child->xcp.regs[REG_R6] = context->r6; /* Volatile register r6 */
child->xcp.regs[REG_R7] = context->r7; /* Volatile register r7 */
child->xcp.regs[REG_R8] = context->r8; /* Volatile register r8 */
child->xcp.regs[REG_R9] = context->r9; /* Volatile register r9 */
child->xcp.regs[REG_R10] = context->r10; /* Volatile register r10 */
child->xcp.regs[REG_FP] = newfp; /* Frame pointer */
child->xcp.regs[REG_SP] = newsp; /* Stack pointer */
/* And, finally, start the child task. On a failure, task_vforkstart()
* will discard the TCB by calling task_vforkabort().
*/
return task_vforkstart(child);
}

View File

@@ -0,0 +1,88 @@
/****************************************************************************
* arch/arm/src/common/up_vfork.h
*
* 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.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_ARM_VFORK_H
#define __ARCH_ARM_SRC_ARM_VFORK_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define VFORK_R4_OFFSET (0*4) /* Volatile register r4 */
#define VFORK_R5_OFFSET (1*4) /* Volatile register r5 */
#define VFORK_R6_OFFSET (2*4) /* Volatile register r6 */
#define VFORK_R7_OFFSET (3*4) /* Volatile register r7 */
#define VFORK_R8_OFFSET (4*4) /* Volatile register r8 */
#define VFORK_R9_OFFSET (5*4) /* Volatile register r9 */
#define VFORK_R10_OFFSET (6*4) /* Volatile register r10 */
#define VFORK_FP_OFFSET (7*4) /* Frame pointer */
#define VFORK_SP_OFFSET (8*4) /* Stack pointer*/
#define VFORK_LR_OFFSET (9*4) /* Return address*/
#define VFORK_SIZEOF (10*4)
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
struct vfork_s
{
/* CPU registers */
uint32_t r4; /* Volatile register r4 */
uint32_t r5; /* Volatile register r5 */
uint32_t r6; /* Volatile register r6 */
uint32_t r7; /* Volatile register r7 */
uint32_t r8; /* Volatile register r8 */
uint32_t r9; /* Volatile register r9 */
uint32_t r10; /* Volatile register r10 */
uint32_t fp; /* Frame pointer */
uint32_t sp; /* Stack pointer*/
uint32_t lr; /* Return address*/
/* Floating point registers (not yet) */
};
#endif
#endif /* __ARCH_ARM_SRC_ARM_VFORK_H */

View File

@@ -1,7 +1,7 @@
############################################################################
# arch/arm/src/stm32/Make.defs
#
# Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
# Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@@ -39,15 +39,16 @@ else
HEAD_ASRC = stm32_vectors.S
endif
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S \
vfork.S
CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c \
up_createstack.c up_mdelay.c up_udelay.c up_exit.c \
up_initialize.c up_initialstate.c up_interruptcontext.c \
up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c \
up_releasepending.c up_releasestack.c up_reprioritizertr.c \
up_schedulesigaction.c up_sigdeliver.c up_systemreset.c \
up_unblocktask.c up_usestack.c up_doirq.c up_hardfault.c up_svcall.c \
up_stackcheck.c
up_unblocktask.c up_usestack.c up_doirq.c up_hardfault.c \
up_svcall.c up_stackcheck.c up_vfork.c
ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
CMN_ASRCS += up_exception.S

View File

@@ -35,7 +35,7 @@
/* Provides standard flash access functions, to be used by the flash mtd driver.
* The interface is defined in the include/nuttx/progmem.h
*
*
* Requirements during write/erase operations on FLASH:
* - HSI must be ON.
* - Low Power Modes are not permitted during write/erase
@@ -80,7 +80,7 @@ void stm32_flash_unlock(void)
if (getreg32(STM32_FLASH_CR) & FLASH_CR_LOCK)
{
/* Unlock sequence */
putreg32(FLASH_KEY1, STM32_FLASH_KEYR);
putreg32(FLASH_KEY2, STM32_FLASH_KEYR);
}
@@ -112,6 +112,11 @@ uint16_t up_progmem_pagesize(uint16_t page)
int up_progmem_getpage(uint32_t addr)
{
if (addr >= STM32_FLASH_BASE)
{
addr -= STM32_FLASH_BASE;
}
if (addr >= STM32_FLASH_SIZE)
{
return -EFAULT;
@@ -131,14 +136,14 @@ int up_progmem_erasepage(uint16_t page)
}
/* Get flash ready and begin erasing single page */
if (!(getreg32(STM32_RCC_CR) & RCC_CR_HSION))
{
return -EPERM;
}
stm32_flash_unlock();
modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PER);
putreg32(page * STM32_FLASH_PAGESIZE, STM32_FLASH_AR);
modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_STRT);
@@ -146,10 +151,10 @@ int up_progmem_erasepage(uint16_t page)
while(getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) up_waste();
modifyreg32(STM32_FLASH_CR, FLASH_CR_PER, 0);
/* Verify */
for (addr = page * STM32_FLASH_PAGESIZE + STM32_FLASH_BASE, count = STM32_FLASH_PAGESIZE;
for (addr = page * STM32_FLASH_PAGESIZE + STM32_FLASH_BASE, count = STM32_FLASH_PAGESIZE;
count; count-=4, addr += 4)
{
if (getreg32(addr) != 0xffffffff)
@@ -173,8 +178,8 @@ int up_progmem_ispageerased(uint16_t page)
}
/* Verify */
for (addr = page * STM32_FLASH_PAGESIZE + STM32_FLASH_BASE, count = STM32_FLASH_PAGESIZE;
for (addr = page * STM32_FLASH_PAGESIZE + STM32_FLASH_BASE, count = STM32_FLASH_PAGESIZE;
count; count--, addr++)
{
if (getreg8(addr) != 0xff)
@@ -200,6 +205,11 @@ int up_progmem_write(uint32_t addr, const void *buf, size_t count)
/* Check for valid address range */
if (addr >= STM32_FLASH_BASE)
{
addr -= STM32_FLASH_BASE;
}
if ((addr+count) >= STM32_FLASH_SIZE)
{
return -EFAULT;
@@ -213,10 +223,10 @@ int up_progmem_write(uint32_t addr, const void *buf, size_t count)
}
stm32_flash_unlock();
modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PG);
for (addr += STM32_FLASH_BASE; count; count--, hword++, addr+=2)
for (addr += STM32_FLASH_BASE; count; count-=2, hword++, addr+=2)
{
/* Write half-word and wait to complete */
@@ -237,7 +247,6 @@ int up_progmem_write(uint32_t addr, const void *buf, size_t count)
modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0);
return -EIO;
}
}
modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0);

View File

@@ -79,22 +79,22 @@
#if SERIAL_HAVE_DMA
/* Verify that DMA has been enabled an the DMA channel has been defined.
* NOTE: These assignments may only be true for the F4.
# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
/* Verify that DMA has been enabled and the DMA channel has been defined.
*/
# if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART6_RXDMA)
# ifndef CONFIG_STM32_DMA2
# error STM32 USART1/6 receive DMA requires CONFIG_STM32_DMA2
# if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART6_RXDMA)
# ifndef CONFIG_STM32_DMA2
# error STM32 USART1/6 receive DMA requires CONFIG_STM32_DMA2
# endif
# endif
# endif
# if defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) || \
# if defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) || \
defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA)
# ifndef CONFIG_STM32_DMA1
# error STM32 USART2/3/4/5 receive DMA requires CONFIG_STM32_DMA1
# ifndef CONFIG_STM32_DMA1
# error STM32 USART2/3/4/5 receive DMA requires CONFIG_STM32_DMA1
# endif
# endif
# endif
/* Currently RS-485 support cannot be enabled when RXDMA is in use due to lack
* of testing - RS-485 support was developed on STM32F1x
@@ -114,28 +114,52 @@
* the following in the board.h file.
*/
# if defined(CONFIG_USART1_RXDMA) && !defined(DMAMAP_USART1_RX)
# error "USART1 DMA channel not defined (DMAMAP_USART1_RX)"
# endif
# if defined(CONFIG_USART1_RXDMA) && !defined(DMAMAP_USART1_RX)
# error "USART1 DMA channel not defined (DMAMAP_USART1_RX)"
# endif
# if defined(CONFIG_USART2_RXDMA) && !defined(DMAMAP_USART2_RX)
# error "USART2 DMA channel not defined (DMAMAP_USART2_RX)"
# endif
# if defined(CONFIG_USART2_RXDMA) && !defined(DMAMAP_USART2_RX)
# error "USART2 DMA channel not defined (DMAMAP_USART2_RX)"
# endif
# if defined(CONFIG_USART3_RXDMA) && !defined(DMAMAP_USART3_RX)
# error "USART3 DMA channel not defined (DMAMAP_USART3_RX)"
# endif
# if defined(CONFIG_USART3_RXDMA) && !defined(DMAMAP_USART3_RX)
# error "USART3 DMA channel not defined (DMAMAP_USART3_RX)"
# endif
# if defined(CONFIG_UART4_RXDMA) && !defined(DMAMAP_UART4_RX)
# error "UART4 DMA channel not defined (DMAMAP_UART4_RX)"
# endif
# if defined(CONFIG_UART4_RXDMA) && !defined(DMAMAP_UART4_RX)
# error "UART4 DMA channel not defined (DMAMAP_UART4_RX)"
# endif
# if defined(CONFIG_UART5_RXDMA) && !defined(DMAMAP_UART5_RX)
# error "UART5 DMA channel not defined (DMAMAP_UART5_RX)"
# endif
# if defined(CONFIG_UART5_RXDMA) && !defined(DMAMAP_UART5_RX)
# error "UART5 DMA channel not defined (DMAMAP_UART5_RX)"
# endif
# if defined(CONFIG_USART6_RXDMA) && !defined(DMAMAP_USART6_RX)
# error "USART6 DMA channel not defined (DMAMAP_USART6_RX)"
# endif
# elif defined(CONFIG_STM32_STM32F10XX)
# if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART2_RXDMA) || \
defined(CONFIG_USART3_RXDMA)
# ifndef CONFIG_STM32_DMA1
# error STM32 USART1/2/3 receive DMA requires CONFIG_STM32_DMA1
# endif
# endif
# if defined(CONFIG_UART4_RXDMA)
# ifndef CONFIG_STM32_DMA2
# error STM32 USART4 receive DMA requires CONFIG_STM32_DMA2
# endif
# endif
/* There are no optional DMA channel assignments for the F1 */
# define DMAMAP_USART1_RX DMACHAN_USART1_RX
# define DMAMAP_USART2_RX DMACHAN_USART2_RX
# define DMAMAP_USART3_RX DMACHAN_USART3_RX
# define DMAMAP_UART4_RX DMACHAN_USART4_RX
# if defined(CONFIG_USART6_RXDMA) && !defined(DMAMAP_USART6_RX)
# error "USART6 DMA channel not defined (DMAMAP_USART6_RX)"
# endif
/* The DMA buffer size when using RX DMA to emulate a FIFO.
@@ -169,6 +193,27 @@
# error "Unknown STM32 DMA"
# endif
/* DMA control word */
# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
# define SERIAL_DMA_CONTROL_WORD \
(DMA_SCR_DIR_P2M | \
DMA_SCR_CIRC | \
DMA_SCR_MINC | \
DMA_SCR_PSIZE_8BITS | \
DMA_SCR_MSIZE_8BITS | \
CONFIG_USART_DMAPRIO | \
DMA_SCR_PBURST_SINGLE | \
DMA_SCR_MBURST_SINGLE)
# else
# define SERIAL_DMA_CONTROL_WORD \
(DMA_CCR_CIRC | \
DMA_CCR_MINC | \
DMA_CCR_PSIZE_8BITS | \
DMA_CCR_MSIZE_8BITS | \
CONFIG_USART_DMAPRIO)
# endif
#endif
/* Power management definitions */
@@ -1115,14 +1160,7 @@ static int up_dma_setup(struct uart_dev_s *dev)
priv->usartbase + STM32_USART_DR_OFFSET,
(uint32_t)priv->rxfifo,
RXDMA_BUFFER_SIZE,
DMA_SCR_DIR_P2M |
DMA_SCR_CIRC |
DMA_SCR_MINC |
DMA_SCR_PSIZE_8BITS |
DMA_SCR_MSIZE_8BITS |
CONFIG_USART_DMAPRIO |
DMA_SCR_PBURST_SINGLE |
DMA_SCR_MBURST_SINGLE);
SERIAL_DMA_CONTROL_WORD);
/* Reset our DMA shadow pointer to match the address just
* programmed above.

View File

@@ -140,12 +140,9 @@
# undef HAVE_CONSOLE
#endif
/* DMA support is only provided if CONFIG_ARCH_DMA is in the NuttX configuration.
* Furthermore, DMA support is currently only implemented for the F4 (but could be
* extended to the F1 and F2 with a little effort in the DMA code.
*/
/* DMA support is only provided if CONFIG_ARCH_DMA is in the NuttX configuration */
#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA) || !defined(CONFIG_STM32_STM32F40XX)
#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA)
# undef CONFIG_USART1_RXDMA
# undef CONFIG_USART2_RXDMA
# undef CONFIG_USART3_RXDMA

View File

@@ -303,13 +303,13 @@ static int stm32_dmainterrupt(int irq, void *context)
}
dmach = &g_dma[chndx];
/* Get the interrupt status (for this channel only) -- not currently used */
/* Get the interrupt status (for this channel only) */
isr = dmabase_getreg(dmach, STM32_DMA_ISR_OFFSET) & DMA_ISR_CHAN_MASK(dmach->chan);
/* Disable the DMA channel */
/* Clear the interrupts we are handling */
stm32_dmachandisable(dmach);
dmabase_putreg(dmach, STM32_DMA_IFCR_OFFSET, isr);
/* Invoke the callback */
@@ -528,14 +528,34 @@ void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, bool
ccr = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET);
ccr |= DMA_CCR_EN;
/* Once half of the bytes are transferred, the half-transfer flag (HTIF) is
* set and an interrupt is generated if the Half-Transfer Interrupt Enable
* bit (HTIE) is set. At the end of the transfer, the Transfer Complete Flag
* (TCIF) is set and an interrupt is generated if the Transfer Complete
* Interrupt Enable bit (TCIE) is set.
/* In normal mode, interrupt at either half or full completion. In circular mode,
* always interrupt on buffer wrap, and optionally interrupt at the halfway point.
*/
ccr |= (half ? (DMA_CCR_HTIE|DMA_CCR_TEIE) : (DMA_CCR_TCIE|DMA_CCR_TEIE));
if ((ccr & DMA_CCR_CIRC) == 0)
{
/* Once half of the bytes are transferred, the half-transfer flag (HTIF) is
* set and an interrupt is generated if the Half-Transfer Interrupt Enable
* bit (HTIE) is set. At the end of the transfer, the Transfer Complete Flag
* (TCIF) is set and an interrupt is generated if the Transfer Complete
* Interrupt Enable bit (TCIE) is set.
*/
ccr |= (half ? (DMA_CCR_HTIE|DMA_CCR_TEIE) : (DMA_CCR_TCIE|DMA_CCR_TEIE));
}
else
{
/* In nonstop mode, when the transfer completes it immediately resets
* and starts again. The transfer-complete interrupt is thus always
* enabled, and the half-complete interrupt can be used in circular
* mode to determine when the buffer is half-full, or in double-buffered
* mode to determine when one of the two buffers is full.
*/
ccr |= (half ? DMA_CCR_HTIE : 0) | DMA_CCR_TCIE | DMA_CCR_TEIE;
}
dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, ccr);
}
@@ -558,6 +578,24 @@ void stm32_dmastop(DMA_HANDLE handle)
stm32_dmachandisable(dmach);
}
/****************************************************************************
* Name: stm32_dmaresidual
*
* Description:
* Returns the number of bytes remaining to be transferred
*
* Assumptions:
* - DMA handle allocated by stm32_dmachannel()
*
****************************************************************************/
size_t stm32_dmaresidual(DMA_HANDLE handle)
{
struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
return dmachan_getreg(dmach, STM32_DMACHAN_CNDTR_OFFSET);
}
/****************************************************************************
* Name: stm32_dmasample
*

View File

@@ -94,7 +94,6 @@ struct stm32_dma_s
uint8_t irq; /* DMA stream IRQ number */
uint8_t shift; /* ISR/IFCR bit shift value */
uint8_t channel; /* DMA channel number (0-7) */
bool nonstop; /* Stream is configured in a non-stopping mode. */
sem_t sem; /* Used to wait for DMA channel to become available */
uint32_t base; /* DMA register channel base address */
dma_callback_t callback; /* Callback invoked when the DMA completes */
@@ -728,7 +727,6 @@ void stm32_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
DMA_SCR_DBM|DMA_SCR_CIRC|
DMA_SCR_PBURST_MASK|DMA_SCR_MBURST_MASK);
regval |= scr;
dmast->nonstop = (scr & (DMA_SCR_DBM|DMA_SCR_CIRC)) != 0;
dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, regval);
}
@@ -764,7 +762,12 @@ void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, bool
scr = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET);
scr |= DMA_SCR_EN;
if (!dmast->nonstop)
/* In normal mode, interrupt at either half or full completion. In circular
* and double-buffered modes, always interrupt on buffer wrap, and optionally
* interrupt at the halfway point.
*/
if ((scr & (DMA_SCR_DBM|DMA_SCR_CIRC)) == 0)
{
/* Once half of the bytes are transferred, the half-transfer flag (HTIF) is
* set and an interrupt is generated if the Half-Transfer Interrupt Enable
@@ -777,7 +780,7 @@ void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, bool
}
else
{
/* In nonstop mode, when the transfer completes it immediately resets
/* In non-stop modes, when the transfer completes it immediately resets
* and starts again. The transfer-complete interrupt is thus always
* enabled, and the half-complete interrupt can be used in circular
* mode to determine when the buffer is half-full, or in double-buffered

View File

@@ -49,6 +49,20 @@ if ELF
source binfmt/libelf/Kconfig
endif
config BUILTIN
bool "Support Builtin Applications"
default n
---help---
Enable support for builtin applications. This features assigns a string
name to an application and in addition if FS_BINFS is defined, retaining
those names in a file system from which they can be executed. This feature
is also the underlying requirement to support built-in applications in the
NuttShell (NSH).
if BUILTIN
source binfmt/libbuiltin/Kconfig
endif
endif
config PIC

View File

@@ -1,7 +1,7 @@
############################################################################
# nxflat/Makefile
#
# Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
# Copyright (C) 2007-2009, 2012-2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@@ -65,6 +65,7 @@ DEPPATH = --dep-path .
include libnxflat$(DELIM)Make.defs
include libelf$(DELIM)Make.defs
include libbuiltin$(DELIM)Make.defs
BINFMT_AOBJS = $(BINFMT_ASRCS:.S=$(OBJEXT))
BINFMT_COBJS = $(BINFMT_CSRCS:.c=$(OBJEXT))

View File

@@ -1,7 +1,7 @@
/****************************************************************************
* binfmt/binfmt_exec.c
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,6 @@
#include <nuttx/config.h>
#include <string.h>
#include <sched.h>
#include <debug.h>
#include <errno.h>
@@ -96,6 +95,8 @@ int exec(FAR const char *filename, FAR const char **argv,
struct binary_s bin;
int ret;
/* Load the module into memory */
memset(&bin, 0, sizeof(struct binary_s));
bin.filename = filename;
bin.exports = exports;
@@ -108,7 +109,9 @@ int exec(FAR const char *filename, FAR const char **argv,
return ERROR;
}
ret = exec_module(&bin, 50);
/* Then start the module */
ret = exec_module(&bin);
if (ret < 0)
{
bdbg("ERROR: Failed to execute program '%s'\n", filename);

View File

@@ -1,7 +1,7 @@
/****************************************************************************
* binfmt/binfmt_execmodule.c
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -47,6 +47,7 @@
#include <errno.h>
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include <nuttx/binfmt/binfmt.h>
#include "os_internal.h"
@@ -143,7 +144,7 @@ static inline int exec_ctors(FAR const struct binary_s *binp)
*
****************************************************************************/
int exec_module(FAR const struct binary_s *binp, int priority)
int exec_module(FAR const struct binary_s *binp)
{
FAR _TCB *tcb;
#ifndef CONFIG_CUSTOM_STACK
@@ -167,7 +168,7 @@ int exec_module(FAR const struct binary_s *binp, int priority)
/* Allocate a TCB for the new task. */
tcb = (FAR _TCB*)zalloc(sizeof(_TCB));
tcb = (FAR _TCB*)kzalloc(sizeof(_TCB));
if (!tcb)
{
err = ENOMEM;
@@ -177,7 +178,7 @@ int exec_module(FAR const struct binary_s *binp, int priority)
/* Allocate the stack for the new task */
#ifndef CONFIG_CUSTOM_STACK
stack = (FAR uint32_t*)malloc(binp->stacksize);
stack = (FAR uint32_t*)kmalloc(binp->stacksize);
if (!tcb)
{
err = ENOMEM;
@@ -186,12 +187,12 @@ int exec_module(FAR const struct binary_s *binp, int priority)
/* Initialize the task */
ret = task_init(tcb, binp->filename, priority, stack,
ret = task_init(tcb, binp->filename, binp->priority, stack,
binp->stacksize, binp->entrypt, binp->argv);
#else
/* Initialize the task */
ret = task_init(tcb, binp->filename, priority, stack,
ret = task_init(tcb, binp->filename, binp->priority, stack,
binp->entrypt, binp->argv);
#endif
if (ret < 0)
@@ -201,6 +202,9 @@ int exec_module(FAR const struct binary_s *binp, int priority)
goto errout_with_stack;
}
/* Note that tcb->flags are not modified. 0=normal task */
/* tcb->flags |= TCB_FLAG_TTYPE_TASK; */
/* Add the D-Space address as the PIC base address. By convention, this
* must be the first allocated address space.
*/
@@ -257,14 +261,14 @@ errout_with_stack:
#ifndef CONFIG_CUSTOM_STACK
tcb->stack_alloc_ptr = NULL;
sched_releasetcb(tcb);
free(stack);
kfree(stack);
#else
sched_releasetcb(tcb);
#endif
goto errout;
errout_with_tcb:
free(tcb);
kfree(tcb);
errout:
errno = err;
bdbg("returning errno: %d\n", err);

View File

@@ -66,6 +66,39 @@
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: load_default_priority
*
* Description:
* Set the default priority of the module to be loaded. This may be
* changed (1) by the actions of the binary format's load() method if
* the binary format contains priority informaition, or (2) by the user
* between calls to load_module() and exec_module().
*
* Returned Value:
* Zero (OK) is returned on success; Otherwise, -1 (ERROR) is returned and
* the errno variable is set appropriately.
*
****************************************************************************/
static int load_default_priority(FAR struct binary_s *bin)
{
struct sched_param param;
/* Get the priority of this thread */
ret = sched_getparam(0, &param);
if (ret < 0)
{
bdbg("ERROR: sched_getparam failed: %d\n", errno);
return ERROR;
}
/* Save that as the priority of child thread */
bin->priority = param.sched_priority;
}
/****************************************************************************
* Name: load_absmodule
*
@@ -145,6 +178,16 @@ int load_module(FAR struct binary_s *bin)
if (bin && bin->filename)
#endif
{
/* Set the default priority of the new program. */
ret = load_default_priority(bin)
if (ret < 0)
{
/* The errno is already set in this case */
return ERROR;
}
/* Were we given a relative path? Or an absolute path to the file to
* be loaded? Absolute paths start with '/'.
*/

196
nuttx/binfmt/builtin.c Normal file
View File

@@ -0,0 +1,196 @@
/****************************************************************************
* binfmt/builtin.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/binfmt/binfmt.h>
#include <nuttx/binfmt/builtin.h>
#ifdef CONFIG_BUILTIN
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static int builtin_loadbinary(FAR struct binary_s *binp);
/****************************************************************************
* Private Data
****************************************************************************/
static struct binfmt_s g_builtin_binfmt =
{
NULL, /* next */
builtin_loadbinary, /* load */
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: builtin_loadbinary
*
* Description:
* Verify that the file is an builtin binary.
*
****************************************************************************/
static int builtin_loadbinary(struct binary_s *binp)
{
FAR const char *filename;
int fd;
int index;
int ret;
bvdbg("Loading file: %s\n", binp->filename);
/* Open the binary file for reading (only) */
fd = open(filename, O_RDONLY);
if (fd < 0)
{
int errval = errno;
bdbg("ERROR: Failed to open binary %s: %d\n", filename, errval);
return -errval;
}
/* If this file is a BINFS file system, then we can recover the name of
* the file using the FIOC_FILENAME ioctl() call.
*/
ret = ioctl(fd, FIOC_FILENAME, (unsigned long)((uintptr_t)&filename));
if (ret < 0)
{
int errval = errno;
bdbg("ERROR: FIOC_FILENAME ioctl failed: %d\n", errval);
return -errval;
}
/* Other file systems may also support FIOC_FILENAME, so the real proof
* is that we can look up the index to this name in g_builtins[].
*/
index = builtin_isavail(filename);
if (index < 0)
{
int errval = errno;
bdbg("ERROR: %s is not a builtin application\n", filename);
return -errval;
}
/* Return the load information. NOTE: that there is no way to configure
* the priority. That is a bug and needs to be fixed.
*/
binp->entrypt = g_builtins[index].main;
binp->stacksize = g_builtins[index].stacksize;
binp->priority = g_builtins[index].priority;
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: builtin_initialize
*
* Description:
* Builtin support is built unconditionally. However, it order to
* use this binary format, this function must be called during system
* format in order to register the builtin binary format.
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int builtin_initialize(void)
{
int ret;
/* Register ourselves as a binfmt loader */
bvdbg("Registering Builtin Loader\n");
ret = register_binfmt(&g_builtin_binfmt);
if (ret != 0)
{
bdbg("Failed to register binfmt: %d\n", ret);
}
return ret;
}
/****************************************************************************
* Name: builtin_uninitialize
*
* Description:
* Unregister the builtin binary loader
*
* Returned Value:
* None
*
****************************************************************************/
void builtin_uninitialize(void)
{
unregister_binfmt(&g_builtin_binfmt);
}
#endif /* CONFIG_BUILTIN */

View File

@@ -183,7 +183,7 @@ static int elf_loadbinary(struct binary_s *binp)
bvdbg("Loading file: %s\n", binp->filename);
/* Initialize the xflat library to load the program binary. */
/* Initialize the ELF library to load the program binary. */
ret = elf_init(binp->filename, &loadinfo);
elf_dumploadinfo(&loadinfo);

View File

@@ -0,0 +1,4 @@
#
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#

View File

@@ -0,0 +1,52 @@
############################################################################
# binfmt/libbuiltin/Make.defs
#
# 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.
#
############################################################################
ifeq ($(CONFIG_BUILTIN),y)
# Builtin application interfaces
BINFMT_CSRCS += builtin.c
# Builtin library interfaces
BINFMT_CSRCS += libbuiltin_getname.c libbuiltin_isavail.c
# Hook the libbuiltin subdirectory into the build
VPATH += libbuiltin
SUBDIRS += libbuiltin
DEPPATH += --dep-path libbuiltin
endif

View File

@@ -0,0 +1,92 @@
/****************************************************************************
* binfmt/libbuiltin/libbuiltin_getname.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 <nuttx/binfmt/builtin.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: builtin_getname
*
* Description:
* Return the name of the application at index in the table of builtin
* applications.
*
****************************************************************************/
FAR const char *builtin_getname(int index)
{
if (index < 0 || index >= number_builtins())
{
return NULL;
}
return g_builtins[index].name;
}

View File

@@ -1,13 +1,15 @@
/****************************************************************************
* apps/namedaps/exec_namedapp.c
* binfmt/libbuiltin/libbuiltin_isavail.c
*
* Originally by:
*
* Copyright (C) 2011 Uros Platise. All rights reserved.
* Author: Uros Platise <uros.platise@isotel.eu>
*
* With updates, modifications, and general maintenance by:
* With subsequent updates, modifications, and general maintenance by:
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Auther: Gregory Nutt <gnutt@nuttx.org>
* 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
@@ -43,13 +45,16 @@
****************************************************************************/
#include <nuttx/config.h>
#include <apps/apps.h>
#include <sched.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include "namedapp.h"
#include <nuttx/binfmt/builtin.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
@@ -72,26 +77,7 @@
****************************************************************************/
/****************************************************************************
* Name: namedapp_getname
*
* Description:
* Return the name of the application at index in the table of named
* applications.
*
****************************************************************************/
const char *namedapp_getname(int index)
{
if (index < 0 || index >= number_namedapps())
{
return NULL;
}
return namedapps[index].name;
}
/****************************************************************************
* Name: namedapp_isavail
* Name: builtin_isavail
*
* Description:
* Return the index into the table of applications for the applicaiton with
@@ -99,13 +85,13 @@ const char *namedapp_getname(int index)
*
****************************************************************************/
int namedapp_isavail(FAR const char *appname)
int builtin_isavail(FAR const char *appname)
{
int i;
for (i = 0; namedapps[i].name; i++)
for (i = 0; g_builtins[i].name; i++)
{
if (!strcmp(namedapps[i].name, appname))
if (!strncmp(g_builtins[i].name, appname, NAME_MAX))
{
return i;
}
@@ -114,74 +100,3 @@ int namedapp_isavail(FAR const char *appname)
set_errno(ENOENT);
return ERROR;
}
/****************************************************************************
* Name: namedapp_isavail
*
* Description:
* Execute the application with name 'appname', providing the arguments
* in the argv[] array.
*
* Returned Value:
* On success, the task ID of the named application is returned. On
* failure, -1 (ERROR) is returned an the errno value is set appropriately.
*
****************************************************************************/
int exec_namedapp(FAR const char *appname, FAR const char **argv)
{
pid_t pid;
int index;
/* Verify that an application with this name exists */
index = namedapp_isavail(appname);
if (index >= 0)
{
/* Disable pre-emption. This means that although we start the named
* application here, it will not actually run until pre-emption is
* re-enabled below.
*/
sched_lock();
/* Start the named application task */
pid = TASK_CREATE(namedapps[index].name, namedapps[index].priority,
namedapps[index].stacksize, namedapps[index].main,
(argv) ? &argv[1] : (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 (pid > 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 = namedapps[index].priority;
sched_setscheduler(pid, SCHED_RR, &param);
}
#endif
/* Now let the named application run */
sched_unlock();
/* Return the task ID of the new task if the task was sucessfully
* started. Otherwise, pid will be ERROR (and the errno value will
* be set appropriately).
*/
return pid;
}
/* Return ERROR with errno set appropriately */
return ERROR;
}

View File

@@ -334,6 +334,12 @@ defconfig -- This is a configuration file similar to the Linux
CONFIG_TASK_NAME_SIZE - Specifies that maximum size of a
task name to save in the TCB. Useful if scheduler
instrumentation is selected. Set to zero to disable.
CONFIG_SCHED_HAVE_PARENT - Remember the ID of the parent thread
when a new child thread is created. This support enables some
additional features (such as SIGCHLD) and modifies the behavior
of other interfaces. For example, it makes waitpid() more
standards complete by restricting the waited-for tasks to the
children of the caller. Default: disabled.
CONFIG_START_YEAR, CONFIG_START_MONTH, CONFIG_START_DAY -
Used to initialize the internal time logic.
CONFIG_GREGORIAN_TIME - Enables Gregorian time conversions.
@@ -400,7 +406,7 @@ defconfig -- This is a configuration file similar to the Linux
CONFIG_SCHED_WORKSTACKSIZE - The stack size allocated for the worker
thread. Default: CONFIG_IDLETHREAD_STACKSIZE.
CONFIG_SIG_SIGWORK - The signal number that will be used to wake-up
the worker thread. Default: 4
the worker thread. Default: 17
CONFIG_SCHED_LPWORK. If CONFIG_SCHED_WORKQUEUE is defined, then a single
work queue is created by default. If CONFIG_SCHED_LPWORK is also defined
then an additional, lower-priority work queue will also be created. This
@@ -412,7 +418,12 @@ defconfig -- This is a configuration file similar to the Linux
checks for work in units of microseconds. Default: 50*1000 (50 MS).
CONFIG_SCHED_LPWORKSTACKSIZE - The stack size allocated for the lower
priority worker thread. Default: CONFIG_IDLETHREAD_STACKSIZE.
CONFIG_SCHED_WAITPID - Enables the waitpid() API
CONFIG_SCHED_WAITPID - Enables the waitpid() interface in a default,
non-standard mode (non-standard in the sense that the waited for
PID need not be child of the caller). If SCHED_HAVE_PARENT is
also defined, then this setting will modify the behavior or
waitpid() (making more spec compliant) and will enable the
waitid() and wait() interfaces as well.
CONFIG_SCHED_ATEXIT - Enables the atexit() API
CONFIG_SCHED_ATEXIT_MAX - By default if CONFIG_SCHED_ATEXIT is
selected, only a single atexit() function is supported. That number
@@ -426,6 +437,23 @@ defconfig -- This is a configuration file similar to the Linux
where 'app' is the application name. If not defined, CONFIG_USER_ENTRYPOINT
defaults to user_start.
Signal Numbers:
CONFIG_SIG_SIGUSR1 - Value of standard user signal 1 (SIGUSR1).
Default: 1
CONFIG_SIG_SIGUSR2 - Value of standard user signal 2 (SIGUSR2).
Default: 2
CONFIG_SIG_SIGALARM - Default the standard signal used with POSIX
timers (SIGALRM). Default: 3
CONFIG_SIG_SIGCHLD - The SIGCHLD signal is sent to the parent of a child
process when it exits, is interrupted (stopped), or resumes after being
interrupted. Default: 4
CONFIG_SIG_SIGCONDTIMEDOUT - This non-standard signal number is used in
the implementation of pthread_cond_timedwait(). Default 16.
CONFIG_SIG_SIGWORK - SIGWORK is a non-standard signal used to wake up
the internal NuttX worker thread. Default: 17.
Binary Loaders:
CONFIG_BINFMT_DISABLE - By default, support for loadable binary formats
is built.
@@ -1562,7 +1590,7 @@ defconfig -- This is a configuration file similar to the Linux
operation from FLASH but must copy initialized .data sections to RAM.
CONFIG_BOOT_COPYTORAM - Some configurations boot in FLASH
but copy themselves entirely into RAM for better performance.
CONFIG_BOOT_RAMFUNCS - Other configurations may copy just some functions
CONFIG_ARCH_RAMFUNCS - Other configurations may copy just some functions
into RAM, either for better performance or for errata workarounds.
CONFIG_STACK_ALIGNMENT - Set if the your application has specific
stack alignment requirements (may not be supported
@@ -1936,6 +1964,11 @@ configs/z8f64200100kit
development kit, Z8F6423 part, and the Zilog ZDS-II Windows command line
tools. The development environment is Cygwin under WinXP.
configs/zp214xpa
This port is for the NXP LPC2148 as provided on the The0.net
ZPA213X/4XPA development board. Includes support for the
UG-2864AMBAG01 OLED also from The0.net
Configuring NuttX
^^^^^^^^^^^^^^^^^
@@ -1955,16 +1988,24 @@ tools/configure.sh
There is a script that automates these steps. The following steps will
accomplish the same configuration:
cd tools
./configure.sh <board-name>/<config-dir>
cd tools
./configure.sh <board-name>/<config-dir>
And if configs/<board-name>/<config-dir>/appconfig exists and your
application directory is not in the standard loction (../apps), then
you should also specify the location of the application directory on the
command line like:
There is an alternative Windows batch file that can be used in the
windows native enironment like:
cd tools
./configure.sh -a <app-dir> <board-name>/<config-dir>
cd ${TOPDIR}\tools
configure.bat <board-name>\<config-dir>
See tools/README.txt for more information about these scripts.
And if configs/<board-name>/<config-dir>/appconfig exists and your
application directory is not in the standard loction (../apps), then
you should also specify the location of the application directory on the
command line like:
cd tools
./configure.sh -a <app-dir> <board-name>/<config-dir>
Building Symbol Tables
^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -140,7 +140,8 @@ menuconfig SPI
bool "SPI Driver Support"
default n
---help---
This selection enables building of the "upper-half" SPI driver.
This selection enables selection of common SPI options. This option
should be enabled by all platforms that support SPI interfaces.
See include/nuttx/spi.h for further SPI driver information.
if SPI

View File

@@ -123,6 +123,25 @@ config STMPE811_I2C
endchoice
config STMPE811_ACTIVELOW
bool "Active Low Interrupt"
default n
---help---
The STMPE811 interrupt is provided by a discrete input (usually a
GPIO interrupt on most MCU architectures). This setting determines
whether the interrupt is active high (or rising edge triggered) or
active low (or falling edge triggered). Default: Active
high/rising edge.
config STMPE811_EDGE
bool "Edge triggered Interrupt"
default n
---help---
The STMPE811 interrupt is provided by a discrete input (usually a
GPIO interrupt on most MCU architectures). This setting determines
whether the interrupt is edge or level triggered. Default: Level
triggered.
config STMPE811_MULTIPLE
bool "Multiple STMPE811 Devices"
default n

View File

@@ -51,6 +51,10 @@ ifeq ($(CONFIG_LCD_UG2864AMBAG01),y)
CSRCS += ug-2864ambag01.c
endif
ifeq ($(CONFIG_LCD_UG2864HSWEG01),y)
CSRCS += ug-2864hsweg01.c
endif
ifeq ($(CONFIG_LCD_UG9664HSWAG01),y)
CSRCS += ug-9664hswag01.c
endif

View File

@@ -428,7 +428,7 @@ static inline void ug2864ambag01_configspi(FAR struct spi_dev_s *spi)
SPI_SETMODE(spi, CONFIG_UG2864AMBAG01_SPIMODE);
SPI_SETBITS(spi, 8);
SPI_SETFREQUENCY(spi, CONFIG_UG2864AMBAG01_FREQUENCY)
SPI_SETFREQUENCY(spi, CONFIG_UG2864AMBAG01_FREQUENCY);
}
#endif
@@ -1035,7 +1035,7 @@ FAR struct lcd_dev_s *ug2864ambag01_initialize(FAR struct spi_dev_s *spi, unsign
/* Configure the SPI */
ug2864ambag01_configspi(spi)
ug2864ambag01_configspi(spi);
/* Lock and select device */
@@ -1148,8 +1148,8 @@ void ug2864ambag01_fill(FAR struct lcd_dev_s *dev, uint8_t color)
/* Transfer one page of the selected color */
(void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * UG2864AMBAG01_XRES],
UG2864AMBAG01_XRES);
(void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * UG2864AMBAG01_XRES],
UG2864AMBAG01_XRES);
}
/* De-select and unlock the device */

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
config MMCSD_NSLOTS
int "Number of MMC/SD slots"
default 1
@@ -38,8 +39,9 @@ config MMCSD_HAVECARDDETECT
100% accurate
config MMCSD_SPI
bool "MMC/SD spi transfer support"
bool "MMC/SD SPI transfer support"
default y
depends on SPI
config MMCSD_SPICLOCK
int "MMC/SD maximum SPI clock"

View File

@@ -37,6 +37,8 @@
# Include MTD drivers
ifeq ($(CONFIG_MTD),y)
CSRCS += at45db.c flash_eraseall.c ftl.c m25px.c rammtd.c ramtron.c
ifeq ($(CONFIG_MTD_AT24XX),y)
@@ -60,3 +62,4 @@ endif
DEPPATH += --dep-path mtd
VPATH += :mtd
endif

View File

@@ -523,12 +523,12 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
{
/* Save the configuration and inform the constituent classes */
ret = CLASS_SETUP(priv->dev1, dev, ctrl);
ret = CLASS_SETUP(priv->dev1, dev, ctrl, dataout, outlen);
dispatched = true;
if (ret >= 0)
{
ret = CLASS_SETUP(priv->dev2, dev, ctrl);
ret = CLASS_SETUP(priv->dev2, dev, ctrl, dataout, outlen);
if (ret >= 0)
{
priv->config = value;

View File

@@ -333,7 +333,7 @@ static void usbclass_wrcomplete(FAR struct usbdev_ep_s *ep,
/* USB class device ********************************************************/
static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver,
FAR struct usbdev_s *dev);
@@ -1295,7 +1295,7 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
priv->usbdev = dev;
/* Save the reference to our private data structure in EP0 so that it
* can be recovered in ep0 completion events (Unless we are part of
* can be recovered in ep0 completion events (Unless we are part of
* a composite device and, in that case, the composite device owns
* EP0).
*/
@@ -1859,7 +1859,7 @@ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
* re-enumerated.
*/
DEV_CONNECT(dev);
DEV_CONNECT(dev);
}
/****************************************************************************
@@ -1878,7 +1878,7 @@ static int usbser_setup(FAR struct uart_dev_s *dev)
{
FAR struct pl2303_dev_s *priv;
usbtrace(PL2303_CLASSASPI_SETUP, 0);
usbtrace(PL2303_CLASSAPI_SETUP, 0);
/* Sanity check */
@@ -1919,7 +1919,7 @@ static int usbser_setup(FAR struct uart_dev_s *dev)
static void usbser_shutdown(FAR struct uart_dev_s *dev)
{
usbtrace(PL2303_CLASSASPI_SHUTDOWN, 0);
usbtrace(PL2303_CLASSAPI_SHUTDOWN, 0);
/* Sanity check */
@@ -1941,7 +1941,7 @@ static void usbser_shutdown(FAR struct uart_dev_s *dev)
static int usbser_attach(FAR struct uart_dev_s *dev)
{
usbtrace(PL2303_CLASSASPI_ATTACH, 0);
usbtrace(PL2303_CLASSAPI_ATTACH, 0);
return OK;
}
@@ -1955,7 +1955,7 @@ static int usbser_attach(FAR struct uart_dev_s *dev)
static void usbser_detach(FAR struct uart_dev_s *dev)
{
usbtrace(PL2303_CLASSASPI_DETACH, 0);
usbtrace(PL2303_CLASSAPI_DETACH, 0);
}
/****************************************************************************
@@ -1981,7 +1981,7 @@ static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable)
FAR uart_dev_t *serdev;
irqstate_t flags;
usbtrace(PL2303_CLASSASPI_RXINT, (uint16_t)enable);
usbtrace(PL2303_CLASSAPI_RXINT, (uint16_t)enable);
/* Sanity check */
@@ -2072,7 +2072,7 @@ static void usbser_txint(FAR struct uart_dev_s *dev, bool enable)
{
FAR struct pl2303_dev_s *priv;
usbtrace(PL2303_CLASSASPI_TXINT, (uint16_t)enable);
usbtrace(PL2303_CLASSAPI_TXINT, (uint16_t)enable);
/* Sanity checks */
@@ -2117,7 +2117,7 @@ static bool usbser_txempty(FAR struct uart_dev_s *dev)
{
FAR struct pl2303_dev_s *priv = (FAR struct pl2303_dev_s*)dev->priv;
usbtrace(PL2303_CLASSASPI_TXEMPTY, 0);
usbtrace(PL2303_CLASSAPI_TXEMPTY, 0);
#if CONFIG_DEBUG
if (!priv)

View File

@@ -2,6 +2,7 @@
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
config USBHOST_NPREALLOC
int "Number of pre-allocated class instances"
default 4
@@ -29,64 +30,85 @@ config USBHOST_ISOC_DISABLE
On some architectures, selecting this setting will reduce driver size
by disabling isochronous endpoint support
config USBHOST_HIDKBD
bool "HID keyboad class support"
config USBHOST_MSC
bool "Mass Storage Class Support"
default n
depends on !USBHOST_INT_DISABLE && SCHED_WORKQUEUE && !DISABLE_SIGNALS
depends on !BULK_DISABLE
---help---
Enable support for the keyboard class driver. This also depends on
NFILE_DESCRIPTORS > 0 && SCHED_WORKQUEUE=y
config USBHOST_HIDKBD
bool "HID Keyboard Class Support"
default n
depends on !INT_DISABLE
---help---
Enable support for the keyboard class driver. This also depends on
SCHED_WORKQUEUE && !DISABLE_SIGNALS
if USBHOST_HIDKBD
config HIDKBD_POLLUSEC
bool ""
default n
int "Keyboard Poll Rate (MSEC)"
default 100000
---help---
Device poll rate in microseconds. Default: 100 milliseconds.
Device poll rate in microseconds. Default: 100,000 microseconds.
config HIDKBD_DEFPRIO
bool ""
default n
int "Polling Thread Priority"
default 50
---help---
Priority of the polling thread. Default: 50.
config HIDKBD_STACKSIZE
bool ""
default n
int "Polling thread stack size"
default 1024
---help---
Stack size for polling thread. Default: 1024
config HIDKBD_BUFSIZE
bool ""
default n
int "Scancode Buffer Size"
default 64
---help---
Scancode buffer size. Default: 64.
config HIDKBD_NPOLLWAITERS
bool ""
default n
int "Max Number of Waiters for Poll Event"
default 2
depends on !DISABLE_POLL
---help---
If the poll() method is enabled, this defines the maximum number
of threads that can be waiting for keyboard events. Default: 2.
config HIDKBD_RAWSCANCODES
bool ""
bool "Use Raw Scan Codes"
default n
---help---
If set to y no conversion will be made on the raw keyboard scan
codes. Default: ASCII conversion.
If set to y no conversions will be made on the raw keyboard scan
codes. This option is useful during testing. Default: ASCII conversion.
config HIDKBD_ENCODED
bool "Enocode Special Keys"
default n
depends on !HIDKBD_RAWSCANCODES && LIB_KBDCODEC
---help---
Encode special key press events in the user buffer. In this case,
the user end must decode the encoded special key values using the
interfaces defined in include/nuttx/input/kbd_codec.h. 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.
config HIDKBD_ALLSCANCODES
bool ""
bool "Use All Scancodes"
default n
---help---
If set to y all 231 possible scancodes will be converted to
something. Default: 104 key US keyboard.
config HIDKBD_NODEBOUNCE
bool ""
bool "Disable Debounce"
default n
---help---
If set to y normal debouncing is disabled. Default:
Debounce enabled (No repeat keys).
USB host mass storage class driver. Requires USBHOST=y,
config USBHOST_BULK_DISABLE=n, NFILE_DESCRIPTORS > 0,
and SCHED_WORKQUEUE=y
endif

View File

@@ -1,7 +1,7 @@
/****************************************************************************
* drivers/usbhost/usbhost_hidkbd.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -62,6 +62,11 @@
#include <nuttx/usb/usbhost.h>
#include <nuttx/usb/hid.h>
#ifdef CONFIG_HIDKBD_ENCODED
# include <nuttx/streams.h>
# include <nuttx/input/kbd_codec.h>
#endif
/* Don't compile if prerequisites are not met */
#if defined(CONFIG_USBHOST) && !defined(CONFIG_USBHOST_INT_DISABLE) && CONFIG_NFILE_DESCRIPTORS > 0
@@ -126,6 +131,22 @@
# endif
#endif
/* We cant support encoding of special characters of unless the Keyboard
* CODEC is enabled.
*/
#ifndef CONFIG_LIB_KBDCODEC
# undef CONFIG_HIDKBD_ENCODED
#endif
/* If we are using raw scancodes, then we cannot support encoding of
* special characters either.
*/
#ifdef CONFIG_HIDKBD_RAWSCANCODES
# undef CONFIG_HIDKBD_ENCODED
#endif
/* Driver support ***********************************************************/
/* This format is used to construct the /dev/kbd[n] device driver path. It
* defined here so that it will be used consistently in all places.
@@ -144,6 +165,23 @@
#define USBHOST_MAX_CREFS 0x7fff
/* Debug ********************************************************************/
/* Both CONFIG_DEBUG_INPUT and CONFIG_DEBUG_USB could apply to this file.
* We assume here that CONFIG_DEBUG_INPUT might be enabled separately, but
* CONFIG_DEBUG_USB implies both.
*/
#ifndef CONFIG_DEBUG_INPUT
# undef idbg
# define idbg udbg
# undef illdbg
# define illdbg ulldbg
# undef ivdbg
# define ivdbg uvdbg
# undef illvdbg
# define illvdbg ullvdbg
#endif
/****************************************************************************
* Private Types
****************************************************************************/
@@ -209,6 +247,16 @@ struct usbhost_state_s
uint8_t kbdbuffer[CONFIG_HIDKBD_BUFSIZE];
};
/* This type is used for encoding special characters */
#ifdef CONFIG_HIDKBD_ENCODED
struct usbhost_outstream_s
{
struct lib_outstream_s stream;
FAR struct usbhost_state_s *priv;
};
#endif
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@@ -240,7 +288,15 @@ static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *dev
/* Keyboard polling thread */
static void usbhost_destroy(FAR void *arg);
static void usbhost_putbuffer(FAR struct usbhost_state_s *priv, uint8_t keycode);
#ifdef CONFIG_HIDKBD_ENCODED
static void usbhost_putstream(FAR struct lib_outstream_s *this, int ch);
#endif
static inline uint8_t usbhost_mapscancode(uint8_t scancode, uint8_t modifier);
#ifdef CONFIG_HIDKBD_ENCODED
static inline void usbhost_encodescancode(FAR struct usbhost_state_s *priv,
uint8_t scancode, uint8_t modifier);
#endif
static int usbhost_kbdpoll(int argc, char *argv[]);
/* Helpers for usbhost_connect() */
@@ -346,6 +402,121 @@ static struct usbhost_state_s *g_priv; /* Data passed to thread */
*/
#ifndef CONFIG_HIDKBD_RAWSCANCODES
#ifdef CONFIG_HIDKBD_ENCODED
/* The first and last scancode values with encode-able values */
#define FIRST_ENCODING USBHID_KBDUSE_ENTER /* 0x28 Keyboard Return (ENTER) */
#ifndef CONFIG_HIDKBD_ALLSCANCODES
# define LAST_ENCODING USBHID_KBDUSE_POWER /* 0x66 Keyboard Power */
#else
# define LAST_ENCODING USBHID_KBDUSE_KPDHEXADECIMAL /* 0xdd Keypad Hexadecimal */
#endif
#define USBHID_NUMENCODINGS (LAST_ENCODING - FIRST_ENCODING + 1)
static const uint8_t encoding[USBHID_NUMENCODINGS] =
{
/* 0x28-0x2f: Enter,escape,del,back-tab,space,_,+,{ */
KEYCODE_ENTER, 0, KEYCODE_FWDDEL, KEYCODE_BACKDEL, 0, 0, 0, 0,
/* 0x30-0x37: },|,Non-US tilde,:,",grave tilde,<,> */
0, 0, 0, 0, 0, 0, 0, 0,
/* 0x38-0x3f: /,CapsLock,F1,F2,F3,F4,F5,F6 */
0, KEYCODE_CAPSLOCK, KEYCODE_F1, KEYCODE_F2, KEYCODE_F3, KEYCODE_F4, KEYCODE_F5, KEYCODE_F6,
/* 0x40-0x47: F7,F8,F9,F10,F11,F12,PrtScn,ScrollLock */
KEYCODE_F7, KEYCODE_F8, KEYCODE_F9, KEYCODE_F10, KEYCODE_F11, KEYCODE_F12, KEYCODE_PRTSCRN, KEYCODE_SCROLLLOCK,
/* 0x48-0x4f: Pause,Insert,Home,PageUp,DeleteForward,End,PageDown,RightArrow */
KEYCODE_PAUSE, KEYCODE_INSERT, KEYCODE_HOME, KEYCODE_PAGEUP, KEYCODE_FWDDEL, KEYCODE_END, KEYCODE_PAGEDOWN, KEYCODE_RIGHT,
/* 0x50-0x57: LeftArrow,DownArrow,UpArrow,Num Lock,/,*,-,+ */
KEYCODE_LEFT, KEYCODE_DOWN, KEYCODE_UP, KEYCODE_NUMLOCK, 0, 0, 0, 0,
/* 0x58-0x5f: Enter,1-7 */
KEYCODE_ENTER, 0, 0, 0, 0, 0, 0, 0,
/* 0x60-0x66: 8-9,0,.,Non-US \,Application,Power */
0, 0, 0, 0, 0, 0, KEYCODE_POWER,
#ifdef CONFIG_HIDKBD_ALLSCANCODES
0, /* 0x67 = */
/* 0x68-0x6f: F13,F14,F15,F16,F17,F18,F19,F20 */
KEYCODE_F13, KEYCODE_F14, KEYCODE_F15, KEYCODE_F16, KEYCODE_F17, KEYCODE_F18, KEYCODE_F19, KEYCODE_F20,
/* 0x70-0x77: F21,F22,F23,F24,Execute,Help,Menu,Select */
KEYCODE_F21, KEYCODE_F22, KEYCODE_F23, KEYCODE_F24, KEYCODE_EXECUTE, KEYCODE_HELP, KEYCODE_MENU, KEYCODE_SELECT,
/* 0x78-0x7f: Stop,Again,Undo,Cut,Copy,Paste,Find,Mute */
KEYCODE_STOP, KEYCODE_AGAIN, KEYCODE_UNDO, KEYCODE_CUT, KEYCODE_COPY, KEYCODE_PASTE, KEYCODE_FIND, KEYCODE_MUTE,
/* 0x80-0x87: VolUp,VolDown,LCapsLock,lNumLock,LScrollLock,,,=,International1 */
KEYCODE_VOLUP, KEYCODE_VOLDOWN, KEYCODE_LCAPSLOCK, KEYCODE_LNUMLOCK, KEYCODE_LSCROLLLOCK, 0, 0, 0,
/* 0x88-0x8f: International 2-9 */
0, 0, 0, 0, 0, 0, 0, 0,
/* 0x90-0x97: LAN 1-8 */
KEYCODE_LANG1, KEYCODE_LANG2, KEYCODE_LANG3, KEYCODE_LANG4, KEYCODE_LANG5, KEYCODE_LANG6, KEYCODE_LANG7, KEYCODE_LANG8,
/* 0x98-0x9f: LAN 9,Erase,SysReq,Cancel,Clear,Prior,Return,Separator */
0, 0, KEYCODE_SYSREQ, KEYCODE_CANCEL, KEYCODE_CLEAR, 0, KEYCODE_ENTER, 0,
/* 0xa0-0xa7: Out,Oper,Clear,CrSel,Excel,(reserved) */
0, 0, 0, 0, 0, 0, 0, 0,
/* 0xa8-0xaf: (reserved) */
0, 0, 0, 0, 0, 0, 0, 0,
/* 0xb0-0xb7: 00,000,ThouSeparator,DecSeparator,CurrencyUnit,SubUnit,(,) */
0, 0, 0, 0, 0, 0, 0, 0,
/* 0xb8-0xbf: {,},tab,backspace,A-D */
0, 0, 0, KEYCODE_BACKDEL, 0, 0, 0, 0,
/* 0xc0-0xc7: E-F,XOR,^,%,<,>,& */
0, 0, 0, 0, 0, 0, 0, 0,
/* 0xc8-0xcf: &&,|,||,:,#, ,@,! */
0, 0, 0, 0, 0, 0, 0, 0,
/* 0xd0-0xd7: Memory Store,Recall,Clear,Add,Subtract,Muliply,Divide,+/- */
KEYCODE_MEMSTORE, KEYCODE_MEMRECALL, KEYCODE_MEMCLEAR, KEYCODE_MEMADD, KEYCODE_MEMSUB, KEYCODE_MEMMUL, KEYCODE_MEMDIV, KEYCODE_NEGATE,
/* 0xd8-0xdd: Clear,ClearEntry,Binary,Octal,Decimal,Hexadecimal */
KEYCODE_CLEAR, KEYCODE_CLEARENTRY, KEYCODE_BINARY, KEYCODE_OCTAL, KEYCODE_DECIMAL, KEYCODE_HEXADECIMAL
#endif
};
#endif
static const uint8_t ucmap[USBHID_NUMSCANCODES] =
{
0, 0, 0, 0, 'A', 'B', 'C', 'D', /* 0x00-0x07: Reserved, errors, A-D */
@@ -354,12 +525,12 @@ static const uint8_t ucmap[USBHID_NUMSCANCODES] =
'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', /* 0x18-0x1f: U-Z,!,@ */
'#', '$', '%', '^', '&', '*', '(', ')', /* 0x20-0x27: #,$,%,^,&,*,(,) */
'\n', '\033', '\177', 0, ' ', '_', '+', '{', /* 0x28-0x2f: Enter,escape,del,back-tab,space,_,+,{ */
'}', '|', 0, ':', '"', 0, '<', '>', /* 0x30-0x37: },|,Non-US tilde,:,",grave tidle,<,> */
'}', '|', 0, ':', '"', '~', '<', '>', /* 0x30-0x37: },|,Non-US tilde,:,",grave tilde,<,> */
'?', 0, 0, 0, 0, 0, 0, 0, /* 0x38-0x3f: /,CapsLock,F1,F2,F3,F4,F5,F6 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x47: F7,F8,F9,F10,F11,F12,PrtScn,sScrollLock */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x47: F7,F8,F9,F10,F11,F12,PrtScn,ScrollLock */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x48-0x4f: Pause,Insert,Home,PageUp,DeleteForward,End,PageDown,RightArrow */
0, 0, 0, 0, '/', '*', '-', '+', /* 0x50-0x57: LeftArrow,DownArrow,UpArrow,Num Lock,/,*,-,+ */
'\n', '1', '2', '3', '4', '4', '6', '7', /* 0x58-0x5f: Enter,1-7 */
'\n', '1', '2', '3', '4', '5', '6', '7', /* 0x58-0x5f: Enter,1-7 */
'8', '9', '0', '.', 0, 0, 0, '=', /* 0x60-0x67: 8-9,0,.,Non-US \,Application,Power,= */
#ifdef CONFIG_HIDKBD_ALLSCANCODES
0, 0, 0, 0, 0, 0, 0, 0, /* 0x68-0x6f: F13,F14,F15,F16,F17,F18,F19,F20 */
@@ -368,7 +539,7 @@ static const uint8_t ucmap[USBHID_NUMSCANCODES] =
0, 0, 0, 0, 0, ',', 0, 0, /* 0x80-0x87: VolUp,VolDown,LCapsLock,lNumLock,LScrollLock,,,=,International1 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x88-0x8f: International 2-9 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x97: LAN 1-8 */
0, 0, 0, 0, 0, 0, '\n', 0, /* 0x98-0x9f: LAN 9,Ease,SysReq,Cancel,Clear,Prior,Return,Separator */
0, 0, 0, 0, 0, 0, '\n', 0, /* 0x98-0x9f: LAN 9,Erase,SysReq,Cancel,Clear,Prior,Return,Separator */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xa7: Out,Oper,Clear,CrSel,Excel,(reserved) */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xa8-0xaf: (reserved) */
0, 0, 0, 0, 0, 0, '(', ')', /* 0xb0-0xb7: 00,000,ThouSeparator,DecSeparator,CurrencyUnit,SubUnit,(,) */
@@ -389,12 +560,12 @@ static const uint8_t lcmap[USBHID_NUMSCANCODES] =
'u', 'v', 'w', 'x', 'y', 'z', '1', '2', /* 0x18-0x1f: u-z,1-2 */
'3', '4', '5', '6', '7', '8', '9', '0', /* 0x20-0x27: 3-9,0 */
'\n', '\033', '\177', '\t', ' ', '-', '=', '[', /* 0x28-0x2f: Enter,escape,del,tab,space,-,=,[ */
']', '\\', '\234', ';', '\'', 0, ',', '.', /* 0x30-0x37: ],\,Non-US pound,;,',grave accent,,,. */
']', '\\', '\234', ';', '\'', '`', ',', '.', /* 0x30-0x37: ],\,Non-US pound,;,',grave accent,,,. */
'/', 0, 0, 0, 0, 0, 0, 0, /* 0x38-0x3f: /,CapsLock,F1,F2,F3,F4,F5,F6 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x47: F7,F8,F9,F10,F11,F12,PrtScn,ScrollLock */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x48-0x4f: Pause,Insert,Home,PageUp,DeleteForward,End,PageDown,RightArrow */
0, 0, 0, 0, '/', '*', '-', '+', /* 0x50-0x57: LeftArrow,DownArrow,UpArrow,Num Lock,/,*,-,+ */
'\n', '1', '2', '3', '4', '4', '6', '7', /* 0x58-0x5f: Enter,1-7 */
'\n', '1', '2', '3', '4', '5', '6', '7', /* 0x58-0x5f: Enter,1-7 */
'8', '9', '0', '.', 0, 0, 0, '=', /* 0x60-0x67: 8-9,0,.,Non-US \,Application,Power,= */
#ifdef CONFIG_HIDKBD_ALLSCANCODES
0, 0, 0, 0, 0, 0, 0, 0, /* 0x68-0x6f: F13,F14,F15,F16,F17,F18,F19,F20 */
@@ -403,7 +574,7 @@ static const uint8_t lcmap[USBHID_NUMSCANCODES] =
0, 0, 0, 0, 0, ',', 0, 0, /* 0x80-0x87: VolUp,VolDown,LCapsLock,lNumLock,LScrollLock,,,=,International1 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x88-0x8f: International 2-9 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x97: LAN 1-8 */
0, 0, 0, 0, 0, 0, '\n', 0, /* 0x98-0x9f: LAN 9,Ease,SysReq,Cancel,Clear,Prior,Return,Separator */
0, 0, 0, 0, 0, 0, '\n', 0, /* 0x98-0x9f: LAN 9,Erase,SysReq,Cancel,Clear,Prior,Return,Separator */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xa7: Out,Oper,Clear,CrSel,Excel,(reserved) */
0, 0, 0, 0, 0, 0, 0, 0, /* 0xa8-0xaf: (reserved) */
0, 0, 0, 0, 0, 0, '(', ')', /* 0xb0-0xb7: 00,000,ThouSeparator,DecSeparator,CurrencyUnit,SubUnit,(,) */
@@ -637,6 +808,88 @@ static void usbhost_destroy(FAR void *arg)
usbhost_freeclass(priv);
}
/****************************************************************************
* Name: usbhost_putbuffer
*
* Description:
* Add one character to the user buffer.
*
* Input Parameters:
* priv - Driver internal state
* keycode - The value to add to the user buffer
*
* Returned Values:
* None
*
****************************************************************************/
static void usbhost_putbuffer(FAR struct usbhost_state_s *priv,
uint8_t keycode)
{
register unsigned int head;
register unsigned int tail;
/* Copy the next keyboard character into the user buffer. */
head = priv->headndx;
priv->kbdbuffer[head] = keycode;
/* Increment the head index */
if (++head >= CONFIG_HIDKBD_BUFSIZE)
{
head = 0;
}
/* If the buffer is full, then increment the tail index to make space. Is
* it better to lose old keystrokes or new?
*/
tail = priv->tailndx;
if (tail == head)
{
if (++tail >= CONFIG_HIDKBD_BUFSIZE)
{
tail = 0;
}
/* Save the updated tail index */
priv->tailndx = tail;
}
/* Save the updated head index */
priv->headndx = head;
}
/****************************************************************************
* Name: usbhost_putstream
*
* Description:
* A wrapper for usbhost_putc that is compatibile with the lib_outstream_s
* putc methos.
*
* Input Parameters:
* stream - The struct lib_outstream_s reference
* ch - The character to add to the user buffer
*
* Returned Values:
* None
*
****************************************************************************/
#ifdef CONFIG_HIDKBD_ENCODED
static void usbhost_putstream(FAR struct lib_outstream_s *stream, int ch)
{
FAR struct usbhost_outstream_s *privstream = (FAR struct usbhost_outstream_s *)stream;
DEBUGASSERT(privstream && privstream->priv);
usbhost_putbuffer(privstream->priv, (uint8_t)ch);
stream->nput++;
}
#endif
/****************************************************************************
* Name: usbhost_mapscancode
*
@@ -679,6 +932,58 @@ static inline uint8_t usbhost_mapscancode(uint8_t scancode, uint8_t modifier)
#endif
}
/****************************************************************************
* Name: usbhost_encodescancode
*
* Description:
* Check if the key has a special function encoding and, if it does, add
* the encoded value to the user buffer.
*
* Input Parameters:
* priv - Driver internal state
* scancode - Scan code to be mapped.
* modifier - Ctrl,Alt,Shift,GUI modifier bits
*
* Returned Values:
* None
*
****************************************************************************/
#ifdef CONFIG_HIDKBD_ENCODED
static inline void usbhost_encodescancode(FAR struct usbhost_state_s *priv,
uint8_t scancode, uint8_t modifier)
{
uint8_t encoded;
/* Check if the raw scancode is in a valid range */
if (scancode >= FIRST_ENCODING && scancode <= LAST_ENCODING)
{
/* Yes the value is within range */
encoded = encoding[scancode - FIRST_ENCODING];
ivdbg(" scancode: %02x modifier: %02x encoded: %d\n",
scancode, modifier, encoded);
if (encoded)
{
struct usbhost_outstream_s usbstream;
/* And it does correspond to a special function key */
usbstream.stream.put = usbhost_putstream;
usbstream.stream.nput = 0;
usbstream.priv = priv;
/* Add the special function value to the user buffer */
kbd_specpress((enum kbd_keycode_e)encoded,
(FAR struct lib_outstream_s *)&usbstream);
}
}
}
#endif
/****************************************************************************
* Name: usbhost_kbdpoll
*
@@ -704,6 +1009,8 @@ static int usbhost_kbdpoll(int argc, char *argv[])
unsigned int npolls = 0;
#endif
unsigned int nerrors = 0;
bool empty = true;
bool newstate;
int ret;
uvdbg("Started\n");
@@ -717,17 +1024,18 @@ static int usbhost_kbdpoll(int argc, char *argv[])
* running.
*/
priv = g_priv;
DEBUGASSERT(priv != NULL);
priv = g_priv;
DEBUGASSERT(priv != NULL);
priv->polling = true;
priv->crefs++;
usbhost_givesem(&g_syncsem);
sleep(1);
priv->polling = true;
priv->crefs++;
usbhost_givesem(&g_syncsem);
sleep(1);
/* Loop here until the device is disconnected */
uvdbg("Entering poll loop\n");
while (!priv->disconnected)
{
/* Make sure that we have exclusive access to the private data
@@ -784,17 +1092,12 @@ static int usbhost_kbdpoll(int argc, char *argv[])
else if (priv->open)
{
struct usbhid_kbdreport_s *rpt = (struct usbhid_kbdreport_s *)priv->tbuffer;
unsigned int head;
unsigned int tail;
uint8_t ascii;
uint8_t keycode;
int i;
/* Add the newly received keystrokes to our internal buffer */
usbhost_takesem(&priv->exclsem);
head = priv->headndx;
tail = priv->tailndx;
for (i = 0; i < 6; i++)
{
/* Is this key pressed? But not pressed last time?
@@ -828,15 +1131,15 @@ static int usbhost_kbdpoll(int argc, char *argv[])
* or cursor controls in this version of the driver.
*/
ascii = usbhost_mapscancode(rpt->key[i], rpt->modifier);
uvdbg("Key %d: %02x ASCII:%c modifier: %02x\n",
i, rpt->key[i], ascii ? ascii : ' ', rpt->modifier);
keycode = usbhost_mapscancode(rpt->key[i], rpt->modifier);
ivdbg("Key %d: %02x keycode:%c modifier: %02x\n",
i, rpt->key[i], keycode ? keycode : ' ', rpt->modifier);
/* Zero at this point means that the key does not map to a
* printable character.
*/
if (ascii != 0)
if (keycode != 0)
{
/* Handle control characters. Zero after this means
* a valid, NUL character.
@@ -844,36 +1147,28 @@ static int usbhost_kbdpoll(int argc, char *argv[])
if ((rpt->modifier & (USBHID_MODIFER_LCTRL|USBHID_MODIFER_RCTRL)) != 0)
{
ascii &= 0x1f;
keycode &= 0x1f;
}
/* Copy the next keyboard character into the user
* buffer.
*/
priv->kbdbuffer[head] = ascii;
/* Increment the head index */
if (++head >= CONFIG_HIDKBD_BUFSIZE)
{
head = 0;
}
/* If the buffer is full, then increment the tail
* index to make space. Is it better to lose old
* keystrokes or new?
*/
if (tail == head)
{
if (++tail >= CONFIG_HIDKBD_BUFSIZE)
{
tail = 0;
}
}
usbhost_putbuffer(priv, keycode);
}
/* The zero might, however, map to a special keyboard action (such as a
* cursor movement or function key). Attempt to encode the special key.
*/
#ifdef CONFIG_HIDKBD_ENCODED
else
{
usbhost_encodescancode(priv, rpt->key[i], rpt->modifier);
}
#endif
}
/* Save the scancode (or lack thereof) for key debouncing on
* next keyboard report.
*/
@@ -883,9 +1178,10 @@ static int usbhost_kbdpoll(int argc, char *argv[])
#endif
}
/* Did we just transition from no data available to data available? */
/* Is there data available? */
if (head != tail && priv->headndx == priv->tailndx)
newstate = (priv->headndx == priv->tailndx);
if (!newstate)
{
/* Yes.. Is there a thread waiting for keyboard data now? */
@@ -897,15 +1193,18 @@ static int usbhost_kbdpoll(int argc, char *argv[])
priv->waiting = false;
}
/* And wake up any threads waiting for the POLLIN event */
/* Did we just transition from no data available to data
* available? If so, wake up any threads waiting for the
* POLLIN event.
*/
usbhost_pollnotify(priv);
if (empty)
{
usbhost_pollnotify(priv);
}
}
/* Update the head/tail indices */
priv->headndx = head;
priv->tailndx = tail;
empty = newstate;
usbhost_givesem(&priv->exclsem);
}
@@ -958,6 +1257,7 @@ static int usbhost_kbdpoll(int argc, char *argv[])
usbhost_givesem(&priv->exclsem);
}
return 0;
}
@@ -1861,6 +2161,7 @@ static ssize_t usbhost_read(FAR struct file *filep, FAR char *buffer, size_t len
/* Wait for data to be available */
uvdbg("Waiting...\n");
priv->waiting = true;
usbhost_givesem(&priv->exclsem);
usbhost_takesem(&priv->waitsem);

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