mirror of
https://gitee.com/xiaohuolufeihua/bizhang_-obav.git
synced 2026-05-21 09:22:18 +00:00
Merge NuttX r5527
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 "********************************************************"; \
|
||||
|
||||
146
apps/README.txt
146
apps/README.txt
@@ -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
17
apps/builtin/Kconfig
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
|
||||
if BUILTIN
|
||||
|
||||
config BUILTIN_PROXY_STACKSIZE
|
||||
int "Builtin Proxy Stack Size"
|
||||
default 1024
|
||||
---help---
|
||||
If exec_builtin uses I/O redirection options, then it will require
|
||||
an intermediary/proxy task to muck with the file descriptors. This
|
||||
configuration item specifies the stack size used for the proxy. Default:
|
||||
1024 bytes.
|
||||
|
||||
endif
|
||||
@@ -1,5 +1,5 @@
|
||||
############################################################################
|
||||
# apps/namedapps/Make.defs
|
||||
# apps/builtin/Make.defs
|
||||
# Adds selected applications to apps/ build
|
||||
#
|
||||
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
@@ -34,7 +34,7 @@
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifeq ($(CONFIG_NAMEDAPP),y)
|
||||
CONFIGURED_APPS += namedapp
|
||||
ifeq ($(CONFIG_BUILTIN),y)
|
||||
CONFIGURED_APPS += builtin
|
||||
endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
############################################################################
|
||||
# apps/nshlib/Makefile
|
||||
# apps/builtin/Makefile
|
||||
#
|
||||
# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@@ -33,20 +33,13 @@
|
||||
#
|
||||
############################################################################
|
||||
|
||||
-include $(TOPDIR)/.config
|
||||
-include $(TOPDIR)/Make.defs
|
||||
include $(APPDIR)/Make.defs
|
||||
|
||||
# NSH Library
|
||||
|
||||
# Source and object files
|
||||
|
||||
ASRCS =
|
||||
CSRCS = namedapp.c exec_namedapp.c
|
||||
|
||||
ifeq ($(CONFIG_APPS_BINDIR),y)
|
||||
CSRCS += binfs.c
|
||||
endif
|
||||
CSRCS = builtin.c exec_builtin.c
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
@@ -70,7 +63,7 @@ VPATH =
|
||||
# Build Targets
|
||||
|
||||
all: .built
|
||||
.PHONY: .context context depend clean distclean
|
||||
.PHONY: context depend clean distclean
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(call ASSEMBLE, $<, $@)
|
||||
@@ -78,33 +71,60 @@ $(AOBJS): %$(OBJEXT): %.S
|
||||
$(COBJS): %$(OBJEXT): %.c
|
||||
$(call COMPILE, $<, $@)
|
||||
|
||||
.built: $(OBJS)
|
||||
registry$(DELIM).updated:
|
||||
$(V) $(MAKE) -C registry .updated TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
|
||||
|
||||
builtin_list.h: registry$(DELIM).updated
|
||||
$(call DELFILE, builtin_list.h)
|
||||
$(Q) touch builtin_list.h
|
||||
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||
$(Q) for /f %%G in ('dir /b registry\*.bdat`) do ( type registry\%%G >> builtin_list.h )
|
||||
else
|
||||
$(Q) ( \
|
||||
filelist=`ls registry/*.bdat 2>/dev/null || echo ""`; \
|
||||
for file in $$filelist; \
|
||||
do cat $$file >> builtin_list.h; \
|
||||
done; \
|
||||
)
|
||||
endif
|
||||
|
||||
builtin_proto.h: registry$(DELIM).updated
|
||||
$(call DELFILE, builtin_proto.h)
|
||||
$(Q) touch builtin_proto.h
|
||||
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||
$(Q) for /f %%G in ('dir /b registry\*.pdat`) do ( type registry\%%G >> builtin_proto.h )
|
||||
else
|
||||
$(Q) ( \
|
||||
filelist=`ls registry/*.pdat 2>/dev/null || echo ""`; \
|
||||
for file in $$filelist; \
|
||||
do cat $$file >> builtin_proto.h; \
|
||||
done; \
|
||||
)
|
||||
endif
|
||||
|
||||
.built: builtin_list.h builtin_proto.h $(OBJS)
|
||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||
$(Q) touch .built
|
||||
|
||||
.context:
|
||||
@echo "/* List of application requirements, generated during make context. */" > namedapp_list.h
|
||||
@echo "/* List of application entry points, generated during make context. */" > namedapp_proto.h
|
||||
$(Q) touch $@
|
||||
context:
|
||||
$(Q) $(MAKE) -C registry context TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
|
||||
|
||||
context: .context
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
.depend: Makefile $(SRCS) builtin_list.h builtin_proto.h
|
||||
$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
$(Q) touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
$(Q) $(MAKE) -C registry clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
|
||||
$(call DELFILE, .built)
|
||||
$(call CLEAN)
|
||||
|
||||
distclean: clean
|
||||
$(call DELFILE, .context)
|
||||
$(Q) $(MAKE) -C registry distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
|
||||
$(call DELFILE, Make.dep)
|
||||
$(call DELFILE, .depend)
|
||||
$(call DELFILE, namedapp_list.h)
|
||||
$(call DELFILE, namedapp_proto.h)
|
||||
$(call DELFILE, builtin_list.h)
|
||||
$(call DELFILE, builtin_proto.h)
|
||||
|
||||
-include Make.dep
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* apps/namedaps/namedapp.c
|
||||
* apps/builtin/builtin.c
|
||||
*
|
||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
@@ -40,7 +40,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <apps/apps.h>
|
||||
|
||||
#include <nuttx/binfmt/builtin.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
@@ -62,11 +63,11 @@ extern "C" {
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#include "namedapp_proto.h"
|
||||
#include "builtin_proto.h"
|
||||
|
||||
const struct namedapp_s namedapps[] =
|
||||
const struct builtin_s g_builtins[] =
|
||||
{
|
||||
# include "namedapp_list.h"
|
||||
# include "builtin_list.h"
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -88,9 +89,9 @@ const struct namedapp_s namedapps[] =
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int number_namedapps(void)
|
||||
int number_builtins(void)
|
||||
{
|
||||
return sizeof(namedapps)/sizeof(struct namedapp_s) - 1;
|
||||
return sizeof(g_builtins)/sizeof(struct builtin_s) - 1;
|
||||
}
|
||||
|
||||
|
||||
423
apps/builtin/exec_builtin.c
Normal file
423
apps/builtin/exec_builtin.c
Normal 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, ¶m);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now let the builtin application run */
|
||||
|
||||
sched_unlock();
|
||||
|
||||
/* Return the task ID of the new task if the task was sucessfully
|
||||
* started. Otherwise, ret will be ERROR (and the errno value will
|
||||
* be set appropriately).
|
||||
*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: builtin_proxy
|
||||
*
|
||||
* Description:
|
||||
* Perform output redirection, then execute the builtin task.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard task start-up parameters
|
||||
*
|
||||
* Returned Value:
|
||||
* Standard task return value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int builtin_proxy(int argc, char *argv[])
|
||||
{
|
||||
int fd;
|
||||
int ret = ERROR;
|
||||
|
||||
/* Open the output file for redirection */
|
||||
|
||||
svdbg("Open'ing redirfile=%s oflags=%04x mode=0644\n",
|
||||
g_builtin_parms.redirfile, g_builtin_parms.oflags);
|
||||
|
||||
fd = open(g_builtin_parms.redirfile, g_builtin_parms.oflags, 0644);
|
||||
if (fd < 0)
|
||||
{
|
||||
/* Remember the errno value. ret is already set to ERROR */
|
||||
|
||||
g_builtin_parms.errcode = errno;
|
||||
sdbg("ERROR: open of %s failed: %d\n",
|
||||
g_builtin_parms.redirfile, g_builtin_parms.errcode);
|
||||
}
|
||||
|
||||
/* Does the return file descriptor happen to match the required file
|
||||
* desciptor number?
|
||||
*/
|
||||
|
||||
else if (fd != 1)
|
||||
{
|
||||
/* No.. dup2 to get the correct file number */
|
||||
|
||||
svdbg("Dup'ing %d->1\n", fd);
|
||||
|
||||
ret = dup2(fd, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
g_builtin_parms.errcode = errno;
|
||||
sdbg("ERROR: dup2 failed: %d\n", g_builtin_parms.errcode);
|
||||
}
|
||||
|
||||
svdbg("Closing fd=%d\n", fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* Was the setup successful? */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
/* Yes.. Start the task. On success, the task ID of the builtin task
|
||||
* is returned; On failure, -1 (ERROR) is returned and the errno
|
||||
* is set appropriately.
|
||||
*/
|
||||
|
||||
ret = builtin_taskcreate(g_builtin_parms.index, g_builtin_parms.argv);
|
||||
if (ret < 0)
|
||||
{
|
||||
g_builtin_parms.errcode = errno;
|
||||
sdbg("ERROR: builtin_taskcreate failed: %d\n",
|
||||
g_builtin_parms.errcode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Post the semaphore to inform the parent task that we have completed
|
||||
* what we need to do.
|
||||
*/
|
||||
|
||||
g_builtin_parms.result = ret;
|
||||
builtin_semgive(&g_builtin_execsem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: builtin_startproxy
|
||||
*
|
||||
* Description:
|
||||
* Perform output redirection, then execute the builtin task.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard task start-up parameters
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the task ID of the builtin task is returned; On failure, -1
|
||||
* (ERROR) is returned and the errno is set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int builtin_startproxy(int index, FAR const char **argv,
|
||||
FAR const char *redirfile, int oflags)
|
||||
{
|
||||
struct sched_param param;
|
||||
pid_t proxy;
|
||||
int errcode;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(path);
|
||||
|
||||
svdbg("index=%d argv=%p redirfile=%s oflags=%04x\n",
|
||||
index, argv, redirfile, oflags);
|
||||
|
||||
/* We will have to go through an intermediary/proxy task in order to
|
||||
* perform the I/O redirection. This would be a natural place to fork().
|
||||
* However, true fork() behavior requires an MMU and most implementations
|
||||
* of vfork() are not capable of these operations.
|
||||
*
|
||||
* Even without fork(), we can still do the job, but parameter passing is
|
||||
* messier. Unfortunately, there is no (clean) way to pass binary values
|
||||
* as a task parameter, so we will use a semaphore-protected global
|
||||
* structure.
|
||||
*/
|
||||
|
||||
/* Get exclusive access to the global parameter structure */
|
||||
|
||||
bultin_semtake(&g_builtin_parmsem);
|
||||
|
||||
/* Populate the parameter structure */
|
||||
|
||||
g_builtin_parms.redirfile = redirfile;
|
||||
g_builtin_parms.argv = argv;
|
||||
g_builtin_parms.result = ERROR;
|
||||
g_builtin_parms.oflags = oflags;
|
||||
g_builtin_parms.index = index;
|
||||
|
||||
/* Get the priority of this (parent) task */
|
||||
|
||||
ret = sched_getparam(0, ¶m);
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = errno;
|
||||
sdbg("ERROR: sched_getparam failed: %d\n", errcode);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Start the intermediary/proxy task at the same priority as the parent task. */
|
||||
|
||||
proxy = TASK_CREATE("builtin_proxy", param.sched_priority,
|
||||
CONFIG_BUILTIN_PROXY_STACKSIZE, (main_t)builtin_proxy,
|
||||
(FAR const char **)NULL);
|
||||
if (proxy < 0)
|
||||
{
|
||||
errcode = errno;
|
||||
sdbg("ERROR: Failed to start builtin_proxy: %d\n", errcode);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Wait for the proxy to complete its job. We could use waitpid()
|
||||
* for this.
|
||||
*/
|
||||
|
||||
bultin_semtake(&g_builtin_execsem);
|
||||
|
||||
/* Get the result and relinquish our access to the parameter structure */
|
||||
|
||||
set_errno(g_builtin_parms.errcode);
|
||||
builtin_semgive(&g_builtin_parmsem);
|
||||
return g_builtin_parms.result;
|
||||
|
||||
errout:
|
||||
set_errno(errcode);
|
||||
builtin_semgive(&g_builtin_parmsem);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: exec_builtin
|
||||
*
|
||||
* Description:
|
||||
* Executes builtin applications registered during 'make context' time.
|
||||
* New application is run in a separate task context (and thread).
|
||||
*
|
||||
* Input Parameter:
|
||||
* filename - Name of the linked-in binary to be started.
|
||||
* argv - Argument list
|
||||
* redirfile - If output if redirected, this parameter will be non-NULL
|
||||
* and will provide the full path to the file.
|
||||
* oflags - If output is redirected, this parameter will provide the
|
||||
* open flags to use. This will support file replacement
|
||||
* of appending to an existing file.
|
||||
*
|
||||
* Returned Value:
|
||||
* This is an end-user function, so it follows the normal convention:
|
||||
* Returns the PID of the exec'ed module. On failure, it.returns
|
||||
* -1 (ERROR) and sets errno appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int exec_builtin(FAR const char *appname, FAR const char **argv,
|
||||
FAR const char *redirfile, int oflags)
|
||||
{
|
||||
int index;
|
||||
int ret = ERROR;
|
||||
|
||||
/* Verify that an application with this name exists */
|
||||
|
||||
index = builtin_isavail(appname);
|
||||
if (index >= 0)
|
||||
{
|
||||
/* Is output being redirected? */
|
||||
|
||||
if (redirfile)
|
||||
{
|
||||
ret = builtin_startproxy(index, argv, redirfile, oflags);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Start the builtin application task */
|
||||
|
||||
ret = builtin_taskcreate(index, argv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Return the task ID of the new task if the task was sucessfully
|
||||
* started. Otherwise, ret will be ERROR (and the errno value will
|
||||
* be set appropriately).
|
||||
*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
61
apps/builtin/registry/Makefile
Normal file
61
apps/builtin/registry/Makefile
Normal 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)
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -54,12 +54,37 @@ static sem_t sem;
|
||||
static bool sigreceived = false;
|
||||
static bool threadexited = false;
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
static void death_of_child(int signo, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
/* Use of printf in a signal handler is NOT safe! It can cause deadlocks!
|
||||
* Also, signals are not queued by NuttX. As a consequence, some
|
||||
* notifications will get lost (or the info data can be overwrittedn)!
|
||||
* Because POSIX does not require signals to be queued, I do not think
|
||||
* that this is a bug (the overwriting is a bug, however).
|
||||
*/
|
||||
|
||||
if (info)
|
||||
{
|
||||
printf("death_of_child: PID %d received signal=%d code=%d pid=%d status=%d\n",
|
||||
getpid(), signo, info->si_code, info->si_pid, info->si_status);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("death_of_child: PID %d received signal=%d (no info?)\n",
|
||||
getpid(), signo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void wakeup_action(int signo, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
sigset_t oldset;
|
||||
sigset_t allsigs;
|
||||
int status;
|
||||
|
||||
/* Use of printf in a signal handler is NOT safe! It can cause deadlocks! */
|
||||
|
||||
printf("wakeup_action: Received signal %d\n" , signo);
|
||||
|
||||
sigreceived = true;
|
||||
@@ -186,6 +211,11 @@ static int waiter_main(int argc, char *argv[])
|
||||
|
||||
void sighand_test(void)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
struct sigaction act;
|
||||
struct sigaction oact;
|
||||
sigset_t sigset;
|
||||
#endif
|
||||
struct sched_param param;
|
||||
union sigval sigvalue;
|
||||
pid_t waiterpid;
|
||||
@@ -195,6 +225,32 @@ void sighand_test(void)
|
||||
printf("sighand_test: Initializing semaphore to 0\n" );
|
||||
sem_init(&sem, 0, 0);
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
printf("sighand_test: Unmasking SIGCHLD\n");
|
||||
|
||||
(void)sigemptyset(&sigset);
|
||||
(void)sigaddset(&sigset, SIGCHLD);
|
||||
status = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("sighand_test: ERROR sigprocmask failed, status=%d\n",
|
||||
status);
|
||||
}
|
||||
|
||||
printf("sighand_test: Registering SIGCHLD handler\n" );
|
||||
act.sa_sigaction = death_of_child;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
|
||||
(void)sigfillset(&act.sa_mask);
|
||||
(void)sigdelset(&act.sa_mask, SIGCHLD);
|
||||
|
||||
status = sigaction(SIGCHLD, &act, &oact);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("waiter_main: ERROR sigaction failed, status=%d\n" , status);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Start waiter thread */
|
||||
|
||||
printf("sighand_test: Starting waiter task\n" );
|
||||
@@ -262,6 +318,13 @@ void sighand_test(void)
|
||||
printf("sighand_test: ERROR signal handler did not run\n" );
|
||||
}
|
||||
|
||||
/* Detach the signal handler */
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
act.sa_sigaction = SIG_DFL;
|
||||
status = sigaction(SIGCHLD, &act, &oact);
|
||||
#endif
|
||||
|
||||
printf("sighand_test: done\n" );
|
||||
FFLUSH();
|
||||
}
|
||||
|
||||
103
apps/examples/ostest/vfork.c
Normal file
103
apps/examples/ostest/vfork.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/****************************************************************************
|
||||
* examples/ostest/vfork.c
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "ostest.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARCH_HAVE_VFORK) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||
static volatile bool g_vforkchild;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int vfork_test(void)
|
||||
{
|
||||
#if defined(CONFIG_ARCH_HAVE_VFORK) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||
pid_t pid;
|
||||
|
||||
g_vforkchild = false;
|
||||
pid = vfork();
|
||||
if (pid == 0)
|
||||
{
|
||||
/* There is not very much that the child is permitted to do. Perhaps
|
||||
* it can just set g_vforkchild.
|
||||
*/
|
||||
|
||||
g_vforkchild = true;
|
||||
exit(0);
|
||||
}
|
||||
else if (pid < 0)
|
||||
{
|
||||
printf("vfork_test: vfork() failed: %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sleep(1);
|
||||
if (g_vforkchild)
|
||||
{
|
||||
printf("vfork_test: Child %d ran successfully\n", pid);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("vfork_test: ERROR Child %d did not run\n", pid);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
269
apps/examples/ostest/waitpid.c
Normal file
269
apps/examples/ostest/waitpid.c
Normal file
@@ -0,0 +1,269 @@
|
||||
/****************************************************************************
|
||||
* examples/ostest/waitpid.c
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "ostest.h"
|
||||
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define RETURN_STATUS 14
|
||||
#define NCHILDREN 3
|
||||
#define PRIORITY 100
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static int g_waitpids[NCHILDREN];
|
||||
|
||||
/****************************************************************************
|
||||
* Priviate Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int waitpid_main(int argc, char *argv[])
|
||||
{
|
||||
pid_t me = getpid();
|
||||
|
||||
printf("waitpid_main: PID %d Started\n", me);
|
||||
sleep(3);
|
||||
printf("waitpid_main: PID %d exitting with result=%d\n", me, RETURN_STATUS);
|
||||
return RETURN_STATUS;
|
||||
}
|
||||
|
||||
static void waitpid_start_children(void)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NCHILDREN; i++)
|
||||
{
|
||||
ret = TASK_CREATE("waitpid", PRIORITY, STACKSIZE, waitpid_main, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("waitpid_start_child: ERROR Failed to start user_main\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("waitpid_start_child: Started waitpid_main at PID=%d\n", ret);
|
||||
}
|
||||
|
||||
g_waitpids[i] = ret;
|
||||
}
|
||||
}
|
||||
|
||||
static void waitpid_last(void)
|
||||
{
|
||||
int stat_loc;
|
||||
int ret;
|
||||
|
||||
printf("waitpid_last: Waiting for PID=%d with waitpid()\n",
|
||||
g_waitpids[NCHILDREN-1]);
|
||||
|
||||
ret = (int)waitpid(g_waitpids[NCHILDREN-1], &stat_loc, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("waitpid_last: ERROR: PID %d waitpid failed: %d\n",
|
||||
g_waitpids[NCHILDREN-1], errcode);
|
||||
}
|
||||
else if (stat_loc != RETURN_STATUS)
|
||||
{
|
||||
printf("waitpid_last: ERROR: PID %d return status is %d, expected %d\n",
|
||||
g_waitpids[NCHILDREN-1], stat_loc, RETURN_STATUS);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("waitpid_last: PID %d waitpid succeeded with stat_loc=%d\n",
|
||||
g_waitpids[NCHILDREN-1], stat_loc);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int waitpid_test(void)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
siginfo_t info;
|
||||
#endif
|
||||
int stat_loc;
|
||||
int ret;
|
||||
|
||||
/* Start the children and wait for first one to complete */
|
||||
|
||||
printf("\nTest waitpid()\n");
|
||||
waitpid_start_children();
|
||||
|
||||
printf("waitpid_test: Waiting for PID=%d with waitpid()\n", g_waitpids[0]);
|
||||
ret = (int)waitpid(g_waitpids[0], &stat_loc, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("waitpid_test: ERROR: PID %d waitpid failed: %d\n",
|
||||
g_waitpids[0], errcode);
|
||||
}
|
||||
else if (ret != g_waitpids[0])
|
||||
{
|
||||
printf("waitpid_test: ERROR: PID %d wait returned PID %d\n",
|
||||
g_waitpids[0], ret);
|
||||
}
|
||||
else if (stat_loc != RETURN_STATUS)
|
||||
{
|
||||
printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
|
||||
g_waitpids[0], stat_loc, RETURN_STATUS);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("waitpid_test: PID %d waitpid succeeded with stat_loc=%d\n",
|
||||
g_waitpids[0], stat_loc);
|
||||
}
|
||||
|
||||
/* Wait a big to make sure that the other threads complete */
|
||||
|
||||
waitpid_last();
|
||||
sleep(1);
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
/* Start the children and wait for first one to complete */
|
||||
|
||||
printf("\nTest waitid(P_PID)\n");
|
||||
waitpid_start_children();
|
||||
|
||||
printf("waitpid_test: Waiting for PID=%d with waitid()\n", g_waitpids[0]);
|
||||
ret = waitid(P_PID, (id_t)g_waitpids[0], &info, WEXITED);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("waitpid_test: ERROR: PID %d waitid failed: %d\n",
|
||||
g_waitpids[0], errcode);
|
||||
}
|
||||
else if (info.si_pid != g_waitpids[0])
|
||||
{
|
||||
printf("waitpid_test: ERROR: PID %d waitid returned PID %d\n",
|
||||
g_waitpids[0], info.si_pid);
|
||||
}
|
||||
else if (info.si_status != RETURN_STATUS)
|
||||
{
|
||||
printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
|
||||
info.si_pid, info.si_status, RETURN_STATUS);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("waitpid_test: waitid PID %d succeeded with si_status=%d\n",
|
||||
info.si_pid, info.si_status);
|
||||
}
|
||||
|
||||
/* Wait a big to make sure that the other threads complete */
|
||||
|
||||
waitpid_last();
|
||||
sleep(1);
|
||||
|
||||
/* Start the children and wait for any one to complete */
|
||||
|
||||
printf("\nTest waitid(P_ALL)\n");
|
||||
waitpid_start_children();
|
||||
|
||||
printf("waitpid_test: Waiting for any child with waitid()\n");
|
||||
ret = waitid(P_ALL, 0, &info, WEXITED);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("waitpid_test: ERROR: waitid failed: %d\n", errcode);
|
||||
}
|
||||
else if (info.si_status != RETURN_STATUS)
|
||||
{
|
||||
printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
|
||||
info.si_pid, info.si_status, RETURN_STATUS);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("waitpid_test: PID %d waitid succeeded with si_status=%d\n",
|
||||
info.si_pid, info.si_status);
|
||||
}
|
||||
|
||||
/* Wait a big to make sure that the other threads complete */
|
||||
|
||||
waitpid_last();
|
||||
sleep(1);
|
||||
|
||||
/* Start the children and wait for first one to complete */
|
||||
|
||||
printf("\nTest wait()\n");
|
||||
waitpid_start_children();
|
||||
|
||||
printf("waitpid_test: Waiting for any child with wait()\n");
|
||||
ret = (int)wait(&stat_loc);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("waitpid_test: ERROR: wait failed: %d\n", errcode);
|
||||
}
|
||||
else if (stat_loc != RETURN_STATUS)
|
||||
{
|
||||
printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
|
||||
ret, stat_loc, RETURN_STATUS);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("waitpid_test: PID %d wait succeeded with stat_loc=%d\n",
|
||||
ret, stat_loc);
|
||||
}
|
||||
|
||||
/* Wait a big to make sure that the other threads complete */
|
||||
|
||||
waitpid_last();
|
||||
sleep(1);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SCHED_WAITPID */
|
||||
29
apps/examples/posix_spawn/Kconfig
Normal file
29
apps/examples/posix_spawn/Kconfig
Normal file
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
|
||||
config EXAMPLES_POSIXSPAWN
|
||||
bool "posix_spawn Unit Test"
|
||||
default n
|
||||
---help---
|
||||
Enable the posix_spawn() unit test
|
||||
|
||||
if EXAMPLES_POSIXSPAWN
|
||||
config EXAMPLES_POSIXSPAWN_DEVMINOR
|
||||
int "ROMFS Minor Device Number"
|
||||
default 0
|
||||
---help---
|
||||
The minor device number of the ROMFS block. For example, the N in /dev/ramN.
|
||||
Used for registering the RAM block driver that will hold the ROMFS file system
|
||||
containing the ELF executables to be tested. Default: 0
|
||||
|
||||
config EXAMPLES_POSIXSPAWN_DEVPATH
|
||||
string "ROMFS Devie Path"
|
||||
default "/dev/ram0"
|
||||
---help---
|
||||
The path to the ROMFS block driver device. This must match EXAMPLES_POSIXSPAWN_DEVMINOR.
|
||||
Used for registering the RAM block driver that will hold the ROMFS file system
|
||||
containing the ELF executables to be tested. Default: "/dev/ram0"
|
||||
|
||||
endif
|
||||
130
apps/examples/posix_spawn/Makefile
Normal file
130
apps/examples/posix_spawn/Makefile
Normal 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
|
||||
88
apps/examples/posix_spawn/filesystem/Makefile
Normal file
88
apps/examples/posix_spawn/filesystem/Makefile
Normal 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)
|
||||
78
apps/examples/posix_spawn/filesystem/hello/hello.c
Normal file
78
apps/examples/posix_spawn/filesystem/hello/hello.c
Normal 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;
|
||||
}
|
||||
51
apps/examples/posix_spawn/filesystem/mksymtab.sh
Executable file
51
apps/examples/posix_spawn/filesystem/mksymtab.sh
Executable 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);"
|
||||
|
||||
63
apps/examples/posix_spawn/filesystem/redirect/redirect.c
Normal file
63
apps/examples/posix_spawn/filesystem/redirect/redirect.c
Normal 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;
|
||||
}
|
||||
2
apps/examples/posix_spawn/filesystem/testdata.txt
Normal file
2
apps/examples/posix_spawn/filesystem/testdata.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Now is the time for all good men to come to the aid of their party.
|
||||
|
||||
460
apps/examples/posix_spawn/spawn_main.c
Normal file
460
apps/examples/posix_spawn/spawn_main.c
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
111
apps/include/builtin.h
Normal 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 */
|
||||
@@ -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)
|
||||
|
||||
@@ -108,7 +108,6 @@ context:
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
$(call DELFILE, .context)
|
||||
$(call DELFILE, .built)
|
||||
$(call CLEAN)
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
|
||||
config NAMEDAPP
|
||||
bool "Support named applications"
|
||||
default n
|
||||
---help---
|
||||
Enable support for named applications. This features assigns a string
|
||||
name to an application. This feature is also the underlying requirement
|
||||
to support built-in applications in the NuttShell (NSH).
|
||||
|
||||
if NAMEDAPP
|
||||
endif
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
|
||||
@@ -491,7 +491,8 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline);
|
||||
/* Application interface */
|
||||
|
||||
#ifdef CONFIG_NSH_BUILTIN_APPS
|
||||
int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, FAR char **argv);
|
||||
int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
FAR char **argv, FAR const char *redirfile, int oflags);
|
||||
#endif
|
||||
|
||||
/* Working directory support */
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
/****************************************************************************
|
||||
* apps/nshlib/nsh_apps.c
|
||||
* apps/nshlib/nsh_builtin.c
|
||||
*
|
||||
* Originally by:
|
||||
*
|
||||
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||
* Author: Uros Platise <uros.platise@isotel.eu>
|
||||
*
|
||||
* With subsequent updates, modifications, and general maintenance by:
|
||||
*
|
||||
* Copyright (C) 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -48,7 +54,8 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <apps/apps.h>
|
||||
#include <nuttx/binfmt/builtin.h>
|
||||
#include <apps/builtin.h>
|
||||
|
||||
#include "nsh.h"
|
||||
#include "nsh_console.h"
|
||||
@@ -84,13 +91,13 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_execapp
|
||||
* Name: nsh_builtin
|
||||
*
|
||||
* Description:
|
||||
* Attempt to execute the application task whose name is 'cmd'
|
||||
*
|
||||
* Returned Value:
|
||||
* <0 If exec_namedapp() fails, then the negated errno value
|
||||
* <0 If exec_builtin() fails, then the negated errno value
|
||||
* is returned.
|
||||
* -1 (ERROR) if the application task corresponding to 'cmd' could not
|
||||
* be started (possibly because it doesn not exist).
|
||||
@@ -104,8 +111,8 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
FAR char **argv)
|
||||
int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
FAR char **argv, FAR const char *redirfile, int oflags)
|
||||
{
|
||||
int ret = OK;
|
||||
|
||||
@@ -119,7 +126,7 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
* applications.
|
||||
*/
|
||||
|
||||
ret = exec_namedapp(cmd, (FAR const char **)argv);
|
||||
ret = exec_builtin(cmd, (FAR const char **)argv, redirfile, oflags);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* The application was successfully started (but still blocked because
|
||||
@@ -191,7 +198,7 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
#if !defined(CONFIG_SCHED_WAITPID) || !defined(CONFIG_NSH_DISABLEBG)
|
||||
{
|
||||
struct sched_param param;
|
||||
sched_getparam(0, ¶m);
|
||||
sched_getparam(ret, ¶m);
|
||||
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
538
apps/nshlib/nsh_codeccmd.c
Normal 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 */
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -100,7 +100,6 @@ clean:
|
||||
$(call CLEAN)
|
||||
|
||||
distclean: clean
|
||||
$(call DELFILE, .context)
|
||||
$(call DELFILE, Make.dep)
|
||||
$(call DELFILE, .depend)
|
||||
|
||||
|
||||
171
nuttx/ChangeLog
171
nuttx/ChangeLog
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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
|
||||
#
|
||||
|
||||
284
nuttx/README.txt
284
nuttx/README.txt
@@ -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
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
224
nuttx/TODO
224
nuttx/TODO
@@ -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)
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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-
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
142
nuttx/arch/arm/src/armv7-m/vfork.S
Normal file
142
nuttx/arch/arm/src/armv7-m/vfork.S
Normal 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
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
233
nuttx/arch/arm/src/common/up_vfork.c
Normal file
233
nuttx/arch/arm/src/common/up_vfork.c
Normal 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);
|
||||
}
|
||||
88
nuttx/arch/arm/src/common/up_vfork.h
Normal file
88
nuttx/arch/arm/src/common/up_vfork.h
Normal 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 */
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, ¶m);
|
||||
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
196
nuttx/binfmt/builtin.c
Normal 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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
4
nuttx/binfmt/libbuiltin/Kconfig
Normal file
4
nuttx/binfmt/libbuiltin/Kconfig
Normal file
@@ -0,0 +1,4 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
52
nuttx/binfmt/libbuiltin/Make.defs
Normal file
52
nuttx/binfmt/libbuiltin/Make.defs
Normal 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
|
||||
92
nuttx/binfmt/libbuiltin/libbuiltin_getname.c
Normal file
92
nuttx/binfmt/libbuiltin/libbuiltin_getname.c
Normal 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;
|
||||
}
|
||||
@@ -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, ¶m);
|
||||
}
|
||||
#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;
|
||||
}
|
||||
@@ -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
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
1218
nuttx/drivers/lcd/ug-2864hsweg01.c
Normal file
1218
nuttx/drivers/lcd/ug-2864hsweg01.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user