mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-20 20:03:54 +08:00
Merge Nuttx r5554
This commit is contained in:
@@ -485,3 +485,10 @@
|
||||
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.
|
||||
* apps/nshlib/nsh_fileapp.c: Add the ability to execute a file
|
||||
from a file system using posix_spawn().
|
||||
* apps/builtin/: Extensions from Mike Smith.
|
||||
* apps/examples/ftpd/Makefile: Name ftpd_start is not the name of
|
||||
the entrypoint. Should be ftpd_main (from Yan T.)
|
||||
* apps/netutils/telnetd/telnetd_driver: Was stuck in a loop if
|
||||
recv[from]() ever returned a value <= 0.
|
||||
|
||||
@@ -39,7 +39,7 @@ include $(APPDIR)/Make.defs
|
||||
# Source and object files
|
||||
|
||||
ASRCS =
|
||||
CSRCS = builtin.c exec_builtin.c
|
||||
CSRCS = builtin.c builtin_list.c exec_builtin.c
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
+8
-25
@@ -55,27 +55,8 @@
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#include "builtin_proto.h"
|
||||
|
||||
const struct builtin_s g_builtins[] =
|
||||
{
|
||||
# include "builtin_list.h"
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
extern const struct builtin_s g_builtins[];
|
||||
extern const int g_builtin_count;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
@@ -89,9 +70,11 @@ const struct builtin_s g_builtins[] =
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int number_builtins(void)
|
||||
FAR const struct builtin_s *builtin_for_index(int index)
|
||||
{
|
||||
return sizeof(g_builtins)/sizeof(struct builtin_s) - 1;
|
||||
if (index < g_builtin_count)
|
||||
{
|
||||
return &g_builtins[index];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
* apps/builtin/builtin_list.c
|
||||
*
|
||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Authors: Uros Platise <uros.platise@isotel.eu>
|
||||
* 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>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#include "builtin_proto.h"
|
||||
|
||||
const struct builtin_s g_builtins[] =
|
||||
{
|
||||
# include "builtin_list.h"
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
const int g_builtin_count = sizeof(g_builtins) / sizeof(g_builtins[0]);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
+58
-14
@@ -46,6 +46,7 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sched.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
@@ -92,7 +93,9 @@ struct builtin_parms_s
|
||||
****************************************************************************/
|
||||
|
||||
static sem_t g_builtin_parmsem = SEM_INITIALIZER(1);
|
||||
#ifndef CONFIG_SCHED_WAITPID
|
||||
static sem_t g_builtin_execsem = SEM_INITIALIZER(0);
|
||||
#endif
|
||||
static struct builtin_parms_s g_builtin_parms;
|
||||
|
||||
/****************************************************************************
|
||||
@@ -121,7 +124,7 @@ static void bultin_semtake(FAR sem_t *sem)
|
||||
do
|
||||
{
|
||||
ret = sem_wait(sem);
|
||||
ASSERT(ret == 0 || errno == EINTR);
|
||||
ASSERT(ret == 0 || get_errno() == EINTR);
|
||||
}
|
||||
while (ret != 0);
|
||||
}
|
||||
@@ -142,8 +145,17 @@ static void bultin_semtake(FAR sem_t *sem)
|
||||
|
||||
static int builtin_taskcreate(int index, FAR const char **argv)
|
||||
{
|
||||
FAR const struct builtin_s *b;
|
||||
int ret;
|
||||
|
||||
b = builtin_for_index(index);
|
||||
|
||||
if (b == NULL)
|
||||
{
|
||||
set_errno(ENOENT);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
@@ -153,8 +165,7 @@ static int builtin_taskcreate(int index, FAR const char **argv)
|
||||
|
||||
/* Start the builtin application task */
|
||||
|
||||
ret = TASK_CREATE(g_builtins[index].name, g_builtins[index].priority,
|
||||
g_builtins[index].stacksize, g_builtins[index].main,
|
||||
ret = TASK_CREATE(b->name, b->priority, b->stacksize, b->main,
|
||||
(argv) ? &argv[1] : (FAR const char **)NULL);
|
||||
|
||||
/* If robin robin scheduling is enabled, then set the scheduling policy
|
||||
@@ -171,7 +182,7 @@ static int builtin_taskcreate(int index, FAR const char **argv)
|
||||
* new task cannot yet have changed from its initial value.
|
||||
*/
|
||||
|
||||
param.sched_priority = g_builtins[index].priority;
|
||||
param.sched_priority = b->priority;
|
||||
(void)sched_setscheduler(ret, SCHED_RR, ¶m);
|
||||
}
|
||||
#endif
|
||||
@@ -217,7 +228,7 @@ static int builtin_proxy(int argc, char *argv[])
|
||||
{
|
||||
/* Remember the errno value. ret is already set to ERROR */
|
||||
|
||||
g_builtin_parms.errcode = errno;
|
||||
g_builtin_parms.errcode = get_errno();
|
||||
sdbg("ERROR: open of %s failed: %d\n",
|
||||
g_builtin_parms.redirfile, g_builtin_parms.errcode);
|
||||
}
|
||||
@@ -235,7 +246,7 @@ static int builtin_proxy(int argc, char *argv[])
|
||||
ret = dup2(fd, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
g_builtin_parms.errcode = errno;
|
||||
g_builtin_parms.errcode = get_errno();
|
||||
sdbg("ERROR: dup2 failed: %d\n", g_builtin_parms.errcode);
|
||||
}
|
||||
|
||||
@@ -255,18 +266,26 @@ static int builtin_proxy(int argc, char *argv[])
|
||||
ret = builtin_taskcreate(g_builtin_parms.index, g_builtin_parms.argv);
|
||||
if (ret < 0)
|
||||
{
|
||||
g_builtin_parms.errcode = errno;
|
||||
g_builtin_parms.errcode = get_errno();
|
||||
sdbg("ERROR: builtin_taskcreate failed: %d\n",
|
||||
g_builtin_parms.errcode);
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: There is a logical error here if CONFIG_SCHED_HAVE_PARENT is
|
||||
* defined: The new task is the child of this proxy task, not the
|
||||
* original caller. As a consequence, operations like waitpid() will
|
||||
* fail on the caller's thread.
|
||||
*/
|
||||
|
||||
/* Post the semaphore to inform the parent task that we have completed
|
||||
* what we need to do.
|
||||
*/
|
||||
|
||||
g_builtin_parms.result = ret;
|
||||
#ifndef CONFIG_SCHED_WAITPID
|
||||
builtin_semgive(&g_builtin_execsem);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -291,10 +310,11 @@ static inline int builtin_startproxy(int index, FAR const char **argv,
|
||||
struct sched_param param;
|
||||
pid_t proxy;
|
||||
int errcode;
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
int status;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
// DEBUGASSERT(path);
|
||||
|
||||
svdbg("index=%d argv=%p redirfile=%s oflags=%04x\n",
|
||||
index, argv, redirfile, oflags);
|
||||
|
||||
@@ -326,11 +346,21 @@ static inline int builtin_startproxy(int index, FAR const char **argv,
|
||||
ret = sched_getparam(0, ¶m);
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = errno;
|
||||
errcode = get_errno();
|
||||
sdbg("ERROR: sched_getparam failed: %d\n", errcode);
|
||||
goto errout;
|
||||
goto errout_with_sem;
|
||||
}
|
||||
|
||||
/* Disable pre-emption so that the proxy does not run until we waitpid
|
||||
* is called. This is probably unnecessary since the builtin_proxy has
|
||||
* the same priority as this thread; it should be schedule behind this
|
||||
* task in the ready-to-run list.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
sched_lock();
|
||||
#endif
|
||||
|
||||
/* Start the intermediary/proxy task at the same priority as the parent task. */
|
||||
|
||||
proxy = TASK_CREATE("builtin_proxy", param.sched_priority,
|
||||
@@ -338,16 +368,25 @@ static inline int builtin_startproxy(int index, FAR const char **argv,
|
||||
(FAR const char **)NULL);
|
||||
if (proxy < 0)
|
||||
{
|
||||
errcode = errno;
|
||||
errcode = get_errno();
|
||||
sdbg("ERROR: Failed to start builtin_proxy: %d\n", errcode);
|
||||
goto errout;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Wait for the proxy to complete its job. We could use waitpid()
|
||||
* for this.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
ret = waitpid(proxy, &status, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
sdbg("ERROR: waitpid() failed: %d\n", get_errno());
|
||||
goto errout_with_lock;
|
||||
}
|
||||
#else
|
||||
bultin_semtake(&g_builtin_execsem);
|
||||
#endif
|
||||
|
||||
/* Get the result and relinquish our access to the parameter structure */
|
||||
|
||||
@@ -355,7 +394,12 @@ static inline int builtin_startproxy(int index, FAR const char **argv,
|
||||
builtin_semgive(&g_builtin_parmsem);
|
||||
return g_builtin_parms.result;
|
||||
|
||||
errout:
|
||||
errout_with_lock:
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
sched_unlock();
|
||||
#endif
|
||||
|
||||
errout_with_sem:
|
||||
set_errno(errcode);
|
||||
builtin_semgive(&g_builtin_parmsem);
|
||||
return ERROR;
|
||||
|
||||
@@ -46,6 +46,12 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#if defined(CONFIG_FS_BINFS) && (CONFIG_BUILTIN)
|
||||
#include <nuttx/binfmt/builtin.h>
|
||||
#endif
|
||||
#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
|
||||
#include <nuttx/binfmt/symtab.h>
|
||||
#endif
|
||||
|
||||
#include <apps/nsh.h>
|
||||
|
||||
@@ -75,6 +81,21 @@
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* If posix_spawn() is enabled as required for CONFIG_NSH_FILE_APPS, then
|
||||
* a symbol table is needed by the internals of posix_spawn(). The symbol
|
||||
* table is needed to support ELF and NXFLAT binaries to dynamically link to
|
||||
* the base code. However, if only the BINFS file system is supported, then
|
||||
* no Makefile is needed.
|
||||
*
|
||||
* This is a kludge to plug the missing file system in the case where BINFS
|
||||
* is used. REVISIT: This will, of course, be in the way if you want to
|
||||
* support ELF or NXFLAT binaries!
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
|
||||
const struct symtab_s CONFIG_EXECFUNCS_SYMTAB[1];
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@@ -98,6 +119,23 @@ int nsh_main(int argc, char *argv[])
|
||||
up_cxxinitialize();
|
||||
#endif
|
||||
|
||||
/* Make sure that we are using our symbol take */
|
||||
|
||||
#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
|
||||
exec_setsymtab(CONFIG_EXECFUNCS_SYMTAB, 0);
|
||||
#endif
|
||||
|
||||
/* Register the BINFS file system */
|
||||
|
||||
#if defined(CONFIG_FS_BINFS) && (CONFIG_BUILTIN)
|
||||
ret = builtin_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: builtin_initialize failed: %d\n", ret);
|
||||
exitval = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize the NSH library */
|
||||
|
||||
nsh_initialize();
|
||||
|
||||
+10
-1
@@ -14,7 +14,7 @@ config NSH_LIBRARY
|
||||
if NSH_LIBRARY
|
||||
config NSH_BUILTIN_APPS
|
||||
bool "Enable built-in applications"
|
||||
default y
|
||||
default n
|
||||
depends on BUILTIN
|
||||
---help---
|
||||
Support external registered, "built-in" applications that can be
|
||||
@@ -22,6 +22,15 @@ config NSH_BUILTIN_APPS
|
||||
more information). This options requires support for builtin
|
||||
applications (BUILTIN).
|
||||
|
||||
config NSH_FILE_APPS
|
||||
bool "Enable execution of program files"
|
||||
default n
|
||||
depends on LIBC_EXECFUNCS
|
||||
---help---
|
||||
Support execution of program files residing within a file
|
||||
system. This options requires support for the posix_spawn()
|
||||
interface (LIBC_EXECFUNCS).
|
||||
|
||||
menu "Disable Individual commands"
|
||||
|
||||
config NSH_DISABLE_BASE64DEC
|
||||
|
||||
@@ -47,6 +47,10 @@ ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||
CSRCS += nsh_builtin.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NSH_FILE_APPS),y)
|
||||
CSRCS += nsh_fileapps.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NSH_ROMFSETC),y)
|
||||
CSRCS += nsh_romfsetc.c
|
||||
endif
|
||||
|
||||
@@ -495,6 +495,11 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
FAR char **argv, FAR const char *redirfile, int oflags);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NSH_FILE_APPS
|
||||
int nsh_fileapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
FAR char **argv, FAR const char *redirfile, int oflags);
|
||||
#endif
|
||||
|
||||
/* Working directory support */
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||
|
||||
+49
-14
@@ -116,8 +116,8 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
{
|
||||
int ret = OK;
|
||||
|
||||
/* Lock the scheduler to prevent the application from running until the
|
||||
* waitpid() has been called.
|
||||
/* Lock the scheduler in an attempt to prevent the application from
|
||||
* running until waitpid() has been called.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
@@ -129,16 +129,20 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
ret = exec_builtin(cmd, (FAR const char **)argv, redirfile, oflags);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* The application was successfully started (but still blocked because
|
||||
* the scheduler is locked). If the application was not backgrounded,
|
||||
* then we need to wait here for the application to exit. These really
|
||||
* only works works with the following options:
|
||||
/* The application was successfully started with pre-emption disabled.
|
||||
* In the simplest cases, the application will not have run because the
|
||||
* the scheduler is locked. But in the case where I/O was redirected, a
|
||||
* proxy task ran and broke our lock. As result, the application may
|
||||
* have aso ran if its priority was higher than than the priority of
|
||||
* this thread.
|
||||
*
|
||||
* If the application did not run to completion and if the application
|
||||
* was not backgrounded, then we need to wait here for the application
|
||||
* to exit. This only works works with the following options:
|
||||
*
|
||||
* - CONFIG_NSH_DISABLEBG - Do not run commands in background
|
||||
* - CONFIG_SCHED_WAITPID - Required to run external commands in
|
||||
* foreground
|
||||
*
|
||||
* These concepts do not apply cleanly to the external applications.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
@@ -154,15 +158,46 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* Wait for the application to exit. Since we have locked the
|
||||
* scheduler above, we know that the application has not yet
|
||||
* started and there is no possibility that it has already exited.
|
||||
* The scheduler will be unlocked while waitpid is waiting and the
|
||||
* application will be able to run.
|
||||
/* Wait for the application to exit. We did lock the scheduler
|
||||
* above, but that does not guarantee that the application did not
|
||||
* already run to completion in the case where I/O was redirected.
|
||||
* Here the scheduler will be unlocked while waitpid is waiting
|
||||
* and if the application has not yet run, it will now be able to
|
||||
* do so.
|
||||
*
|
||||
* Also, if CONFIG_SCHED_HAVE_PARENT is defined waitpid() might fail
|
||||
* even if task is still active: If the I/O was re-directed by a
|
||||
* proxy task, then the ask is a child of the proxy, and not this
|
||||
* task. waitpid() fails with ECHILD in either case.
|
||||
*/
|
||||
|
||||
ret = waitpid(ret, &rc, 0);
|
||||
if (ret >= 0)
|
||||
if (ret < 0)
|
||||
{
|
||||
/* If the child thread does not exist, waitpid() will return
|
||||
* the error ECHLD. Since we know that the task was successfully
|
||||
* started, this must be one of the cases described above; we
|
||||
* have to assume that the task already exit'ed. In this case,
|
||||
* we have no idea if the application ran successfully or not
|
||||
* (because NuttX does not retain exit status of child tasks).
|
||||
* Let's assume that is did run successfully.
|
||||
*/
|
||||
|
||||
int errcode = errno;
|
||||
if (errcode == ECHILD)
|
||||
{
|
||||
ret = OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsh_output(vtbl, g_fmtcmdfailed, cmd, "waitpid",
|
||||
NSH_ERRNO_OF(errcode));
|
||||
}
|
||||
}
|
||||
|
||||
/* Waitpid completed the wait successfully */
|
||||
|
||||
else
|
||||
{
|
||||
/* We can't return the exact status (nsh has nowhere to put it)
|
||||
* so just pass back zero/nonzero in a fashion that doesn't look
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
/****************************************************************************
|
||||
* apps/nshlib/nsh_fileapps.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>
|
||||
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <spawn.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nsh.h"
|
||||
#include "nsh_console.h"
|
||||
|
||||
#ifdef CONFIG_NSH_FILE_APPS
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_fileapp
|
||||
*
|
||||
* Description:
|
||||
* Attempt to execute the application task whose name is 'cmd'
|
||||
*
|
||||
* Returned 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).
|
||||
* 0 (OK) if the application task corresponding to 'cmd' 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nsh_fileapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
FAR char **argv, FAR const char *redirfile, int oflags)
|
||||
{
|
||||
posix_spawn_file_actions_t file_actions;
|
||||
posix_spawnattr_t attr;
|
||||
pid_t pid;
|
||||
int ret;
|
||||
|
||||
/* Initialize the attributes file actions structure */
|
||||
|
||||
ret = posix_spawn_file_actions_init(&file_actions);
|
||||
if (ret != 0)
|
||||
{
|
||||
/* posix_spawn_file_actions_init returns a positive errno value on
|
||||
* failure.
|
||||
*/
|
||||
|
||||
nsh_output(vtbl, g_fmtcmdfailed, cmd, "posix_spawn_file_actions_init",
|
||||
NSH_ERRNO_OF(ret));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ret = posix_spawnattr_init(&attr);
|
||||
if (ret != 0)
|
||||
{
|
||||
/* posix_spawnattr_init returns a positive errno value on failure. */
|
||||
|
||||
nsh_output(vtbl, g_fmtcmdfailed, cmd, "posix_spawnattr_init",
|
||||
NSH_ERRNO);
|
||||
goto errout_with_actions;
|
||||
}
|
||||
|
||||
/* Handle re-direction of output */
|
||||
|
||||
if (redirfile)
|
||||
{
|
||||
ret = posix_spawn_file_actions_addopen(&file_actions, 1, redirfile,
|
||||
oflags, 0644);
|
||||
if (ret != 0)
|
||||
{
|
||||
/* posix_spawn_file_actions_addopen returns a positive errno
|
||||
* value on failure.
|
||||
*/
|
||||
|
||||
nsh_output(vtbl, g_fmtcmdfailed, cmd,
|
||||
"posix_spawn_file_actions_addopen",
|
||||
NSH_ERRNO);
|
||||
goto errout_with_attrs;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the scheduler in an attempt to prevent the application from
|
||||
* running until waitpid() has been called.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Execute the program. posix_spawnp returns a positive errno value on
|
||||
* failure.
|
||||
*/
|
||||
|
||||
ret = posix_spawnp(&pid, cmd, &file_actions, &attr, &argv[1], NULL);
|
||||
if (ret == OK)
|
||||
{
|
||||
/* The application was successfully started with pre-emption disabled.
|
||||
* In the simplest cases, the application will not have run because the
|
||||
* the scheduler is locked. But in the case where I/O was redirected, a
|
||||
* proxy task ran and broke our lock. As result, the application may
|
||||
* have aso ran if its priority was higher than than the priority of
|
||||
* this thread.
|
||||
*
|
||||
* If the application did not run to completion and if the application
|
||||
* was not backgrounded, then we need to wait here for the application
|
||||
* to exit. This only works works with the following options:
|
||||
*
|
||||
* - CONFIG_NSH_DISABLEBG - Do not run commands in background
|
||||
* - CONFIG_SCHED_WAITPID - Required to run external commands in
|
||||
* foreground
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
|
||||
/* CONFIG_SCHED_WAITPID is selected, so we may run the command in
|
||||
* foreground unless we were specifically requested to run the command
|
||||
* in background (and running commands in background is enabled).
|
||||
*/
|
||||
|
||||
# ifndef CONFIG_NSH_DISABLEBG
|
||||
if (vtbl->np.np_bg == false)
|
||||
# endif /* CONFIG_NSH_DISABLEBG */
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* Wait for the application to exit. We did lock the scheduler
|
||||
* above, but that does not guarantee that the application did not
|
||||
* already run to completion in the case where I/O was redirected.
|
||||
* Here the scheduler will be unlocked while waitpid is waiting
|
||||
* and if the application has not yet run, it will now be able to
|
||||
* do so.
|
||||
*/
|
||||
|
||||
ret = waitpid(pid, &rc, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* If the child thread does not exist, waitpid() will return
|
||||
* the error ECHLD. Since we know that the task was successfully
|
||||
* started, this must be one of the cases described above; we
|
||||
* have to assume that the task already exit'ed. In this case,
|
||||
* we have no idea if the application ran successfully or not
|
||||
* (because NuttX does not retain exit status of child tasks).
|
||||
* Let's assume that is did run successfully.
|
||||
*/
|
||||
|
||||
int errcode = errno;
|
||||
if (errcode == ECHILD)
|
||||
{
|
||||
ret = OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsh_output(vtbl, g_fmtcmdfailed, cmd, "waitpid",
|
||||
NSH_ERRNO_OF(errcode));
|
||||
}
|
||||
}
|
||||
|
||||
/* Waitpid completed the wait successfully */
|
||||
|
||||
else
|
||||
{
|
||||
/* We can't return the exact status (nsh has nowhere to put it)
|
||||
* so just pass back zero/nonzero in a fashion that doesn't look
|
||||
* like an error.
|
||||
*/
|
||||
|
||||
ret = (rc == 0) ? OK : 1;
|
||||
|
||||
/* TODO: Set the environment variable '?' to a string corresponding
|
||||
* to WEXITSTATUS(rc) so that $? will expand to the exit status of
|
||||
* the most recently executed task.
|
||||
*/
|
||||
}
|
||||
}
|
||||
# ifndef CONFIG_NSH_DISABLEBG
|
||||
else
|
||||
# endif /* CONFIG_NSH_DISABLEBG */
|
||||
#endif /* CONFIG_SCHED_WAITPID */
|
||||
|
||||
/* We get here if either:
|
||||
*
|
||||
* - CONFIG_SCHED_WAITPID is not selected meaning that all commands
|
||||
* have to be run in background, or
|
||||
* - CONFIG_SCHED_WAITPID and CONFIG_NSH_DISABLEBG are both selected, but the
|
||||
* user requested to run the command in background.
|
||||
*
|
||||
* NOTE that the case of a) CONFIG_SCHED_WAITPID is not selected and
|
||||
* b) CONFIG_NSH_DISABLEBG selected cannot be supported. In that event, all
|
||||
* commands will have to run in background. The waitpid() API must be
|
||||
* available to support running the command in foreground.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_SCHED_WAITPID) || !defined(CONFIG_NSH_DISABLEBG)
|
||||
{
|
||||
struct sched_param param;
|
||||
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
|
||||
* them.
|
||||
*/
|
||||
|
||||
ret = OK;
|
||||
}
|
||||
#endif /* !CONFIG_SCHED_WAITPID || !CONFIG_NSH_DISABLEBG */
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
|
||||
/* Free attibutes and file actions. Ignoring return values in the case
|
||||
* of an error.
|
||||
*/
|
||||
|
||||
errout_with_actions:
|
||||
(void)posix_spawn_file_actions_destroy(&file_actions);
|
||||
|
||||
errout_with_attrs:
|
||||
(void)posix_spawnattr_destroy(&attr);
|
||||
|
||||
errout:
|
||||
/* Most posix_spawn interfaces return a positive errno value on failure
|
||||
* and do not set the errno variable.
|
||||
*/
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
/* Set the errno value and return -1 */
|
||||
|
||||
set_errno(ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
else if (ret < 0)
|
||||
{
|
||||
/* Return -1 on failure. errno should have been set. */
|
||||
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NSH_FILE_APPS */
|
||||
@@ -53,12 +53,13 @@
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <netinet/ether.h>
|
||||
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <nuttx/net/uip/uip.h>
|
||||
#include <nuttx/net/uip/uip-arch.h>
|
||||
#include <netinet/ether.h>
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
# include <nuttx/net/uip/uip.h>
|
||||
|
||||
+36
-1
@@ -61,6 +61,7 @@
|
||||
#ifdef CONFIG_NSH_BUILTIN_APPS
|
||||
# include <nuttx/binfmt/builtin.h>
|
||||
#endif
|
||||
|
||||
#include <apps/nsh.h>
|
||||
|
||||
#include "nsh.h"
|
||||
@@ -1398,6 +1399,40 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
|
||||
nsh_output(vtbl, g_fmttoomanyargs, cmd);
|
||||
}
|
||||
|
||||
/* Does this command correspond to an application filename?
|
||||
* nsh_fileapp() 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_FILE_APPS
|
||||
ret = nsh_fileapp(vtbl, argv[0], argv, redirfile, oflags);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* nsh_fileapp() 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
|
||||
|
||||
/* Does this command correspond to a builtin command?
|
||||
* nsh_builtin() returns:
|
||||
*
|
||||
@@ -1414,7 +1449,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
|
||||
* Note the priority if not effected by nice-ness.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NSH_BUILTIN_APPS
|
||||
#if defined(CONFIG_NSH_BUILTIN_APPS) && (!defined(CONFIG_NSH_FILE_APPS) || !defined(CONFIG_FS_BINFS))
|
||||
ret = nsh_builtin(vtbl, argv[0], argv, redirfile, oflags);
|
||||
if (ret >= 0)
|
||||
{
|
||||
|
||||
@@ -3967,4 +3967,55 @@
|
||||
file system.
|
||||
* configs/sim/nsh: Convert to use kconfig-frontends configuration
|
||||
tool.
|
||||
* binfmt/binfmt_schedunload.c: Add logic based on SIGCHLD to
|
||||
automatically unload and clean-up after running a task that
|
||||
was loaded into memory.
|
||||
* binfmt/libbuiltin: Extensions from Mike Smith
|
||||
* sched/task_reparent.c: Add internal interface to change the
|
||||
parent task.
|
||||
* sched/task_posixspawn(): Move libc/spawn/lib_ps.c to
|
||||
sched/task_posixspawn() now it requires internal, reparenting
|
||||
interfaces
|
||||
* include/nuttx/spawn(): Move libc/spawn.h to include/nuttx/spawn.h
|
||||
* arch/arm/include/lpc17xx/chip.h, irq178x.h: Integrate Marcelo
|
||||
Rommel's LPC1788 definitions into the base LPC17xx.
|
||||
* configs/olimex-lpc1766stk/nsh: Convert configuration to use
|
||||
the kconfig-frontends tools.
|
||||
* sched/task_reparent.c: Simplify reparenting interface.
|
||||
* arch/arm/src/[many]: More LPC1788 definitions from Rommel
|
||||
Marcelo incorporated.
|
||||
* configs/open1788: Board configuration for the Wave Share
|
||||
Open1788 board. Still fragmentary (contribnuted by Rommel
|
||||
Marcelo, adapted to use kconfig-frontends.
|
||||
* net/send(): Add logic to work around delayed ACKs by splitting
|
||||
packets (contributed by Yan T.).
|
||||
* net/recvfrom(): Fix a bug. When the host closes a connection
|
||||
(gracefully). recv[from]() returned success and the closure
|
||||
was never detected. Hmmm.. I don't know why the network monitor
|
||||
did not catch this event. This is an important bug fix.
|
||||
* net/recvfrom(): Fix a introduced with the last bugfix. If
|
||||
the peer does an orderly closure of the socket, report 0 not
|
||||
-ENOTCONN
|
||||
* configs/lm3s6965-ek/README.txt and tools/: Add an OpenOCD
|
||||
configuration for the LM3S (from Jose Pablo Carballo).
|
||||
* nuttx/lcd/hd4478ou.h and configs/pcblogic-pic32mx/src/up_lcd1602:
|
||||
Start of support of LCD1602 alphanumeric LCD. I need a few
|
||||
more parts before I can finish integrating this one.
|
||||
* arch/arm/src/*/chip.h and arch/arm/include/*/chip.h: Move all
|
||||
priority ranges from the src to the include chip.h header file.
|
||||
* arch/arm/include/armv7-m/irq.h: Add inline functions to enable
|
||||
and disable interrupts via the BASEPRI register.
|
||||
* arch/arm/Kconfig: Add new option CONFIG_ARM7VM_USEBASEI
|
||||
* arch/arm/src/*/*_irq.c: Set the priority of the SVCALL exception
|
||||
to the highest possible value.
|
||||
* arch/armv7-m/up_hardfault.c: Fail if a hardfault occurs
|
||||
while CONFIG_ARM7VM_USEBASEPRI=y.
|
||||
* arch/arm/src/stm32/stm32_serial.c: Add support for USART
|
||||
single wire more (Contributed by the PX4 team).
|
||||
* sched/: Implement support for retaining child task status after
|
||||
the child task exists. This is behavior required by POSIX.
|
||||
But in NuttX is only enabled with CONFIG_SCHED_HAVE_PARENT and
|
||||
CONFIG_SCHED_CHILD_STATUS
|
||||
* Add support for keyboard encode to the keypad test (from
|
||||
Denis Carikli).
|
||||
|
||||
|
||||
+98
-69
@@ -1,4 +1,4 @@
|
||||
NuttX TODO List (Last updated January 14, 2013)
|
||||
NuttX TODO List (Last updated January 23, 2013)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
||||
@@ -6,7 +6,7 @@ standards, things that could be improved, and ideas for enhancements.
|
||||
|
||||
nuttx/
|
||||
|
||||
(10) Task/Scheduler (sched/)
|
||||
(11) Task/Scheduler (sched/)
|
||||
(1) Memory Managment (mm/)
|
||||
(3) Signals (sched/, arch/)
|
||||
(2) pthreads (sched/)
|
||||
@@ -21,7 +21,7 @@ nuttx/
|
||||
(1) Documentation (Documentation/)
|
||||
(7) Build system / Toolchains
|
||||
(5) Linux/Cywgin simulation (arch/sim)
|
||||
(6) ARM (arch/arm/)
|
||||
(5) ARM (arch/arm/)
|
||||
(1) ARM/C5471 (arch/arm/src/c5471/)
|
||||
(3) ARM/DM320 (arch/arm/src/dm320/)
|
||||
(2) ARM/i.MX (arch/arm/src/imx/)
|
||||
@@ -38,14 +38,14 @@ nuttx/
|
||||
(3) MIPS/PIC32 (arch/mips)
|
||||
(1) Hitachi/Renesas SH-1 (arch/sh/src/sh1)
|
||||
(4) Renesas M16C/26 (arch/sh/src/m16c)
|
||||
(10) z80/z8/ez80 (arch/z80/)
|
||||
(11) z80/z8/ez80/z180 (arch/z80/)
|
||||
(9) z16 (arch/z16/)
|
||||
(1) mc68hc1x (arch/hc)
|
||||
|
||||
apps/
|
||||
|
||||
(5) Network Utilities (apps/netutils/)
|
||||
(4) NuttShell (NSH) (apps/nshlib)
|
||||
(5) NuttShell (NSH) (apps/nshlib)
|
||||
(1) System libraries apps/system (apps/system)
|
||||
(5) Other Applications & Tests (apps/examples/)
|
||||
|
||||
@@ -161,39 +161,8 @@ o Task/Scheduler (sched/)
|
||||
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
|
||||
Description: 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).
|
||||
@@ -206,11 +175,43 @@ o Task/Scheduler (sched/)
|
||||
- File descriptors (struct filelist)
|
||||
- FILE streams (struct streamlist)
|
||||
- Sockets (struct socketlist)
|
||||
Status: Open
|
||||
Priority: Low. This is an enhancement. It would slight reduce
|
||||
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.
|
||||
|
||||
Title: ISSUES WITH atexit() AND on_exit()
|
||||
Description: These functions execute with the following bad properties:
|
||||
|
||||
1. They run with interrupts disabled,
|
||||
2. They run in supervisor mode (if applicable), and
|
||||
3. They do not obey any setup of PIC or address
|
||||
environments. Do they need to?
|
||||
|
||||
The fix for all of these issues it to have the callbacks
|
||||
run on the caller's thread (as with signal handlers).
|
||||
Status: Open
|
||||
Priority: Medium Low. This is an important change to some less
|
||||
important interfaces. For the average user, these
|
||||
functions are just fine the way they are.
|
||||
|
||||
Title: execv() AND vfork()
|
||||
Description: There is a problem when vfork() calls execv() (or execl()) to
|
||||
start a new appliction: When the parent thread calls vfork()
|
||||
it receives and gets the pid of the vforked task, and *not*
|
||||
the pid of the desired execv'ed application.
|
||||
|
||||
The same tasking arrangement is used by the standard function
|
||||
posix_spawn(). However, posix_spawn uses the non-standard, internal
|
||||
NuttX interface task_reparent() to replace the childs parent task
|
||||
with the caller of posix_spawn(). That cannot be done with vfork()
|
||||
because we don't know what vfor() is going to do.
|
||||
|
||||
Any solution to this is either very difficult or impossible with
|
||||
an MMU.
|
||||
Status: Open
|
||||
Priority: Low (it might as well be low since it isn't going to be fixed).
|
||||
|
||||
o Memory Managment (mm/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -516,7 +517,7 @@ o Network (net/, drivers/net)
|
||||
Status: Open. No changes are planned.
|
||||
Priority: Low
|
||||
|
||||
Tile: MULTIPLE NETWORK INTERFACE SUPPORT
|
||||
Title: MULTIPLE NETWORK INTERFACE SUPPORT
|
||||
Description: uIP polling issues / Multiple network interface support:
|
||||
|
||||
(1) Current logic will not support multiple ethernet drivers.
|
||||
@@ -666,6 +667,21 @@ o Network (net/, drivers/net)
|
||||
Status: Open
|
||||
Priority: Low... fix defconfig files as necessary.
|
||||
|
||||
Title: net_poll() DOES NOT HANDLE LOSS-OF-CONNECTION CORRECTLY
|
||||
Description: When a loss of connection is detected by any logic waiting on the
|
||||
networking events, the function net_lostconnection() must be called.
|
||||
That function just sets some bits in the socket structure so that
|
||||
it remembers that the connection is lost.
|
||||
|
||||
That is currently done in recvfrom(), send(), and net_monitor.c. But
|
||||
it is not done in the net_poll() logic; that logic correctly sets
|
||||
the POLLHUP status, but it does not call net_lostconnection(). As a
|
||||
result, if recv() is called after the poll() or select(), the system
|
||||
will hang because the recv() does not know that the connection has
|
||||
been lost.
|
||||
Status: Open
|
||||
Priority: High
|
||||
|
||||
o USB (drivers/usbdev, drivers/usbhost)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -1059,13 +1075,13 @@ o Build system
|
||||
Priority: Low -- the kernel build configuration is not fully fielded
|
||||
yet.
|
||||
|
||||
Title: mconf NOT AVAILABLE IN NATIVE WINDOWS BUILD
|
||||
Description: NuttX is migrating to the use of the kconfig-frontends mconf
|
||||
Title: kconfig-mconf NOT AVAILABLE IN NATIVE WINDOWS BUILD
|
||||
Description: NuttX is migrating to the use of the kconfig-frontends kconfig-mconf
|
||||
tool for all configurations. In NuttX 6.24, support for native
|
||||
Windows builds was added. However, the mconf tool does not
|
||||
Windows builds was added. However, thekconfig- mconf tool does not
|
||||
build to run natively under Windows.
|
||||
|
||||
Some effort was spent trying to get a clean mconf build under
|
||||
Some effort was spent trying to get a clean kconfig-mconf build under
|
||||
Windows. This is documented in the message thread beginning
|
||||
here: http://tech.groups.yahoo.com/group/nuttx/message/2900.
|
||||
The build was successfully completed using: MinGW-GCC, MSYS,
|
||||
@@ -1077,8 +1093,8 @@ o Build system
|
||||
was considered a show stopper and the changs were not checked
|
||||
in.
|
||||
|
||||
Options: (1) Use conf (not mconf). confis the text-only
|
||||
configuration tool, (2) fix mconf, (3) write another variant
|
||||
Options: (1) Use kconfigs-conf (not kconfig-mconf). confis the text-only
|
||||
configuration tool, (2) fix kconfig-mconf, (3) write another variant
|
||||
of the configuration tool for windows, or (4) do all configuration
|
||||
under Cygwin or MSYS. I am doing (4) now, but this is very
|
||||
awkward because I have to set the apps path to ../apps (vs
|
||||
@@ -1161,27 +1177,6 @@ o ARM (arch/arm/)
|
||||
Status: Open
|
||||
Priority: Low
|
||||
|
||||
Title: SVCALLS AND HARDFAULTS
|
||||
Description: The Cortex-M3 user context switch logic uses SVCall instructions.
|
||||
This user context switching time could be improved by eliminating
|
||||
the SVCalls and developing assembly language implementations
|
||||
of the context save and restore logic.
|
||||
Also, because interrupts are always disabled when the SVCall is
|
||||
executed, the SVC goes to the hard fault handler where it must
|
||||
be handled as a special case. I recall seeing some controls
|
||||
somewhere that will allow to suppress one hard fault. I don't
|
||||
recall the control, but something like this should be used before
|
||||
executing the SVCall so that it vectors directly to the SVC
|
||||
handler.
|
||||
Another, more standard option would be to use interrupt priority
|
||||
levels to control interrupts. In that case, (1) The SVC would
|
||||
be the highest priority interrupt (0), (2) irqsave() would set
|
||||
the interrupt mask level to just above that, and (2) irqrestore
|
||||
would restore the interrupt level. This would not be diffult,
|
||||
but does affect a lot of files!
|
||||
Status: Open
|
||||
Priority: Low
|
||||
|
||||
Title: ARM INTERRUPTS AND USER MODE
|
||||
Description: The ARM interrupt handling (arch/arm/src/arm/up_vectors.S) returns
|
||||
using 'ldmia sp, {r0-r15}^' My understanding is that this works
|
||||
@@ -1769,8 +1764,8 @@ o Renesas M16C/26 (arch/sh/src/m16c)
|
||||
Status: Open
|
||||
Priority: Medium
|
||||
|
||||
o z80/z8/ez80 (arch/z80)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
o z80/z8/ez80/z180 (arch/z80)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Title: SDCC INTEGER OVERFLOWS
|
||||
Description: The SDCC version the same problems with integer overflow during
|
||||
@@ -1860,6 +1855,14 @@ o z80/z8/ez80 (arch/z80)
|
||||
Status: Open
|
||||
Priority: Med
|
||||
|
||||
Title: UNFINISHED Z180 LOGIC NEEDED BY THE P112 BOARD
|
||||
Description: 1) Need to revist the start-up logic. Looking at the P112 Bios
|
||||
(Bios.mcd), I see that quite of bit of register setup is done
|
||||
there.
|
||||
2) Finish ESCC driver logic.
|
||||
Status: Open
|
||||
Priority: Low (at least until I get P112 hardware)
|
||||
|
||||
o z16 (arch/z16)
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -2051,6 +2054,32 @@ o NuttShell (NSH) (apps/nshlib)
|
||||
Status: Open
|
||||
Priority: Low (enhancement)
|
||||
|
||||
Title: RE-DIRECTION OF BUILTIN APPLICATONS
|
||||
Description: There is a problem with the re-direction of output form built-in
|
||||
applications in NSH. When output is re-directed, exec_builtin()
|
||||
spawns a tiny trampoline task that re-directs the output as
|
||||
requested, starts the built-in task and then exit.
|
||||
|
||||
The problem is that when exec_builtin() starts the trampoline task,
|
||||
it receives and returns the pid of the trampoline task, and *not*
|
||||
the pid of the desired builtin application. This bad pid is returned
|
||||
to NSH and when NSH tries to use that pid in the waitpid() call, it
|
||||
fails because the trampoline task no longer exists.
|
||||
|
||||
The same tasking arrangement is used by the standard function
|
||||
posix_spawn(). However, posix_spawn uses the non-standard, internal
|
||||
NuttX interface task_reparent() to replace the childs parent task
|
||||
with the caller of posix_spawn().
|
||||
|
||||
exec_builtin() should not use this internal interface, however,
|
||||
since it resides in the application space. The suggested solution
|
||||
is (1) move the exec_builtin() logic into nuttx/sched, (2) make it
|
||||
a semi-standard interface renamed to task_spawn() and prototyped
|
||||
in nuttx/include/sched.h, and then (2) use task_reparent to solve
|
||||
the parental problem in the same way that posix_spawn does.
|
||||
Status: Open
|
||||
Priority: Medium
|
||||
|
||||
o System libraries apps/system (apps/system)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -103,6 +103,131 @@ source arch/x86/Kconfig
|
||||
source arch/z16/Kconfig
|
||||
source arch/z80/Kconfig
|
||||
|
||||
comment "External Memory Configuration"
|
||||
|
||||
config ARCH_HAVE_EXTNAND
|
||||
bool
|
||||
|
||||
config ARCH_HAVE_EXTNOR
|
||||
bool
|
||||
|
||||
config ARCH_HAVE_EXTDRAM
|
||||
bool
|
||||
|
||||
config ARCH_HAVE_EXTSRAM0
|
||||
bool
|
||||
|
||||
config ARCH_HAVE_EXTSRAM1
|
||||
bool
|
||||
|
||||
config ARCH_EXTNAND
|
||||
bool "Configure external NAND"
|
||||
default n
|
||||
depends on ARCH_HAVE_EXTNAND
|
||||
---help---
|
||||
Configure external NAND memory and, if applicable, map then external
|
||||
NAND into the memory map.
|
||||
|
||||
if ARCH_EXTNAND
|
||||
|
||||
config ARCH_EXTNANDSIZE
|
||||
int "External NAND size"
|
||||
default 0
|
||||
---help---
|
||||
Size of the external NAND in bytes.
|
||||
|
||||
endif
|
||||
|
||||
config ARCH_EXTNOR
|
||||
bool "Configure external NOR memory"
|
||||
default n
|
||||
depends on ARCH_HAVE_EXTNOR
|
||||
---help---
|
||||
Configure external NOR memory and, if applicable, map then external
|
||||
NOR into the memory map.
|
||||
|
||||
if ARCH_EXTNOR
|
||||
|
||||
config ARCH_EXTNORSIZE
|
||||
int "External NOR size"
|
||||
default 0
|
||||
---help---
|
||||
Size of the external NOR in bytes.
|
||||
|
||||
endif
|
||||
|
||||
config ARCH_EXTDRAM
|
||||
bool "Configure external DRAM"
|
||||
default n
|
||||
depends on ARCH_HAVE_EXTDRAM
|
||||
---help---
|
||||
Configure external DRAM memory and, if applicable, map then external
|
||||
DRAM into the memory map.
|
||||
|
||||
if ARCH_EXTDRAM
|
||||
|
||||
config ARCH_EXTDRAMSIZE
|
||||
int "External SDRAM size"
|
||||
default 0
|
||||
---help---
|
||||
Size of the external SDRAM in bytes.
|
||||
|
||||
config ARCH_EXTDRAMHEAP
|
||||
bool "Add external SDRAM to the heap"
|
||||
default y
|
||||
---help---
|
||||
Add the external SDRAM into the heap.
|
||||
|
||||
endif
|
||||
|
||||
config ARCH_EXTSRAM0
|
||||
bool "Configure external SRAM (Bank 0)"
|
||||
default n
|
||||
depends on ARCH_HAVE_EXTSRAM0
|
||||
---help---
|
||||
Configure external SRAM Bank 0 memory and, if applicable, map then
|
||||
external SRAM Bank 0 into the memory map.
|
||||
|
||||
if ARCH_EXTSRAM0
|
||||
|
||||
config ARCH_EXTSRAM0SIZE
|
||||
int "External SRAM size"
|
||||
default 0
|
||||
---help---
|
||||
Size of the external SRAM Bank 0 in bytes.
|
||||
|
||||
config ARCH_EXTSRAM0HEAP
|
||||
bool "Add external SRAM (Bank 0) to the heap"
|
||||
default y
|
||||
---help---
|
||||
Add external SRAM Bank 0 into the heap.
|
||||
|
||||
endif
|
||||
|
||||
config ARCH_EXTSRAM1
|
||||
bool "Configure external SRAM (Bank 1)"
|
||||
default n
|
||||
depends on ARCH_HAVE_EXTSRAM1
|
||||
---help---
|
||||
Configure external SRAM Bank 1 memory and, if applicable, map then
|
||||
external SRAM Bank 1 into the memory map.
|
||||
|
||||
if ARCH_EXTSRAM1
|
||||
|
||||
config ARCH_EXTSRAM1SIZE
|
||||
int "External SRAM1 size"
|
||||
default 0
|
||||
---help---
|
||||
Size of the external SRAM Bank 1 in bytes.
|
||||
|
||||
config ARCH_EXTSRAM1HEAP
|
||||
bool "Add external SRAM (Bank 1) to the heap"
|
||||
default y
|
||||
---help---
|
||||
Add external SRAM Bank 1 into the heap.
|
||||
|
||||
endif
|
||||
|
||||
comment "Architecture Options"
|
||||
|
||||
config ARCH_NOINTC
|
||||
|
||||
+13
-6
@@ -46,7 +46,6 @@ config ARCH_CHIP_KINETIS
|
||||
bool "Freescale Kinetis"
|
||||
select ARCH_CORTEXM4
|
||||
select ARCH_HAVE_MPU
|
||||
select ARCH_IRQPRIO
|
||||
select ARCH_HAVE_RAMFUNCS
|
||||
select ARCH_RAMFUNCS
|
||||
---help---
|
||||
@@ -55,7 +54,6 @@ config ARCH_CHIP_KINETIS
|
||||
config ARCH_CHIP_LM
|
||||
bool "TI Stellaris"
|
||||
select ARCH_HAVE_MPU
|
||||
select ARCH_IRQPRIO
|
||||
---help---
|
||||
TI Stellaris LMS3 architecutres (ARM Cortex-M3)
|
||||
|
||||
@@ -63,7 +61,6 @@ config ARCH_CHIP_LPC17XX
|
||||
bool "NXP LPC17xx"
|
||||
select ARCH_CORTEXM3
|
||||
select ARCH_HAVE_MPU
|
||||
select ARCH_IRQPRIO
|
||||
---help---
|
||||
NXP LPC17xx architectures (ARM Cortex-M3)
|
||||
|
||||
@@ -95,7 +92,6 @@ config ARCH_CHIP_LPC43XX
|
||||
select ARCH_HAVE_CMNVECTOR
|
||||
select ARMV7M_CMNVECTOR
|
||||
select ARCH_HAVE_MPU
|
||||
select ARCH_IRQPRIO
|
||||
---help---
|
||||
NPX LPC43XX architectures (ARM Cortex-M4).
|
||||
|
||||
@@ -103,7 +99,6 @@ config ARCH_CHIP_SAM3U
|
||||
bool "Atmel AT91SAM3U"
|
||||
select ARCH_CORTEXM3
|
||||
select ARCH_HAVE_MPU
|
||||
select ARCH_IRQPRIO
|
||||
---help---
|
||||
Atmel AT91SAM3U architectures (ARM Cortex-M3)
|
||||
|
||||
@@ -112,7 +107,6 @@ config ARCH_CHIP_STM32
|
||||
select ARCH_HAVE_CMNVECTOR
|
||||
select ARCH_HAVE_MPU
|
||||
select ARCH_HAVE_I2CRESET
|
||||
select ARCH_IRQPRIO
|
||||
---help---
|
||||
STMicro STM32 architectures (ARM Cortex-M3/4).
|
||||
|
||||
@@ -136,9 +130,11 @@ config ARCH_ARM920T
|
||||
|
||||
config ARCH_CORTEXM3
|
||||
bool
|
||||
select ARCH_IRQPRIO
|
||||
|
||||
config ARCH_CORTEXM4
|
||||
bool
|
||||
select ARCH_IRQPRIO
|
||||
|
||||
config ARCH_FAMILY
|
||||
string
|
||||
@@ -162,6 +158,17 @@ config ARCH_CHIP
|
||||
default "stm32" if ARCH_CHIP_STM32
|
||||
default "str71x" if ARCH_CHIP_STR71X
|
||||
|
||||
config ARMV7M_USEBASEPRI
|
||||
bool "Use BASEPRI Register"
|
||||
default n
|
||||
depends on ARCH_CORTEXM3 || ARCH_CORTEXM4
|
||||
---help---
|
||||
Use the BASEPRI register to enable and disable able interrupts. By
|
||||
default, the PRIMASK register is used for this purpose. This
|
||||
usually results in hardfaults that are properly handling by the
|
||||
RTOS. Using the BASEPRI register will avoid these hardfault.
|
||||
That is needed primarily for integration with some toolchains.
|
||||
|
||||
config ARCH_HAVE_CMNVECTOR
|
||||
bool
|
||||
|
||||
|
||||
@@ -60,6 +60,10 @@
|
||||
# include <arch/armv7-m/irq_lazyfpu.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
# include <arch/chip/chip.h>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
@@ -114,7 +118,11 @@ struct xcptcontext
|
||||
*/
|
||||
|
||||
uint32_t saved_pc;
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
uint32_t saved_basepri;
|
||||
#else
|
||||
uint32_t saved_primask;
|
||||
#endif
|
||||
uint32_t saved_xpsr;
|
||||
#endif
|
||||
|
||||
@@ -130,65 +138,7 @@ struct xcptcontext
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* Disable IRQs */
|
||||
|
||||
static inline void irqdisable(void) inline_function;
|
||||
static inline void irqdisable(void)
|
||||
{
|
||||
__asm__ __volatile__ ("\tcpsid i\n");
|
||||
}
|
||||
|
||||
/* Save the current primask state & disable IRQs */
|
||||
|
||||
static inline irqstate_t irqsave(void) inline_function;
|
||||
static inline irqstate_t irqsave(void)
|
||||
{
|
||||
unsigned short primask;
|
||||
|
||||
/* Return the current value of primask register and set
|
||||
* bit 0 of the primask register to disable interrupts
|
||||
*/
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmrs %0, primask\n"
|
||||
"\tcpsid i\n"
|
||||
: "=r" (primask)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
return primask;
|
||||
}
|
||||
|
||||
/* Enable IRQs */
|
||||
|
||||
static inline void irqenable(void) inline_function;
|
||||
static inline void irqenable(void)
|
||||
{
|
||||
__asm__ __volatile__ ("\tcpsie i\n");
|
||||
}
|
||||
|
||||
/* Restore saved primask state */
|
||||
|
||||
static inline void irqrestore(irqstate_t primask) inline_function;
|
||||
static inline void irqrestore(irqstate_t primask)
|
||||
{
|
||||
/* If bit 0 of the primask is 0, then we need to restore
|
||||
* interupts.
|
||||
*/
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\ttst %0, #1\n"
|
||||
"\tbne 1f\n"
|
||||
"\tcpsie i\n"
|
||||
"1:\n"
|
||||
:
|
||||
: "r" (primask)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/* Get/set the primask register */
|
||||
/* Get/set the PRIMASK register */
|
||||
|
||||
static inline uint8_t getprimask(void) inline_function;
|
||||
static inline uint8_t getprimask(void)
|
||||
@@ -215,7 +165,11 @@ static inline void setprimask(uint32_t primask)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/* Get/set the basepri register */
|
||||
/* Get/set the BASEPRI register. The BASEPRI register defines the minimum
|
||||
* priority for exception processing. When BASEPRI is set to a nonzero
|
||||
* value, it prevents the activation of all exceptions with the same or
|
||||
* lower priority level as the BASEPRI value.
|
||||
*/
|
||||
|
||||
static inline uint8_t getbasepri(void) inline_function;
|
||||
static inline uint8_t getbasepri(void)
|
||||
@@ -243,6 +197,82 @@ static inline void setbasepri(uint32_t basepri)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/* Disable IRQs */
|
||||
|
||||
static inline void irqdisable(void) inline_function;
|
||||
static inline void irqdisable(void)
|
||||
{
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
setbasepri(NVIC_SYSH_DISABLE_PRIORITY);
|
||||
#else
|
||||
__asm__ __volatile__ ("\tcpsid i\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Save the current primask state & disable IRQs */
|
||||
|
||||
static inline irqstate_t irqsave(void) inline_function;
|
||||
static inline irqstate_t irqsave(void)
|
||||
{
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
|
||||
uint8_t basepri = getbasepri();
|
||||
setbasepri(NVIC_SYSH_DISABLE_PRIORITY);
|
||||
return (irqstate_t)basepri;
|
||||
|
||||
#else
|
||||
|
||||
unsigned short primask;
|
||||
|
||||
/* Return the current value of primask register and set
|
||||
* bit 0 of the primask register to disable interrupts
|
||||
*/
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmrs %0, primask\n"
|
||||
"\tcpsid i\n"
|
||||
: "=r" (primask)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
return primask;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Enable IRQs */
|
||||
|
||||
static inline void irqenable(void) inline_function;
|
||||
static inline void irqenable(void)
|
||||
{
|
||||
setbasepri(0);
|
||||
__asm__ __volatile__ ("\tcpsie i\n");
|
||||
}
|
||||
|
||||
/* Restore saved primask state */
|
||||
|
||||
static inline void irqrestore(irqstate_t flags) inline_function;
|
||||
static inline void irqrestore(irqstate_t flags)
|
||||
{
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
setbasepri((uint32_t)flags);
|
||||
#else
|
||||
/* If bit 0 of the primask is 0, then we need to restore
|
||||
* interupts.
|
||||
*/
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\ttst %0, #1\n"
|
||||
"\tbne 1f\n"
|
||||
"\tcpsie i\n"
|
||||
"1:\n"
|
||||
:
|
||||
: "r" (flags)
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get/set IPSR */
|
||||
|
||||
static inline uint32_t getipsr(void) inline_function;
|
||||
|
||||
@@ -51,7 +51,11 @@
|
||||
*/
|
||||
|
||||
#define REG_R13 (0) /* R13 = SP at time of interrupt */
|
||||
#define REG_PRIMASK (1) /* PRIMASK */
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
# define REG_BASEPRI (1) /* BASEPRI */
|
||||
#else
|
||||
# define REG_PRIMASK (1) /* PRIMASK */
|
||||
#endif
|
||||
#define REG_R4 (2) /* R4 */
|
||||
#define REG_R5 (3) /* R5 */
|
||||
#define REG_R6 (4) /* R6 */
|
||||
|
||||
@@ -51,7 +51,11 @@
|
||||
*/
|
||||
|
||||
#define REG_R13 (0) /* R13 = SP at time of interrupt */
|
||||
#define REG_PRIMASK (1) /* PRIMASK */
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
# define REG_BASEPRI (1) /* BASEPRI */
|
||||
#else
|
||||
# define REG_PRIMASK (1) /* PRIMASK */
|
||||
#endif
|
||||
#define REG_R4 (2) /* R4 */
|
||||
#define REG_R5 (3) /* R5 */
|
||||
#define REG_R6 (4) /* R6 */
|
||||
|
||||
@@ -183,9 +183,43 @@
|
||||
# define STM32_NRNG 0 /* No random number generator (RNG) */
|
||||
# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */
|
||||
|
||||
/* STM32 F103 Medium Density Family *************************************************/
|
||||
/* STM32F103RB is in the Medium-density performance line and is provided in 64 pin
|
||||
* packages with 128K Flash, USB, CAN, 7 timers, 2 ADCs, 9 com. interfaces
|
||||
*/
|
||||
|
||||
#elif defined(CONFIG_ARCH_CHIP_STM32F103RBT6)
|
||||
# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */
|
||||
# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
|
||||
# define CONFIG_STM32_MEDIUMDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
|
||||
# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */
|
||||
# undef CONFIG_STM32_VALUELINE /* STM32F100x */
|
||||
# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */
|
||||
# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */
|
||||
# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */
|
||||
# define STM32_NFSMC 0 /* FSMC */
|
||||
# define STM32_NATIM 1 /* One advanced timer TIM1 */
|
||||
# define STM32_NGTIM 3 /* General timers TIM2,3,4 */
|
||||
# define STM32_NBTIM 0 /* Two basic timers TIM6 and TIM7 */
|
||||
# define STM32_NDMA 1 /* DMA1 */
|
||||
# define STM32_NSPI 2 /* SPI1-2 */
|
||||
# define STM32_NI2S 0 /* No I2S (?) */
|
||||
# define STM32_NUSART 3 /* USART1-3 */
|
||||
# define STM32_NI2C 2 /* I2C1-2 */
|
||||
# define STM32_NCAN 1 /* bxCAN1 */
|
||||
# define STM32_NSDIO 0 /* No SDIO */
|
||||
# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */
|
||||
# define STM32_NGPIO 51 /* GPIOA-E */
|
||||
# define STM32_NADC 2 /* ADC1-2 */
|
||||
# define STM32_NDAC 0 /* No DAC */
|
||||
# define STM32_NCRC 1 /* CRC */
|
||||
# define STM32_NTHERNET 0 /* No ethernet */
|
||||
# define STM32_NRNG 0 /* No random number generator (RNG) */
|
||||
# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */
|
||||
|
||||
/* STM32 F103 High Density Family ***************************************************/
|
||||
/* STM32F103RC, STM32F103RD, and STM32F103RE are all provided in 64 pin packages and differ
|
||||
* only in the available FLASH and SRAM.
|
||||
/* STM32F103RC, STM32F103RD, and STM32F103RE are all provided in 64 pin packages and
|
||||
* differ only in the available FLASH and SRAM.
|
||||
*/
|
||||
|
||||
#elif defined(CONFIG_ARCH_CHIP_STM32F103RET6)
|
||||
@@ -658,5 +692,15 @@
|
||||
# error "Unsupported STM32 chip"
|
||||
#endif
|
||||
|
||||
/* NVIC priority levels *************************************************************/
|
||||
|
||||
#define NVIC_SYSH_PRIORITY_MIN 0xf0 /* All bits set in minimum priority */
|
||||
#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */
|
||||
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
|
||||
#define NVIC_SYSH_PRIORITY_STEP 0x10 /* Four bits of interrupt priority used */
|
||||
|
||||
#define NVIC_SYSH_DISABLE_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
|
||||
#define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_STM32_CHIP_H */
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
@@ -87,7 +89,11 @@ typedef unsigned int _uintptr_t;
|
||||
*/
|
||||
|
||||
#ifdef __thumb2__
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
typedef unsigned char irqstate_t;
|
||||
#else
|
||||
typedef unsigned short irqstate_t;
|
||||
#endif
|
||||
#else /* __thumb2__ */
|
||||
typedef unsigned int irqstate_t;
|
||||
#endif /* __thumb2__ */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-m/up_assert.c
|
||||
*
|
||||
* Copyright (C) 2009-2010, 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009-2010, 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -147,8 +147,13 @@ static inline void up_registerdump(void)
|
||||
current_regs[REG_R10], current_regs[REG_R11],
|
||||
current_regs[REG_R12], current_regs[REG_R13],
|
||||
current_regs[REG_R14], current_regs[REG_R15]);
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
lldbg("xPSR: %08x BASEPRI: %08x\n",
|
||||
current_regs[REG_XPSR], current_regs[REG_BASEPRI]);
|
||||
#else
|
||||
lldbg("xPSR: %08x PRIMASK: %08x\n",
|
||||
current_regs[REG_XPSR], current_regs[REG_PRIMASK]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* arch/arm/src/stm32/up_exception.S
|
||||
* arch/arm/src/chip/up_exception.S
|
||||
*
|
||||
* Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009-2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012 Michael Smith. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
@@ -100,7 +100,11 @@ exception_common:
|
||||
mov r2, r1 /* R2=Copy of the main/process stack pointer */
|
||||
add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
|
||||
/* (ignoring the xPSR[9] alignment bit) */
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
mrs r3, basepri /* R3=Current BASEPRI setting */
|
||||
#else
|
||||
mrs r3, primask /* R3=Current PRIMASK setting */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
|
||||
@@ -205,7 +209,12 @@ exception_common:
|
||||
|
||||
/* Restore the interrupt state */
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
msr basepri, r3 /* Restore interrupts priority masking*/
|
||||
cpsie i /* Re-enable interrupts */
|
||||
#else
|
||||
msr primask, r3 /* Restore interrupts */
|
||||
#endif
|
||||
|
||||
/* Always return with R14 containing the special value that will: (1)
|
||||
* return to thread mode, and (2) select the correct stack.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-m/up_hardfault.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
|
||||
@@ -55,7 +55,9 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Debug output from this file may interfere with context switching! */
|
||||
/* If CONFIG_ARMV7M_USEBASEPRI=n, then debug output from this file may
|
||||
* interfere with context switching!
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DEBUG_HARDFAULT
|
||||
# define hfdbg(format, arg...) lldbg(format, ##arg)
|
||||
@@ -92,18 +94,19 @@
|
||||
|
||||
int up_hardfault(int irq, FAR void *context)
|
||||
{
|
||||
#if defined(CONFIG_DEBUG_HARDFAULT) || !defined(CONFIG_ARMV7M_USEBASEPRI)
|
||||
uint32_t *regs = (uint32_t*)context;
|
||||
uint16_t *pc;
|
||||
uint16_t insn;
|
||||
#endif
|
||||
|
||||
/* Get the value of the program counter where the fault occurred */
|
||||
|
||||
pc = (uint16_t*)regs[REG_PC] - 1;
|
||||
#ifndef CONFIG_ARMV7M_USEBASEPRI
|
||||
uint16_t *pc = (uint16_t*)regs[REG_PC] - 1;
|
||||
if ((void*)pc >= (void*)&_stext && (void*)pc < (void*)&_etext)
|
||||
{
|
||||
/* Fetch the instruction that caused the Hard fault */
|
||||
|
||||
insn = *pc;
|
||||
uint16_t insn = *pc;
|
||||
hfdbg(" PC: %p INSN: %04x\n", pc, insn);
|
||||
|
||||
/* If this was the instruction 'svc 0', then forward processing
|
||||
@@ -116,6 +119,7 @@ int up_hardfault(int irq, FAR void *context)
|
||||
return up_svcall(irq, context);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Dump some hard fault info */
|
||||
|
||||
@@ -133,7 +137,13 @@ int up_hardfault(int irq, FAR void *context)
|
||||
hfdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
|
||||
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
|
||||
hfdbg(" PSR=%08x\n", regs[REG_XPSR]);
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
hfdbg(" xPSR: %08x BASEPRI: %08x (saved)\n",
|
||||
current_regs[REG_XPSR], current_regs[REG_BASEPRI]);
|
||||
#else
|
||||
hfdbg(" xPSR: %08x PRIMASK: %08x (saved)\n",
|
||||
current_regs[REG_XPSR], current_regs[REG_PRIMASK]);
|
||||
#endif
|
||||
|
||||
(void)irqsave();
|
||||
lldbg("PANIC!!! Hard fault: %08x\n", getreg32(NVIC_HFAULTS));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-m/up_initialstate.c
|
||||
*
|
||||
* Copyright (C) 2009, 2011-2 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
|
||||
@@ -156,7 +156,7 @@ void up_initial_state(_TCB *tcb)
|
||||
xcp->regs[REG_FPSCR] = 0; // XXX initial FPSCR should be configurable
|
||||
xcp->regs[REG_FPReserved] = 0;
|
||||
|
||||
#endif
|
||||
#endif /* CONFIG_ARCH_FPU */
|
||||
|
||||
#ifdef CONFIG_NUTTX_KERNEL
|
||||
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
|
||||
@@ -165,7 +165,7 @@ void up_initial_state(_TCB *tcb)
|
||||
|
||||
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PROCESS_STACK;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_NUTTX_KERNEL */
|
||||
|
||||
#else /* CONFIG_ARMV7M_CMNVECTOR */
|
||||
|
||||
@@ -189,12 +189,16 @@ void up_initial_state(_TCB *tcb)
|
||||
|
||||
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_NUTTX_KERNEL */
|
||||
#endif /* CONFIG_ARMV7M_CMNVECTOR */
|
||||
|
||||
/* Enable or disable interrupts, based on user configuration */
|
||||
|
||||
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
xcp->regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
|
||||
#else
|
||||
xcp->regs[REG_PRIMASK] = 1;
|
||||
#endif
|
||||
#endif /* CONFIG_SUPPRESS_INTERRUPTS */
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-m/up_schedulesigaction.c
|
||||
*
|
||||
* Copyright (C) 2009-2012 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
|
||||
@@ -155,7 +155,11 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver)
|
||||
|
||||
tcb->xcp.sigdeliver = sigdeliver;
|
||||
tcb->xcp.saved_pc = current_regs[REG_PC];
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
tcb->xcp.saved_basepri = current_regs[REG_BASEPRI];
|
||||
#else
|
||||
tcb->xcp.saved_primask = current_regs[REG_PRIMASK];
|
||||
#endif
|
||||
tcb->xcp.saved_xpsr = current_regs[REG_XPSR];
|
||||
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
@@ -163,7 +167,11 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
current_regs[REG_PC] = (uint32_t)up_sigdeliver;
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
current_regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
|
||||
#else
|
||||
current_regs[REG_PRIMASK] = 1;
|
||||
#endif
|
||||
current_regs[REG_XPSR] = ARMV7M_XPSR_T;
|
||||
|
||||
/* And make sure that the saved context in the TCB
|
||||
@@ -189,7 +197,11 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver)
|
||||
|
||||
tcb->xcp.sigdeliver = sigdeliver;
|
||||
tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC];
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
tcb->xcp.saved_basepri = tcb->xcp.regs[REG_BASEPRI];
|
||||
#else
|
||||
tcb->xcp.saved_primask = tcb->xcp.regs[REG_PRIMASK];
|
||||
#endif
|
||||
tcb->xcp.saved_xpsr = tcb->xcp.regs[REG_XPSR];
|
||||
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
@@ -197,7 +209,11 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver;
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
tcb->xcp.regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY;
|
||||
#else
|
||||
tcb->xcp.regs[REG_PRIMASK] = 1;
|
||||
#endif
|
||||
tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-m/up_sigdeliver.c
|
||||
*
|
||||
* Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009-2010, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -102,7 +102,11 @@ void up_sigdeliver(void)
|
||||
|
||||
up_copystate(regs, rtcb->xcp.regs);
|
||||
regs[REG_PC] = rtcb->xcp.saved_pc;
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
regs[REG_BASEPRI] = rtcb->xcp.saved_basepri;
|
||||
#else
|
||||
regs[REG_PRIMASK] = rtcb->xcp.saved_primask;
|
||||
#endif
|
||||
regs[REG_XPSR] = rtcb->xcp.saved_xpsr;
|
||||
|
||||
/* Get a local copy of the sigdeliver function pointer. We do this so that
|
||||
@@ -115,7 +119,11 @@ void up_sigdeliver(void)
|
||||
|
||||
/* Then restore the task interrupt state */
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
irqrestore((uint8_t)regs[REG_BASEPRI]);
|
||||
#else
|
||||
irqrestore((uint16_t)regs[REG_PRIMASK]);
|
||||
#endif
|
||||
|
||||
/* Deliver the signals */
|
||||
|
||||
|
||||
@@ -457,32 +457,38 @@ config STM32_USART1
|
||||
bool "USART1"
|
||||
default n
|
||||
select ARCH_HAVE_USART1
|
||||
select STM32_USART
|
||||
|
||||
config STM32_USART2
|
||||
bool "USART2"
|
||||
default n
|
||||
select ARCH_HAVE_USART2
|
||||
select STM32_USART
|
||||
|
||||
config STM32_USART3
|
||||
bool "USART3"
|
||||
default n
|
||||
select ARCH_HAVE_USART3
|
||||
select STM32_USART
|
||||
|
||||
config STM32_UART4
|
||||
bool "UART4"
|
||||
default n
|
||||
select ARCH_HAVE_UART4
|
||||
select STM32_USART
|
||||
|
||||
config STM32_UART5
|
||||
bool "UART5"
|
||||
default n
|
||||
select ARCH_HAVE_UART5
|
||||
select STM32_USART
|
||||
|
||||
config STM32_USART6
|
||||
bool "USART6"
|
||||
default n
|
||||
depends on STM32_STM32F20XX || STM32_STM32F40XX
|
||||
select ARCH_HAVE_USART6
|
||||
select STM32_USART
|
||||
|
||||
config STM32_USB
|
||||
bool "USB Device"
|
||||
@@ -1804,8 +1810,11 @@ config STM32_TIM14_DAC2
|
||||
|
||||
endchoice
|
||||
|
||||
config STM32_USART
|
||||
bool
|
||||
|
||||
menu "U[S]ART Configuration"
|
||||
depends on STM32_USART1 || STM32_USART2 || STM32_USART3 || STM32_USART4 || STM32_USART5 || STM32_USART6
|
||||
depends on STM32_USART
|
||||
|
||||
config USART1_RS485
|
||||
bool "RS-485 on USART1"
|
||||
@@ -1968,6 +1977,14 @@ config SERIAL_TERMIOS
|
||||
|
||||
endmenu
|
||||
|
||||
config STM32_USART_SINGLEWIRE
|
||||
bool "Single Wire Support"
|
||||
default n
|
||||
depends on STM32_USART
|
||||
---help---
|
||||
Enable single wire UART support. The option enables support for the
|
||||
TIOCSSINGLEWIRE ioctl in the STM32 serial driver.
|
||||
|
||||
menu "SPI Configuration"
|
||||
depends on STM32_SPI
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/stm32/chip.h
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -68,12 +68,6 @@
|
||||
# undef CONFIG_DEBUG_QENCODER
|
||||
#endif
|
||||
|
||||
/* NVIC priority levels *************************************************************/
|
||||
|
||||
#define NVIC_SYSH_PRIORITY_MIN 0xff /* All bits set in minimum priority */
|
||||
#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */
|
||||
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
|
||||
|
||||
/* Peripherals **********************************************************************/
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* arch/arm/src/stm32/stm32_irq.c
|
||||
* arch/arm/src/chip/stm32_irq.c
|
||||
*
|
||||
* Copyright (C) 2009-2012 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
|
||||
@@ -194,6 +194,29 @@ static int stm32_reserved(int irq, FAR void *context)
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_prioritize_syscall
|
||||
*
|
||||
* Description:
|
||||
* Set the priority of an exception. This function may be needed
|
||||
* internally even if support for prioritized interrupts is not enabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
static inline void stm32_prioritize_syscall(int priority)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* SVCALL is system handler 11 */
|
||||
|
||||
regval = getreg32(NVIC_SYSH8_11_PRIORITY);
|
||||
regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK;
|
||||
regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT);
|
||||
putreg32(regval, NVIC_SYSH8_11_PRIORITY);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_irqinfo
|
||||
*
|
||||
@@ -334,6 +357,9 @@ void up_irqinitialize(void)
|
||||
|
||||
#ifdef CONFIG_ARCH_IRQPRIO
|
||||
/* up_prioritize_irq(STM32_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
|
||||
#endif
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
stm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
|
||||
#endif
|
||||
|
||||
/* If the MPU is enabled, then attach and enable the Memory Management
|
||||
@@ -365,8 +391,7 @@ void up_irqinitialize(void)
|
||||
|
||||
/* And finally, enable interrupts */
|
||||
|
||||
setbasepri(NVIC_SYSH_PRIORITY_MAX);
|
||||
irqrestore(0);
|
||||
irqenable();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -451,15 +476,28 @@ int up_prioritize_irq(int irq, int priority)
|
||||
uint32_t regval;
|
||||
int shift;
|
||||
|
||||
DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < NR_IRQS && (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < NR_IRQS &&
|
||||
priority >= NVIC_SYSH_DISABLE_PRIORITY &&
|
||||
priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#else
|
||||
DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < NR_IRQS &&
|
||||
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
|
||||
#endif
|
||||
|
||||
if (irq < STM32_IRQ_INTERRUPTS)
|
||||
{
|
||||
irq -= 4;
|
||||
/* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority
|
||||
* registers (0-3 are invalid)
|
||||
*/
|
||||
|
||||
regaddr = NVIC_SYSH_PRIORITY(irq);
|
||||
irq -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */
|
||||
|
||||
irq -= STM32_IRQ_INTERRUPTS;
|
||||
regaddr = NVIC_IRQ_PRIORITY(irq);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32/stm32_serial.c
|
||||
*
|
||||
* Copyright (C) 2009-2012 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
|
||||
@@ -1439,6 +1439,31 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_STM32_USART_SINGLEWIRE
|
||||
case TIOCSSINGLEWIRE:
|
||||
{
|
||||
/* Change the TX port to be open-drain/push-pull and enable/disable
|
||||
* half-duplex mode.
|
||||
*/
|
||||
|
||||
uint32_t cr = up_serialin(priv, STM32_USART_CR3_OFFSET);
|
||||
|
||||
if (arg == SER_SINGLEWIRE_ENABLED)
|
||||
{
|
||||
stm32_configgpio(priv->tx_gpio | GPIO_OPENDRAIN);
|
||||
cr |= USART_CR3_HDSEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL);
|
||||
cr &= ~USART_CR3_HDSEL;
|
||||
}
|
||||
|
||||
up_serialout(priv, STM32_USART_CR3_OFFSET, cr);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_TERMIOS
|
||||
case TCGETS:
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* arch/arm/src/stm32/stm32_vectors.S
|
||||
* arch/arm/src/chip/stm32_vectors.S
|
||||
*
|
||||
* Copyright (C) 2009-2012 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
|
||||
@@ -235,7 +235,11 @@ stm32_common:
|
||||
|
||||
mov r2, r1 /* R2=Copy of the main/process stack pointer */
|
||||
add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
mrs r3, basepri /* R3=Current BASEPRI setting */
|
||||
#else
|
||||
mrs r3, primask /* R3=Current PRIMASK setting */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Skip over the block of memory reserved for floating pointer register save.
|
||||
@@ -248,8 +252,8 @@ stm32_common:
|
||||
#endif
|
||||
|
||||
/* Save the the remaining registers on the stack after the registers pushed
|
||||
* by the exception handling logic. r2=SP and r3=primask, r4-r11,r14=register
|
||||
* values.
|
||||
* by the exception handling logic. r2=SP and r3=primask or basepri, r4-r11,
|
||||
* r14=register values.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NUTTX_KERNEL
|
||||
@@ -349,7 +353,7 @@ stm32_common:
|
||||
* Here:
|
||||
* r1 = Address on the target thread's stack position at the start of
|
||||
* the registers saved by hardware
|
||||
* r3 = primask
|
||||
* r3 = primask or basepri
|
||||
* r4-r11 = restored register values
|
||||
*/
|
||||
2:
|
||||
@@ -375,7 +379,12 @@ stm32_common:
|
||||
|
||||
/* Restore the interrupt state */
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
msr basepri, r3 /* Restore interrupts priority masking*/
|
||||
cpsie i /* Re-enable interrupts */
|
||||
#else
|
||||
msr primask, r3 /* Restore interrupts */
|
||||
#endif
|
||||
|
||||
/* Always return with R14 containing the special value that will: (1)
|
||||
* return to thread mode, and (2) continue to use the MSP
|
||||
|
||||
@@ -52,6 +52,10 @@ ifeq ($(CONFIG_BINFMT_EXEPATH),y)
|
||||
BINFMT_CSRCS += binfmt_exepath.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
|
||||
BINFMT_CSRCS += binfmt_schedunload.c
|
||||
endif
|
||||
|
||||
# Symbol table source files
|
||||
|
||||
BINFMT_CSRCS += symtab_findbyname.c symtab_findbyvalue.c
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/binfmt.h>
|
||||
|
||||
#include "binfmt_internal.h"
|
||||
@@ -74,7 +75,9 @@
|
||||
*
|
||||
* Description:
|
||||
* This is a convenience function that wraps load_ and exec_module into
|
||||
* one call.
|
||||
* one call. If CONFIG_SCHED_ONEXIT is also defined, this function will
|
||||
* automatically call schedule_unload() to unload the module when task
|
||||
* exits.
|
||||
*
|
||||
* Input Parameter:
|
||||
* filename - Fulll path to the binary to be loaded
|
||||
@@ -84,7 +87,7 @@
|
||||
*
|
||||
* 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
|
||||
* It returns the PID of the exec'ed module. On failure, it returns
|
||||
* -1 (ERROR) and sets errno appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
@@ -92,6 +95,66 @@
|
||||
int exec(FAR const char *filename, FAR const char **argv,
|
||||
FAR const struct symtab_s *exports, int nexports)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_ONEXIT
|
||||
FAR struct binary_s *bin;
|
||||
int pid;
|
||||
int ret;
|
||||
|
||||
/* Allocate the load information */
|
||||
|
||||
bin = (FAR struct binary_s *)kzalloc(sizeof(struct binary_s));
|
||||
if (!bin)
|
||||
{
|
||||
set_errno(ENOMEM);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Load the module into memory */
|
||||
|
||||
bin->filename = filename;
|
||||
bin->exports = exports;
|
||||
bin->nexports = nexports;
|
||||
|
||||
ret = load_module(bin);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: Failed to load program '%s'\n", filename);
|
||||
kfree(bin);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Disable pre-emption so that the executed module does
|
||||
* not return until we get a chance to connect the on_exit
|
||||
* handler.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Then start the module */
|
||||
|
||||
pid = exec_module(bin);
|
||||
if (pid < 0)
|
||||
{
|
||||
bdbg("ERROR: Failed to execute program '%s'\n", filename);
|
||||
sched_unlock();
|
||||
unload_module(bin);
|
||||
kfree(bin);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Set up to unload the module (and free the binary_s structure)
|
||||
* when the task exists.
|
||||
*/
|
||||
|
||||
ret = schedule_unload(pid, bin);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: Failed to schedul unload '%s'\n", filename);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
return pid;
|
||||
#else
|
||||
struct binary_s bin;
|
||||
int ret;
|
||||
|
||||
@@ -119,7 +182,10 @@ int exec(FAR const char *filename, FAR const char **argv,
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* TODO: How does the module get unloaded in this case? */
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BINFMT_DISABLE */
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
static int load_default_priority(FAR struct binary_s *bin)
|
||||
{
|
||||
struct sched_param param;
|
||||
int ret;
|
||||
|
||||
/* Get the priority of this thread */
|
||||
|
||||
@@ -97,6 +98,7 @@ static int load_default_priority(FAR struct binary_s *bin)
|
||||
/* Save that as the priority of child thread */
|
||||
|
||||
bin->priority = param.sched_priority;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -180,7 +182,7 @@ int load_module(FAR struct binary_s *bin)
|
||||
{
|
||||
/* Set the default priority of the new program. */
|
||||
|
||||
ret = load_default_priority(bin)
|
||||
ret = load_default_priority(bin);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* The errno is already set in this case */
|
||||
|
||||
@@ -0,0 +1,333 @@
|
||||
/****************************************************************************
|
||||
* binfmt/binfmt_schedunload.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 <sched.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/binfmt.h>
|
||||
|
||||
#include "binfmt_internal.h"
|
||||
|
||||
#if !defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_SCHED_HAVE_PARENT)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct binary_s *g_unloadhead;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: unload_list_add
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_SCHED_HAVE_PARENT is defined then schedul_unload() will
|
||||
* manage instances of struct binary_s allocated with kmalloc. It
|
||||
* will keep the binary data in a link list and when SIGCHLD is received
|
||||
* (meaning that the task has exit'ed, schedul_unload() will find the
|
||||
* data, unload the module, and free the structure.
|
||||
*
|
||||
* This function will add one structure to the linked list
|
||||
*
|
||||
* Input Parameter:
|
||||
* pid - The task ID of the child task
|
||||
* bin - This structure must have been allocated with kmalloc() and must
|
||||
* persist until the task unloads
|
||||
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void unload_list_add(pid_t pid, FAR struct binary_s *bin)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* Save the PID in the structure so that we recover it later */
|
||||
|
||||
bin->pid = pid;
|
||||
|
||||
/* Disable deliver of any signals while we muck with the list. The graceful
|
||||
* way to do this would be block delivery of SIGCHLD would be with
|
||||
* sigprocmask. Here we do it the quick'n'dirty way by just disabling
|
||||
* interrupts.
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
bin->flink = g_unloadhead;
|
||||
g_unloadhead = bin;
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: unload_list_remove
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_SCHED_HAVE_PARENT is defined then schedul_unload() will
|
||||
* manage instances of struct binary_s allocated with kmalloc. It
|
||||
* will keep the binary data in a link list and when SIGCHLD is received
|
||||
* (meaning that the task has exit'ed, schedul_unload() will find the
|
||||
* data, unload the module, and free the structure.
|
||||
*
|
||||
* This function will remove one structure to the linked list
|
||||
*
|
||||
* Input Parameter:
|
||||
* pid - The task ID of the child task
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the load structure is returned. NULL is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR struct binary_s *unload_list_remove(pid_t pid)
|
||||
{
|
||||
FAR struct binary_s *curr;
|
||||
FAR struct binary_s *prev;
|
||||
|
||||
/* Note the asymmetry. We do not have to disable interrupts here because
|
||||
* the main thread cannot run while we are in the interrupt handler. Here,
|
||||
* it should be sufficient to disable pre-emption so that no other thread
|
||||
* can run.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Find the structure in the unload list with the matching PID */
|
||||
|
||||
for (prev = NULL, curr = g_unloadhead;
|
||||
curr && (curr->pid != pid);
|
||||
prev = curr, curr = curr->flink);
|
||||
|
||||
/* Did we find it? It must be there. Hmmm.. we should probably ASSERT if
|
||||
* we do not!
|
||||
*/
|
||||
|
||||
if (curr)
|
||||
{
|
||||
/* Was there another entry before this one? */
|
||||
|
||||
if (prev)
|
||||
{
|
||||
/* Yes.. remove the current entry from after the previous entry */
|
||||
|
||||
prev->flink = curr->flink;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No.. remove the current entry from the head of the list */
|
||||
|
||||
g_unloadhead = curr->flink;
|
||||
}
|
||||
|
||||
/* Nullify the forward link ... superstitious */
|
||||
|
||||
curr->flink = NULL;
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
return curr;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: unload_callback
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_SCHED_HAVE_PARENT is defined, this function may be called to
|
||||
* automatically unload the module when task exits. It assumes that
|
||||
* bin was allocated with kmalloc() or friends and will also automatically
|
||||
* free the structure with kfree() when the task exists.
|
||||
*
|
||||
* Input Parameter:
|
||||
* pid - The ID of the task that just exited
|
||||
* arg - A reference to the load structure cast to FAR void *
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void unload_callback(int signo, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
FAR struct binary_s *bin;
|
||||
int ret;
|
||||
|
||||
/* Sanity checking */
|
||||
|
||||
if (!info || signo != SIGCHLD)
|
||||
{
|
||||
blldbg("ERROR:Bad signal callback: signo=%d info=%p\n", signo, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the load information for this pid */
|
||||
|
||||
bin = unload_list_remove(info->si_pid);
|
||||
if (!bin)
|
||||
{
|
||||
blldbg("ERROR: Could not find load info for PID=%d\n", info->si_pid);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Unload the module */
|
||||
|
||||
ret = unload_module(bin);
|
||||
if (ret < 0)
|
||||
{
|
||||
blldbg("ERROR: unload_module failed: %d\n", get_errno());
|
||||
}
|
||||
|
||||
/* Free the load structure */
|
||||
|
||||
kfree(bin);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: schedule_unload
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_SCHED_HAVE_PARENT is defined, this function may be called by
|
||||
* the parent of the the newly created task to automatically unload the
|
||||
* module when the task exits. This assumes that (1) the caller is the
|
||||
* parent of the created task, (2) that bin was allocated with kmalloc()
|
||||
* or friends. It will also automatically free the structure with kfree()
|
||||
* after unloading the module.
|
||||
*
|
||||
* Input Parameter:
|
||||
* pid - The task ID of the child task
|
||||
* bin - This structure must have been allocated with kmalloc() and must
|
||||
* persist until the task unloads
|
||||
*
|
||||
* Returned Value:
|
||||
* This is an end-user function, so it follows the normal convention:
|
||||
* It returns 0 (OK) if the callback was successfully scheduled. On
|
||||
* failure, it returns -1 (ERROR) and sets errno appropriately.
|
||||
*
|
||||
* On failures, the 'bin' structure will not be deallocated and the
|
||||
* module not not be unloaded.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int schedule_unload(pid_t pid, FAR struct binary_s *bin)
|
||||
{
|
||||
struct sigaction act;
|
||||
struct sigaction oact;
|
||||
sigset_t sigset;
|
||||
irqstate_t flags;
|
||||
int errorcode;
|
||||
int ret;
|
||||
|
||||
/* Make sure that SIGCHLD is unmasked */
|
||||
|
||||
(void)sigemptyset(&sigset);
|
||||
(void)sigaddset(&sigset, SIGCHLD);
|
||||
ret = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
||||
if (ret != OK)
|
||||
{
|
||||
/* The errno value will get trashed by the following debug output */
|
||||
|
||||
errorcode = get_errno();
|
||||
bvdbg("ERROR: sigprocmask failed: %d\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Add the structure to the list. We want to do this *before* connecting
|
||||
* the signal handler. This does, however, make error recovery more
|
||||
* complex if sigaction() fails below because then we have to remove the
|
||||
* unload structure for the list in an unexpected context.
|
||||
*/
|
||||
|
||||
unload_list_add(pid, bin);
|
||||
|
||||
/* Register the SIGCHLD handler */
|
||||
|
||||
act.sa_sigaction = unload_callback;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
|
||||
(void)sigfillset(&act.sa_mask);
|
||||
(void)sigdelset(&act.sa_mask, SIGCHLD);
|
||||
|
||||
ret = sigaction(SIGCHLD, &act, &oact);
|
||||
if (ret != OK)
|
||||
{
|
||||
/* The errno value will get trashed by the following debug output */
|
||||
|
||||
errorcode = get_errno();
|
||||
bvdbg("ERROR: sigaction failed: %d\n" , ret);
|
||||
|
||||
/* Emergency removal from the list */
|
||||
|
||||
flags = irqsave();
|
||||
if (unload_list_remove(pid) != bin)
|
||||
{
|
||||
blldbg("ERROR: Failed to remove structure\n");
|
||||
}
|
||||
|
||||
goto errout;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
set_errno(errorcode);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_BINFMT_DISABLE && CONFIG_SCHED_HAVE_PARENT */
|
||||
|
||||
@@ -89,6 +89,7 @@ static struct binfmt_s g_builtin_binfmt =
|
||||
static int builtin_loadbinary(struct binary_s *binp)
|
||||
{
|
||||
FAR const char *filename;
|
||||
FAR const struct builtin_s *b;
|
||||
int fd;
|
||||
int index;
|
||||
int ret;
|
||||
@@ -97,11 +98,11 @@ static int builtin_loadbinary(struct binary_s *binp)
|
||||
|
||||
/* Open the binary file for reading (only) */
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
fd = open(binp->filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
bdbg("ERROR: Failed to open binary %s: %d\n", filename, errval);
|
||||
bdbg("ERROR: Failed to open binary %s: %d\n", binp->filename, errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
@@ -134,9 +135,10 @@ static int builtin_loadbinary(struct binary_s *binp)
|
||||
* 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;
|
||||
b = builtin_for_index(index);
|
||||
binp->entrypt = b->main;
|
||||
binp->stacksize = b->stacksize;
|
||||
binp->priority = b->priority;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,10 +83,14 @@
|
||||
|
||||
FAR const char *builtin_getname(int index)
|
||||
{
|
||||
if (index < 0 || index >= number_builtins())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
FAR const struct builtin_s *builtin;
|
||||
|
||||
return g_builtins[index].name;
|
||||
builtin = builtin_for_index(index);
|
||||
|
||||
if (builtin != NULL)
|
||||
{
|
||||
return builtin->name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -80,18 +80,19 @@
|
||||
* Name: builtin_isavail
|
||||
*
|
||||
* Description:
|
||||
* Return the index into the table of applications for the applicaiton with
|
||||
* Return the index into the table of applications for the application with
|
||||
* the name 'appname'.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int builtin_isavail(FAR const char *appname)
|
||||
{
|
||||
FAR const char *name;
|
||||
int i;
|
||||
|
||||
for (i = 0; g_builtins[i].name; i++)
|
||||
for (i = 0; (name = builtin_getname(i)); i++)
|
||||
{
|
||||
if (!strncmp(g_builtins[i].name, appname, NAME_MAX))
|
||||
if (!strncmp(name, appname, NAME_MAX))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -334,12 +334,79 @@ 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
|
||||
CONFIG_SCHED_HAVE_PARENT - Remember the ID of the parent task
|
||||
when a new child task 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_SCHED_CHILD_STATUS
|
||||
If this option is selected, then the exit status of the child task
|
||||
will be retained after the child task exits. This option should be
|
||||
selected if you require knowledge of a child process' exit status.
|
||||
Without this setting, wait(), waitpid() or waitid() may fail. For
|
||||
example, if you do:
|
||||
|
||||
1) Start child task
|
||||
2) Wait for exit status (using wait(), waitpid(), or waitid()).
|
||||
|
||||
This can fail because the child task may run to completion before
|
||||
the wait begins. There is a non-standard work-around in this case:
|
||||
The above sequence will work if you disable pre-emption using
|
||||
sched_lock() prior to starting the child task, then re-enable pre-
|
||||
emption with sched_unlock() after the wait completes. This works
|
||||
because the child task is not permitted to run until the wait is in
|
||||
place.
|
||||
|
||||
The standard solution would be to enable CONFIG_SCHED_CHILD_STATUS. In
|
||||
this case the exit status of the child task is retained after the
|
||||
child exits and the wait will successful obtain the child task's
|
||||
exit status whether it is called before the child task exits or not.
|
||||
|
||||
Warning: If you enable this feature, then your application must
|
||||
either (1) take responsibility for reaping the child status with wait(),
|
||||
waitpid(), or waitid(), or (2) suppress retention of child status.
|
||||
If you do not reap the child status, then you have a memory leak and
|
||||
your system will eventually fail.
|
||||
|
||||
Retention of child status can be suppressed on the parent using logic like:
|
||||
|
||||
struct sigaction sa;
|
||||
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sa.sa_flags = SA_NOCLDWAIT;
|
||||
int ret = sigaction(SIGCHLD, &sa, NULL);
|
||||
|
||||
CONFIG_PREALLOC_CHILDSTATUS
|
||||
To prevent runaway child status allocations and to improve
|
||||
allocation performance, child task exit status structures are pre-
|
||||
allocated when the system boots. This setting determines the number
|
||||
of child status structures that will be pre-allocated. If this
|
||||
setting is not defined or if it is defined to be zero then a value
|
||||
of 2*MAX_TASKS is used.
|
||||
|
||||
Note that there cannot be more that CONFIG_MAX_TASKS tasks in total.
|
||||
However, the number of child status structures may need to be
|
||||
significantly larger because this number includes the maximum number
|
||||
of tasks that are running PLUS the number of tasks that have exit'ed
|
||||
without having their exit status reaped (via wait(), waitid(), or
|
||||
waitpid()).
|
||||
|
||||
Obviously, if tasks spawn children indefinitely and never have the
|
||||
exit status reaped, then you may have a memory leak! If you enable
|
||||
the SCHED_CHILD_STATUS feature, then your application must take
|
||||
responsibility for either (1) reaping the child status with wait(),
|
||||
waitpid(), or waitid() or it must (2) suppress retention of child
|
||||
status. Otherwise, your system will eventually fail.
|
||||
|
||||
Retention of child status can be suppressed on the parent using logic like:
|
||||
|
||||
struct sigaction sa;
|
||||
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sa.sa_flags = SA_NOCLDWAIT;
|
||||
int ret = sigaction(SIGCHLD, &sa, NULL);
|
||||
|
||||
CONFIG_START_YEAR, CONFIG_START_MONTH, CONFIG_START_DAY -
|
||||
Used to initialize the internal time logic.
|
||||
CONFIG_GREGORIAN_TIME - Enables Gregorian time conversions.
|
||||
|
||||
@@ -119,47 +119,71 @@ that support additional LCDs. LCD drivers in the configuration directory
|
||||
if they support some differ LCD interface (such as a parallel interface)
|
||||
that makes then less re-usable:
|
||||
|
||||
configs/compal_e99/src/ssd1783.c
|
||||
SSD1783 Drivers:
|
||||
|
||||
SSD1783
|
||||
configs/compal_e99/src/ssd1783.c
|
||||
|
||||
configs/hymini-stm32v/src/ssd1289.c. See also drivers/lcd/ssd1298.c
|
||||
above.
|
||||
SSD1289 Drivers:
|
||||
|
||||
configs/hymini-stm32v/src/ssd1289.c. See also drivers/lcd/ssd1298.c
|
||||
above.
|
||||
configs/stm32f4discovery/src/up_ssd1289.c. This examples is the
|
||||
bottom half for the SSD1289 driver at drivers/lcd/ssd1289.c
|
||||
configs/hymini-stm32v/src/ssd1289.c. See also drivers/lcd/ssd1298.c
|
||||
above.
|
||||
configs/shenzhou/src/up_ssd1289.c
|
||||
|
||||
kwikstik-k40:
|
||||
|
||||
SSD1289
|
||||
configs/kwikstik-k40/src/up_lcd.c. Don't waste your time. This is
|
||||
just a stub.
|
||||
|
||||
configs/kwikstik-k40/src/up_lcd.c. Don't waste your time. This is
|
||||
just a stub.
|
||||
Nokia LCD Drivers:
|
||||
|
||||
configs/olimex-lpc1766stk/src/up_lcd.c. This examples is the
|
||||
bottom half for the SSD1289 driver at drivers/lcd/nokia6100.c.
|
||||
This was never completedly debugged ... there are probably issues
|
||||
with that nasty 9-bit SPI interfaces.
|
||||
configs/olimex-lpc1766stk/src/up_lcd.c. This examples is the
|
||||
bottom half for the driver at drivers/lcd/nokia6100.c.
|
||||
This was never completedly debugged ... there are probably issues
|
||||
with that nasty 9-bit SPI interfaces.
|
||||
|
||||
configs/sam3u-ek/src/up_lcd.c
|
||||
|
||||
The SAM3U-EK developement board features a TFT/Transmissive color
|
||||
LCD module with touch-screen, FTM280C12D, with integrated driver IC
|
||||
HX8346.
|
||||
HX8346:
|
||||
|
||||
configs/skp16c26/src/up_lcd.c. Untested alphanumeric LCD driver.
|
||||
configs/sam3u-ek/src/up_lcd.c. The SAM3U-EK developement board features
|
||||
a TFT/Transmissive color LCD module with touch-screen, FTM280C12D,
|
||||
with integrated driver IC HX8346.
|
||||
|
||||
configs/stm3210e-eval/src/up_lcd.c
|
||||
HX8347:
|
||||
|
||||
This driver supports the following LCDs:
|
||||
configs/pic32mx7mmb/src/up_mio283qt2.c. This driver is for the MI0283QT-2
|
||||
LCD from Multi-Inno Technology Co., Ltd. This LCD is based on the Himax
|
||||
HX8347-D LCD controller.
|
||||
|
||||
ILI93xx and Similar:
|
||||
|
||||
1. Ampire AM-240320LTNQW00H
|
||||
2. Orise Tech SPFD5408B
|
||||
3. RenesasSP R61580
|
||||
configs/stm3210e-eval/src/up_lcd.c. This driver supports the following
|
||||
LCDs:
|
||||
|
||||
configs/stm3220g-eval/src/up_lcd.c and configs/stm3240g-eval/src/up_lcd.c.
|
||||
AM-240320L8TNQW00H (LCD_ILI9320 or LCD_ILI9321) and
|
||||
AM-240320D5TOQW01H (LCD_ILI9325)
|
||||
1. Ampire AM-240320LTNQW00H
|
||||
2. Orise Tech SPFD5408B
|
||||
3. RenesasSP R61580
|
||||
|
||||
configs/stm32f4discovery/src/up_ssd1289.c. This examples is the
|
||||
bottom half for the SSD1289 driver at drivers/lcd/ssd1289.c
|
||||
configs/stm3220g-eval/src/up_lcd.c and configs/stm3240g-eval/src/up_lcd.c.
|
||||
AM-240320L8TNQW00H (LCD_ILI9320 or LCD_ILI9321) and
|
||||
AM-240320D5TOQW01H (LCD_ILI9325)
|
||||
configs/shenzhou/src/up_ili93xx.c. Another ILI93xx driver.
|
||||
|
||||
OLEDs:
|
||||
|
||||
configs/stm32f4discovery/src/up_ug2864ambag01.c
|
||||
configs/stm32f4discovery/src/up_ug2864hsweg01.c
|
||||
configs/zp214xpa/src/up_ug2864ambag01.c
|
||||
|
||||
Alphnumeric LCD Displays:
|
||||
|
||||
configs/skp16c26/src/up_lcd.c. Untested alphanumeric LCD driver.
|
||||
configs/pcblogic-pic32/src/up_lcd1602.c
|
||||
|
||||
graphics/
|
||||
=========
|
||||
|
||||
See also the usage of the LCD driver in the graphics/ directory.
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ config MMCSD_SPICLOCK
|
||||
|
||||
config MMCSD_SDIO
|
||||
bool "MMC/SD sdio transfer support"
|
||||
default y
|
||||
default n
|
||||
|
||||
if MMCSD_SDIO
|
||||
config SDIO_DMA
|
||||
|
||||
@@ -222,7 +222,7 @@ static int binfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr = g_builtins[(int)filep->f_priv].name;
|
||||
*ptr = builtin_getname((int)filep->f_priv);
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
@@ -287,13 +287,15 @@ static int binfs_opendir(struct inode *mountpt, const char *relpath,
|
||||
|
||||
static int binfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR const char *name;
|
||||
unsigned int index;
|
||||
int ret;
|
||||
|
||||
/* Have we reached the end of the directory */
|
||||
|
||||
index = dir->u.binfs.fb_index;
|
||||
if (g_builtins[index].name == NULL)
|
||||
name = builtin_getname(index);
|
||||
if (name == NULL)
|
||||
{
|
||||
/* We signal the end of the directory by returning the
|
||||
* special error -ENOENT
|
||||
@@ -306,9 +308,9 @@ static int binfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||
{
|
||||
/* Save the filename and file type */
|
||||
|
||||
fvdbg("Entry %d: \"%s\"\n", index, g_builtins[index].name);
|
||||
fvdbg("Entry %d: \"%s\"\n", index, name);
|
||||
dir->fd_dir.d_type = DTYPE_FILE;
|
||||
strncpy(dir->fd_dir.d_name, g_builtins[index].name, NAME_MAX+1);
|
||||
strncpy(dir->fd_dir.d_name, name, NAME_MAX+1);
|
||||
|
||||
/* The application list is terminated by an entry with a NULL name.
|
||||
* Therefore, there is at least one more entry in the list.
|
||||
|
||||
@@ -82,6 +82,18 @@ typedef FAR void (*binfmt_dtor_t)(void);
|
||||
struct symtab_s;
|
||||
struct binary_s
|
||||
{
|
||||
/* If CONFIG_SCHED_HAVE_PARENT is defined then schedul_unload() will
|
||||
* manage instances of struct binary_s allocated with kmalloc. It
|
||||
* will keep the binary data in a link list and when SIGCHLD is received
|
||||
* (meaning that the task has exit'ed, schedul_unload() will find the
|
||||
* data, unload the module, and free the structure.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
FAR struct binary_s *flink; /* Supports a singly linked list */
|
||||
pid_t pid; /* Task ID of the child task */
|
||||
#endif
|
||||
|
||||
/* Information provided to the loader to load and bind a module */
|
||||
|
||||
FAR const char *filename; /* Full path to the binary to be loaded (See NOTE 1 above) */
|
||||
@@ -222,19 +234,48 @@ int unload_module(FAR const struct binary_s *bin);
|
||||
*
|
||||
* 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
|
||||
* Returns the PID of the exec'ed module. On failure, it returns
|
||||
* -1 (ERROR) and sets errno appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int exec_module(FAR const struct binary_s *bin);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: schedule_unload
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_SCHED_HAVE_PARENT is defined, this function may be called by
|
||||
* the parent of the the newly created task to automatically unload the
|
||||
* module when the task exits. This assumes that (1) the caller is the
|
||||
* parent of the created task, (2) that bin was allocated with kmalloc()
|
||||
* or friends. It will also automatically free the structure with kfree()
|
||||
* after unloading the module.
|
||||
*
|
||||
* Input Parameter:
|
||||
* pid - The task ID of the child task
|
||||
* bin - This structure must have been allocated with kmalloc() and must
|
||||
* persist until the task unloads
|
||||
*
|
||||
* Returned Value:
|
||||
* This is an end-user function, so it follows the normal convention:
|
||||
* It returns 0 (OK) if the callback was successfully scheduled. On
|
||||
* failure, it returns -1 (ERROR) and sets errno appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
int schedule_unload(pid_t pid, FAR struct binary_s *bin);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: exec
|
||||
*
|
||||
* Description:
|
||||
* This is a convenience function that wraps load_ and exec_module into
|
||||
* one call.
|
||||
* one call. If CONFIG_SCHED_ONEXIT is also defined, this function will
|
||||
* automatically call schedule_unload() to unload the module when task
|
||||
* exits.
|
||||
*
|
||||
* Input Parameter:
|
||||
* filename - Fulll path to the binary to be loaded
|
||||
@@ -244,7 +285,7 @@ int exec_module(FAR const struct binary_s *bin);
|
||||
*
|
||||
* 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
|
||||
* It returns the PID of the exec'ed module. On failure, it returns
|
||||
* -1 (ERROR) and sets errno appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@@ -73,18 +73,40 @@ extern "C" {
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* The g_builtins[] array holds information about each builtin function. If
|
||||
* support for builtin functions is enabled in the NuttX configuration, then
|
||||
* this arrary (along with the number_builtins() function) must be provided
|
||||
* by the application code.
|
||||
*/
|
||||
|
||||
EXTERN const struct builtin_s g_builtins[];
|
||||
|
||||
/****************************************************************************
|
||||
* 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);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: builtin_uninitialize
|
||||
*
|
||||
* Description:
|
||||
* Unregister the builtin binary loader
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void builtin_uninitialize(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Utility Functions Provided to Applications by binfmt/libbuiltin
|
||||
****************************************************************************/
|
||||
@@ -128,24 +150,24 @@ FAR const char *builtin_getname(int index);
|
||||
* Data Set Access Functions Provided to Applications by binfmt/libbuiltin
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
* Name: number_builtins
|
||||
* Name: builtin_for_index
|
||||
*
|
||||
* Description:
|
||||
* Returns the number of builtin functions in the g_builtins[] array. If
|
||||
* support for builtin functions is enabled in the NuttX configuration,
|
||||
* then this function (along with g_builtins[]) must be provided by the
|
||||
* application code.
|
||||
* Returns the builtin_s structure for the selected builtin.
|
||||
* If support for builtin functions is enabled in the NuttX configuration,
|
||||
* then this function must be provided by the application code.
|
||||
*
|
||||
* Input Parameter:
|
||||
* None
|
||||
* index, from 0 and on...
|
||||
*
|
||||
* Returned Value:
|
||||
* The number of entries in the g_builtins[] array. This function does
|
||||
* not return failures.
|
||||
* Returns valid pointer pointing to the builtin_s structure if index is
|
||||
* valid.
|
||||
* Otherwise, NULL is returned.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int number_builtins(void);
|
||||
EXTERN FAR const struct builtin_s *builtin_for_index(int index);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/********************************************************************************************
|
||||
* include/nuttx/lcd/hd4478ou.h
|
||||
*
|
||||
* Definitions for the Hitachi HD44780U LCD controller (as used in the
|
||||
* LCD1602).
|
||||
*
|
||||
* 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 __INCLUDE_NUTTX_HD4478OU_H
|
||||
#define __INCLUDE_NUTTX_HD4478OU_H
|
||||
|
||||
/********************************************************************************************
|
||||
* Included Files
|
||||
********************************************************************************************/
|
||||
/* Command set:
|
||||
*
|
||||
* RS=0 R/W=0 : Command
|
||||
* RS=0 R/W=1 : Busy/AD, Read CT (see below)
|
||||
* RS=1 R/W=0 : Write data to CGRAM or DDRAM
|
||||
* RS=1 R/W=0 : Read data from CGRAM or DDRAM
|
||||
*/
|
||||
|
||||
#define HD4478OU_CLEAR (0x01) /* Screen Clear, Set AC to 0 */
|
||||
#define HD4478OU_RETURN (0x02) /* DDRAM AD=0, return */
|
||||
#define HD4478OU_INPUT (0x04) /* Set moving direction of cursor */
|
||||
# define HD4478OU_INPUT_SHIFT (1 << 0) /* Shift */
|
||||
# define HD4478OU_INPUT_INCR (1 << 1) /* Increment mode */
|
||||
# define HD4478OU_INPUT_DECR (0x00) /* Decrement mode */
|
||||
#define HD4478OU_DISPLAY (0x08) /* Set display, cursor, blink on/off */
|
||||
# define HD4478OU_DISPLAY_BLINK (1 << 0) /* Blink on/off */
|
||||
# define HD4478OU_DISPLAY_CURSOR (1 << 1) /* Cursor on/off */
|
||||
# define HD4478OU_DISPLAY_ON (1 << 2) /* Display on/off */
|
||||
#define HD4478OU_SHIFT (0x10) /* Remove cursor and whole diplay */
|
||||
# define HD4478OU_SHIFT_RIGHT (1 << 2) /* Shift right */
|
||||
# define HD4478OU_SHIFT_LEFT (0x00) /* Shift right */
|
||||
# define HD4478OU_SHIFT_DISPLAY (1 << 3) /* Display shift */
|
||||
# define HD4478OU_SHIFT_CURSOR (0x00) /* Cursor shift */
|
||||
#define HD4478OU_FUNC (0x20) /* Set DL, display line, font */
|
||||
# define HD4478OU_FUNC_F5x10 (1 << 2) /* 5x10 Style */
|
||||
# define HD4478OU_FUNC_F5x7 (0x00) /* 5x7 Style */
|
||||
# define HD4478OU_FUNC_N1 (1 << 3) /* N=2R */
|
||||
# define HD4478OU_FUNC_N0 (0x00) /* N=1R */
|
||||
# define HD4478OU_FUNC_DL8D (1 << 4) /* DL=8D, 8-bit interface */
|
||||
# define HD4478OU_FUNC_DL4D (0x00) /* DL=4D, 4-bit interface */
|
||||
#define HD4478OU_CGRAM_AD(a) (0x40|(a)) /* Set CGRAM AD, send receive data */
|
||||
#define HD4478OU_DDRAM_AD(a) (0x80|(a)) /* Set DDRAM AD, send receive data */
|
||||
|
||||
/* RS=0 R/W=1 : Execute internal function, read AD of CT */
|
||||
|
||||
#define HD4478OU_BUSY(bf,ac) ((bf) << 7 | (ac))
|
||||
|
||||
/********************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
********************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Types
|
||||
********************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Data
|
||||
********************************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Function Prototypes
|
||||
********************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
* Name: up_lcd1602_initialize
|
||||
*
|
||||
* Description:
|
||||
* the LCD1602 is an HD4478OU-based LCD from Wave share. This function initializes the
|
||||
* LCD1602 hardware and registers the character driver as /dev/lcd1602.
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
int up_lcd1602_initialize(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_HD4478OU_H */
|
||||
@@ -1,5 +1,6 @@
|
||||
/**************************************************************************************
|
||||
* include/nuttx/lcd/ug-2864ambag01.h
|
||||
*
|
||||
* Driver for Univision UG-2864AMBAG01 OLED display (wih SH1101A controller) in SPI
|
||||
* mode
|
||||
*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/**************************************************************************************
|
||||
* include/nuttx/lcd/ug-2864hsweg01.h
|
||||
*
|
||||
* Driver for Univision UG-2864HSWEG01 OLED display (wih SSD1306 controller) in SPI
|
||||
* mode
|
||||
*
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user