diff options
Diffstat (limited to 'apps')
43 files changed, 1487 insertions, 341 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt index bcc0ac172..05cd6176a 100644 --- a/apps/ChangeLog.txt +++ b/apps/ChangeLog.txt @@ -434,7 +434,7 @@ tests will now use a relative path to the program and expect the binfmt/ logic to find the absolute path to the program using the PATH variable. -6.25 2013-xx-xx Gregory Nutt <gnutt@nuttx.org> +6.25 2013-02-01 Gregory Nutt <gnutt@nuttx.org> * Makefiles: Removed dependency of distclean on clean in most top-level files. It makes sense for 'leaf' Makefiles to have this dependency, @@ -461,7 +461,7 @@ the USB HID keyboard report data. * apps/examples/wlan: Remove non-functional example. * apps/examples/ostest/vfork.c: Added a test of vfork(). - * apps/exampes/posix_spawn: Added a test of poxis_spawn(). + * apps/exampes/posix_spawn: Added a test of posix_spawn(). * apps/examples/ostest: Extend signal handler test to catch death-of-child signals (SIGCHLD). * apps/examples/ostest/waitpid.c: Add a test for waitpid(), waitid(), @@ -478,7 +478,7 @@ * apps/include/builtin.h: Some of the content of apps/include/apps.h moved to include/nuttx/binfmt/builtin.h. apps/include/apps.h renamed builtin.h - * apps/builtin/exec_builtins.c: Move utility builtin + * apps/builtin/exec_builtins.c: Move builtin utility functions from apps/builtin/exec_builtins.c to binfmt/libbuiltin/libbuiltin_utils.c * apps/nshlib/nsh_mountcmds.c: The block driver/source @@ -492,3 +492,18 @@ 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. + * apps/examples/nettest and poll: Complete Kconfig files. + * apps/examples/ostest/waitpid.c: Need to use WEXITSTATUS() + to decode the correct exit status. + * apps/system/usbmonitor: A daemon that can be used to monitor USB + trace outpout. + * apps/nshlib/nsh_usbdev.c, nsh_consolemain.c, nsh_session.c, nsh_script.c: + Add support for a login script. The init.d/rcS script will be executed + once when NSH starts; the .nshrc script will be executed for each session: + Once for serial, once for each USB connection, once for each Telnet + session. + * apps/system/readline: Correct readline() return value. Was not + any returning special values when end-of-file or read errors + occur (it would return an empty string which is not very useful). + +6.26 2013-xx-xx Gregory Nutt <gnutt@nuttx.org> diff --git a/apps/builtin/exec_builtin.c b/apps/builtin/exec_builtin.c index 60e8b742d..5d3a1c08a 100644 --- a/apps/builtin/exec_builtin.c +++ b/apps/builtin/exec_builtin.c @@ -309,7 +309,7 @@ static inline int builtin_startproxy(int index, FAR const char **argv, { struct sched_param param; pid_t proxy; - int errcode; + int errcode = OK; #ifdef CONFIG_SCHED_WAITPID int status; #endif diff --git a/apps/drivers/boards/px4fmu/px4fmu_init.c b/apps/drivers/boards/px4fmu/px4fmu_init.c index e88d2861e..9960c6bbd 100644 --- a/apps/drivers/boards/px4fmu/px4fmu_init.c +++ b/apps/drivers/boards/px4fmu/px4fmu_init.c @@ -79,13 +79,13 @@ #ifdef CONFIG_CPP_HAVE_VARARGS # ifdef CONFIG_DEBUG -# define message(...) lib_lowprintf(__VA_ARGS__) +# define message(...) lowsyslog(__VA_ARGS__) # else # define message(...) printf(__VA_ARGS__) # endif #else # ifdef CONFIG_DEBUG -# define message lib_lowprintf +# define message lowsyslog # else # define message printf # endif diff --git a/apps/examples/README.txt b/apps/examples/README.txt index 5996cbb70..03d43f1a0 100644 --- a/apps/examples/README.txt +++ b/apps/examples/README.txt @@ -675,8 +675,8 @@ examples/mount when CONFIG_EXAMPLES_MOUNT_DEVNAME is not defined. The default is zero (meaning that "/dev/ram0" will be used). -examples/netttest -^^^^^^^^^^^^^^^^^ +examples/nettest +^^^^^^^^^^^^^^^^ This is a simple network test for verifying client- and server- functionality in a TCP/IP connection. diff --git a/apps/examples/adc/adc.h b/apps/examples/adc/adc.h index 9f79db92a..2d8af87e1 100644 --- a/apps/examples/adc/adc.h +++ b/apps/examples/adc/adc.h @@ -74,7 +74,7 @@ #ifdef CONFIG_CPP_HAVE_VARARGS # ifdef CONFIG_DEBUG -# define message(...) lib_rawprintf(__VA_ARGS__) +# define message(...) syslog(__VA_ARGS__) # define msgflush() # else # define message(...) printf(__VA_ARGS__) @@ -82,7 +82,7 @@ # endif #else # ifdef CONFIG_DEBUG -# define message lib_rawprintf +# define message syslog # define msgflush() # else # define message printf diff --git a/apps/examples/buttons/buttons_main.c b/apps/examples/buttons/buttons_main.c index 5f25c1ef1..655080def 100644 --- a/apps/examples/buttons/buttons_main.c +++ b/apps/examples/buttons/buttons_main.c @@ -299,11 +299,11 @@ static void show_buttons(uint8_t oldset, uint8_t newset) state = "released"; } - /* Use lib_lowprintf() because we make be executing from an + /* Use lowsyslog() because we make be executing from an * interrupt handler. */ - lib_lowprintf(" %s %s\n", g_buttoninfo[BUTTON_INDEX(i)].name, state); + lowsyslog(" %s %s\n", g_buttoninfo[BUTTON_INDEX(i)].name, state); } } } @@ -313,8 +313,8 @@ static void button_handler(int id, int irq) { uint8_t newset = up_buttons(); - lib_lowprintf("IRQ:%d Button %d:%s SET:%02x:\n", - irq, id, g_buttoninfo[BUTTON_INDEX(id)].name, newset); + lowsyslog("IRQ:%d Button %d:%s SET:%02x:\n", + irq, id, g_buttoninfo[BUTTON_INDEX(id)].name, newset); show_buttons(g_oldset, newset); g_oldset = newset; } @@ -409,7 +409,7 @@ int buttons_main(int argc, char *argv[]) { maxbuttons = strtol(argv[1], NULL, 10); } - lib_lowprintf("maxbuttons: %d\n", maxbuttons); + lowsyslog("maxbuttons: %d\n", maxbuttons); #endif /* Initialize the button GPIOs */ @@ -423,11 +423,11 @@ int buttons_main(int argc, char *argv[]) { xcpt_t oldhandler = up_irqbutton(i, g_buttoninfo[BUTTON_INDEX(i)].handler); - /* Use lib_lowprintf() for compatibility with interrrupt handler output. */ + /* Use lowsyslog() for compatibility with interrrupt handler output. */ - lib_lowprintf("Attached handler at %p to button %d [%s], oldhandler:%p\n", - g_buttoninfo[BUTTON_INDEX(i)].handler, i, - g_buttoninfo[BUTTON_INDEX(i)].name, oldhandler); + lowsyslog("Attached handler at %p to button %d [%s], oldhandler:%p\n", + g_buttoninfo[BUTTON_INDEX(i)].handler, i, + g_buttoninfo[BUTTON_INDEX(i)].name, oldhandler); /* Some hardware multiplexes different GPIO button sources to the same * physical interrupt. If we register multiple such multiplexed button @@ -438,9 +438,9 @@ int buttons_main(int argc, char *argv[]) if (oldhandler != NULL) { - lib_lowprintf("WARNING: oldhandler:%p is not NULL! " - "Button events may be lost or aliased!\n", - oldhandler); + lowsyslog("WARNING: oldhandler:%p is not NULL! " + "Button events may be lost or aliased!\n", + oldhandler); } } #endif @@ -468,11 +468,11 @@ int buttons_main(int argc, char *argv[]) flags = irqsave(); - /* Use lib_lowprintf() for compatibility with interrrupt handler + /* Use lowsyslog() for compatibility with interrrupt handler * output. */ - lib_lowprintf("POLL SET:%02x:\n", newset); + lowsyslog("POLL SET:%02x:\n", newset); show_buttons(g_oldset, newset); g_oldset = newset; irqrestore(flags); diff --git a/apps/examples/can/can.h b/apps/examples/can/can.h index 53a6b63ea..d9f9236f7 100644 --- a/apps/examples/can/can.h +++ b/apps/examples/can/can.h @@ -89,7 +89,7 @@ #ifdef CONFIG_CPP_HAVE_VARARGS # ifdef CONFIG_DEBUG -# define message(...) lib_rawprintf(__VA_ARGS__) +# define message(...) syslog(__VA_ARGS__) # define msgflush() # else # define message(...) printf(__VA_ARGS__) @@ -97,7 +97,7 @@ # endif #else # ifdef CONFIG_DEBUG -# define message lib_rawprintf +# define message syslog # define msgflush() # else # define message printf diff --git a/apps/examples/cdcacm/cdcacm.h b/apps/examples/cdcacm/cdcacm.h index 18570bff0..1b3b2511c 100644 --- a/apps/examples/cdcacm/cdcacm.h +++ b/apps/examples/cdcacm/cdcacm.h @@ -112,7 +112,7 @@ #ifdef CONFIG_CPP_HAVE_VARARGS # ifdef CONFIG_DEBUG -# define message(...) lib_lowprintf(__VA_ARGS__) +# define message(...) lowsyslog(__VA_ARGS__) # define msgflush() # else # define message(...) printf(__VA_ARGS__) @@ -120,7 +120,7 @@ # endif #else # ifdef CONFIG_DEBUG -# define message lib_lowprintf +# define message lowsyslog # define msgflush() # else # define message printf diff --git a/apps/examples/ostest/ostest_main.c b/apps/examples/ostest/ostest_main.c index aab1ff045..3e4197fdc 100644 --- a/apps/examples/ostest/ostest_main.c +++ b/apps/examples/ostest/ostest_main.c @@ -43,8 +43,11 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <signal.h> #include <string.h> #include <sched.h> +#include <errno.h> + #include <nuttx/init.h> #include "ostest.h" @@ -264,6 +267,31 @@ static int user_main(int argc, char *argv[]) } check_test_memory_usage(); + /* If retention of child status is enable, then suppress it for this task. + * This task may produce many, many children (especially if + * CONFIG_EXAMPLES_OSTEST_LOOPS) and it does not harvest their exit status. + * As a result, the test may fail inappropriately unless retention of + * child exit status is disabled. + * + * So basically, this tests that child status can be disabled, but cannot + * verify that status is retained correctly. + */ + +#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS) + { + struct sigaction sa; + int ret; + + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDWAIT; + ret = sigaction(SIGCHLD, &sa, NULL); + if (ret < 0) + { + printf("user_main: ERROR: sigaction failed: %d\n", errno); + } + } +#endif + /* Check environment variables */ #ifndef CONFIG_DISABLE_ENVIRON show_environment(true, true, true); diff --git a/apps/examples/ostest/waitpid.c b/apps/examples/ostest/waitpid.c index e53b49213..d45410265 100644 --- a/apps/examples/ostest/waitpid.c +++ b/apps/examples/ostest/waitpid.c @@ -113,14 +113,14 @@ static void waitpid_last(void) printf("waitpid_last: ERROR: PID %d waitpid failed: %d\n", g_waitpids[NCHILDREN-1], errcode); } - else if (stat_loc != RETURN_STATUS) + else if (WEXITSTATUS(stat_loc) != RETURN_STATUS) { printf("waitpid_last: ERROR: PID %d return status is %d, expected %d\n", - g_waitpids[NCHILDREN-1], stat_loc, RETURN_STATUS); + g_waitpids[NCHILDREN-1], WEXITSTATUS(stat_loc), RETURN_STATUS); } else { - printf("waitpid_last: PID %d waitpid succeeded with stat_loc=%d\n", + printf("waitpid_last: PID %d waitpid succeeded with stat_loc=%04x\n", g_waitpids[NCHILDREN-1], stat_loc); } } @@ -155,14 +155,14 @@ int waitpid_test(void) printf("waitpid_test: ERROR: PID %d wait returned PID %d\n", g_waitpids[0], ret); } - else if (stat_loc != RETURN_STATUS) + else if (WEXITSTATUS(stat_loc) != RETURN_STATUS) { printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n", - g_waitpids[0], stat_loc, RETURN_STATUS); + g_waitpids[0], WEXITSTATUS(stat_loc), RETURN_STATUS); } else { - printf("waitpid_test: PID %d waitpid succeeded with stat_loc=%d\n", + printf("waitpid_test: PID %d waitpid succeeded with stat_loc=%04x\n", g_waitpids[0], stat_loc); } @@ -246,14 +246,14 @@ int waitpid_test(void) int errcode = errno; printf("waitpid_test: ERROR: wait failed: %d\n", errcode); } - else if (stat_loc != RETURN_STATUS) + else if (WEXITSTATUS(stat_loc) != RETURN_STATUS) { printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n", - ret, stat_loc, RETURN_STATUS); + ret, WEXITSTATUS(stat_loc), RETURN_STATUS); } else { - printf("waitpid_test: PID %d wait succeeded with stat_loc=%d\n", + printf("waitpid_test: PID %d wait succeeded with stat_loc=%04x\n", ret, stat_loc); } diff --git a/apps/examples/poll/Kconfig b/apps/examples/poll/Kconfig index c52827496..f35a9200b 100644 --- a/apps/examples/poll/Kconfig +++ b/apps/examples/poll/Kconfig @@ -6,8 +6,26 @@ config EXAMPLES_POLL bool "Poll example" default n + depends on !NSH_BUILTIN_APPS ---help--- Enable the poll example if EXAMPLES_POLL + +config EXAMPLES_POLL_NOMAC + bool "Use Canned MAC Address" + default n + +config EXAMPLES_POLL_IPADDR + hex "Target IP address" + default 0x0a000002 + +config EXAMPLES_POLL_DRIPADDR + hex "Default Router IP address (Gateway)" + default 0x0a000001 + +config EXAMPLES_POLL_NETMASK + hex "Network Mask" + default 0xffffff00 + endif diff --git a/apps/examples/poll/poll_internal.h b/apps/examples/poll/poll_internal.h index b2400932e..759d23f1c 100644 --- a/apps/examples/poll/poll_internal.h +++ b/apps/examples/poll/poll_internal.h @@ -71,7 +71,7 @@ # undef HAVE_NETPOLL #endif -/* If debug is enabled, then use lib_rawprintf so that OS debug output and +/* If debug is enabled, then use syslog so that OS debug output and * the test output are synchronized. * * These macros will differ depending upon if the toolchain supports @@ -80,7 +80,7 @@ #ifdef CONFIG_CPP_HAVE_VARARGS # ifdef CONFIG_DEBUG -# define message(...) lib_rawprintf(__VA_ARGS__) +# define message(...) syslog(__VA_ARGS__) # define msgflush() # else # define message(...) printf(__VA_ARGS__) @@ -88,7 +88,7 @@ # endif #else # ifdef CONFIG_DEBUG -# define message lib_rawprintf +# define message syslog # define msgflush() # else # define message printf diff --git a/apps/examples/pwm/pwm.h b/apps/examples/pwm/pwm.h index 5c049a8f8..a6132ca8b 100644 --- a/apps/examples/pwm/pwm.h +++ b/apps/examples/pwm/pwm.h @@ -92,7 +92,7 @@ #ifdef CONFIG_CPP_HAVE_VARARGS # ifdef CONFIG_DEBUG -# define message(...) lib_rawprintf(__VA_ARGS__) +# define message(...) syslog(__VA_ARGS__) # define msgflush() # else # define message(...) printf(__VA_ARGS__) @@ -100,7 +100,7 @@ # endif #else # ifdef CONFIG_DEBUG -# define message lib_rawprintf +# define message syslog # define msgflush() # else # define message printf diff --git a/apps/examples/qencoder/qe.h b/apps/examples/qencoder/qe.h index 4c03689ab..3c20511ca 100644 --- a/apps/examples/qencoder/qe.h +++ b/apps/examples/qencoder/qe.h @@ -77,7 +77,7 @@ #ifdef CONFIG_CPP_HAVE_VARARGS # ifdef CONFIG_DEBUG -# define message(...) lib_rawprintf(__VA_ARGS__) +# define message(...) syslog(__VA_ARGS__) # define msgflush() # else # define message(...) printf(__VA_ARGS__) @@ -85,7 +85,7 @@ # endif #else # ifdef CONFIG_DEBUG -# define message lib_rawprintf +# define message syslog # define msgflush() # else # define message printf diff --git a/apps/examples/watchdog/watchdog.h b/apps/examples/watchdog/watchdog.h index dc2dea944..dd4daebb9 100644 --- a/apps/examples/watchdog/watchdog.h +++ b/apps/examples/watchdog/watchdog.h @@ -89,7 +89,7 @@ #ifdef CONFIG_CPP_HAVE_VARARGS # ifdef CONFIG_DEBUG -# define message(...) lib_rawprintf(__VA_ARGS__) +# define message(...) syslog(__VA_ARGS__) # define msgflush() # else # define message(...) printf(__VA_ARGS__) @@ -97,7 +97,7 @@ # endif #else # ifdef CONFIG_DEBUG -# define message lib_rawprintf +# define message syslog # define msgflush() # else # define message printf diff --git a/apps/include/nsh.h b/apps/include/nsh.h index 4b5a3cd31..8e469a555 100644 --- a/apps/include/nsh.h +++ b/apps/include/nsh.h @@ -1,7 +1,7 @@ /**************************************************************************** * apps/include/nsh.h * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -45,6 +45,31 @@ /**************************************************************************** * Pre-Processor Definitions ****************************************************************************/ +/* If a USB device is selected for the NSH console then we need to handle some + * special start-up conditions. + */ + +#undef HAVE_USB_CONSOLE +#if defined(CONFIG_USBDEV) + +/* Check for a PL2303 serial console. Use console device "/dev/console". */ + +# if defined(CONFIG_PL2303) && defined(CONFIG_PL2303_CONSOLE) +# define HAVE_USB_CONSOLE 1 + +/* Check for a CDC/ACM serial console. Use console device "/dev/console". */ + +# elif defined(CONFIG_CDCACM) && defined(CONFIG_CDCACM_CONSOLE) +# define HAVE_USB_CONSOLE 1 + +/* Check for a generic USB console. In this case, the USB console device + * must be provided in CONFIG_NSH_CONDEV. + */ + +# elif defined(CONFIG_NSH_USBCONSOLE) +# define HAVE_USB_CONSOLE 1 +# endif +#endif #if CONFIG_RR_INTERVAL > 0 # define SCHED_NSH SCHED_RR @@ -58,7 +83,8 @@ #ifdef __cplusplus #define EXTERN extern "C" -extern "C" { +extern "C" +{ #else #define EXTERN extern #endif @@ -83,35 +109,54 @@ extern "C" { * ****************************************************************************/ -EXTERN void nsh_initialize(void); +void nsh_initialize(void); /**************************************************************************** * Name: nsh_consolemain * * Description: * This interfaces maybe to called or started with task_start to start a - * single an NSH instance that operates on stdin and stdout (/dev/console). - * This function does not return. + * single an NSH instance that operates on stdin and stdout. This + * function does not return. * + * This function handles generic /dev/console character devices, or + * special USB console devices. The USB console requires some special + * operations to handle the cases where the session is lost when the + * USB device is unplugged and restarted when the USB device is plugged + * in again. + * * Input Parameters: - * Standard task start-up arguements. These are not used. argc may be + * Standard task start-up arguments. These are not used. argc may be * zero and argv may be NULL. * * Returned Values: * This function does not normally return. exit() is usually called to * terminate the NSH session. This function will return in the event of - * an error. In that case, a nonzero value is returned (1). + * an error. In that case, a nonzero value is returned (EXIT_FAILURE=1). * ****************************************************************************/ -EXTERN int nsh_consolemain(int argc, char *argv[]); +int nsh_consolemain(int argc, char *argv[]); -/* nsh_telnetstart() starts a telnet daemon that will allow multiple - * NSH connections via telnet. This function returns immediately after - * the daemon has been started. - */ +/**************************************************************************** + * Name: nsh_telnetstart + * + * Description: + * nsh_telnetstart() starts the Telnet daemon that will allow multiple + * NSH connections via Telnet. This function returns immediately after + * the daemon has been started. + * + * Input Parameters: + * None. All of the properties of the Telnet daemon are controlled by + * NuttX configuration setting. + * + * Returned Values: + * The task ID of the Telnet daemon was successfully started. A negated + * errno value will be returned on failure. + * + ****************************************************************************/ -EXTERN int nsh_telnetstart(void); +int nsh_telnetstart(void); #undef EXTERN #ifdef __cplusplus diff --git a/apps/include/usbmonitor.h b/apps/include/usbmonitor.h new file mode 100644 index 000000000..01fa060b0 --- /dev/null +++ b/apps/include/usbmonitor.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * apps/include/usbmonitor.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_USBMONITOR_H +#define __APPS_INCLUDE_USBMONITOR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#ifdef CONFIG_SYSTEM_USBMONITOR + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: usbmon_start and usbmon_stop + * + * Start and top the USB monitor daemon. These are normally controlled + * from the USB command line, but the ability to control these + * programmatically is also helpful (for example, so that the daemon is + * running before NSH starts). + * + * Input Parameters: + * Standard task parameters. These can be called or spawned. Since the + * return almost immediately, it is fine to just call the functions. The + * parameters are not used so you can pass 0 and NULL, respectivley; this + * is done this way so that these functions can be NSH builtin + * applications. + * + * Returned values: + * Standard task return values (zero meaning success). + * + **************************************************************************/ + +int usbmonitor_start(int argc, char **argv); +int usbmonitor_stop(int argc, char **argv); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SYSTEM_USBMONITOR */ +#endif /* __APPS_INCLUDE_USBMONITOR_H */ diff --git a/apps/nshlib/Kconfig b/apps/nshlib/Kconfig index f6a5aa045..92bc83cfd 100644 --- a/apps/nshlib/Kconfig +++ b/apps/nshlib/Kconfig @@ -292,6 +292,19 @@ config NSH_ROMFSETC endif if NSH_ROMFSETC + +config NSH_ROMFSRC + bool "Support ROMFS login script" + default n + ---help--- + The ROMFS start-up script will be executed excactly once. For + simple, persistence consoles (like a serial console). But with + other other kinds of consoles, there may be multiple, transient + sessions (such as Telnet and USB consoles). In these cases, you + may need another script that is executed at the beginning of each + session. Selecting this option enables support for such a login + script + config NSH_ROMFSMOUNTPT string "ROMFS mount point" default "/etc" @@ -308,6 +321,15 @@ config NSH_INITSCRIPT The default is init.d/rcS. This is a relative path and must not start with '/'. +config NSH_RCSCRIPT + string "Relative path to login script" + default ".nshrc" + depends on NSH_ROMFSRC + ---help--- + This is the relative path to the login script within the mountpoint. + The default is .nshrc. This is a relative path and must not + start with '/'. + config NSH_ROMFSDEVNO int "ROMFS block device minor number" default 0 @@ -406,7 +428,7 @@ config NSH_USBCONDEV readable/write-able USB driver such as: NSH_USBCONDEV="/dev/ttyACM0". -config UBSDEV_MINOR +config USBDEV_MINOR int "USB console device minor number" default 0 depends on NSH_USBCONSOLE @@ -414,8 +436,22 @@ config UBSDEV_MINOR If there are more than one USB devices, then a USB device minor number may also need to be provided. Default: 0 -menu "USB Trace Support" +comment "USB Trace Support" +config NSH_USBDEV_TRACE + bool "Enable Builtin USB Trace Support" + default n depends on USBDEV && (DEBUG || USBDEV_TRACE) + ---help--- + Enable builtin USB trace support in NSH. If selected, buffered USB + trace data will be presented each time a command is provided to NSH. + The USB trace data will be sent to the console unless DEBUG set or + unless you are using a USB console. In those cases, the trace data + will go to the SYSLOG device. + + If not enabled, the USB trace support can be provided by external + logic such as apps/system/usbmonitor. + +if NSH_USBDEV_TRACE config NSH_USBDEV_TRACEINIT bool "Show initialization events" @@ -447,7 +483,7 @@ config NSH_USBDEV_TRACEINTERRUPTS ---help--- Show interrupt-related events -endmenu +endif config NSH_CONDEV bool "Default console device" diff --git a/apps/nshlib/Makefile b/apps/nshlib/Makefile index 948f43d52..76cdac40d 100644 --- a/apps/nshlib/Makefile +++ b/apps/nshlib/Makefile @@ -1,7 +1,7 @@ ############################################################################ # apps/nshlib/Makefile # -# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. # Author: Gregory Nutt <gnutt@nuttx.org> # # Redistribution and use in source and binary forms, with or without @@ -39,9 +39,10 @@ include $(APPDIR)/Make.defs # NSH Library -ASRCS = -CSRCS = nsh_init.c nsh_parse.c nsh_console.c nsh_fscmds.c nsh_ddcmd.c \ - nsh_proccmds.c nsh_mmcmds.c nsh_envcmds.c nsh_dbgcmds.c +ASRCS = +CSRCS = nsh_init.c nsh_parse.c nsh_console.c nsh_script.c nsh_session.c +CSRCS += nsh_fscmds.c nsh_ddcmd.c nsh_proccmds.c nsh_mmcmds.c nsh_envcmds.c +CSRCS += nsh_dbgcmds.c ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) CSRCS += nsh_builtin.c diff --git a/apps/nshlib/README.txt b/apps/nshlib/README.txt index 006839628..a03f4a8ee 100644 --- a/apps/nshlib/README.txt +++ b/apps/nshlib/README.txt @@ -1025,12 +1025,16 @@ NSH-Specific Configuration Settings If there are more than one USB devices, then a USB device minor number may also need to be provided: - CONFIG_NSH_UBSDEV_MINOR + CONFIG_NSH_USBDEV_MINOR The minor device number of the USB device. Default: 0 - If USB tracing is enabled (CONFIG_USBDEV_TRACE), then NSH will - initialize USB tracing as requested by the following. Default: - Only USB errors are traced. + CONFIG_NSH_USBDEV_TRACE + If USB tracing is enabled (CONFIG_USBDEV_TRACE), then NSH can + be configured to show the buffered USB trace data afer each + NSH command: + + If CONFIG_NSH_USBDEV_TRACE is selected, then USB trace data + can be filtered as follows. Default: Only USB errors are traced. CONFIG_NSH_USBDEV_TRACEINIT Show initialization events diff --git a/apps/nshlib/nsh.h b/apps/nshlib/nsh.h index 64099a8df..23209dba5 100644 --- a/apps/nshlib/nsh.h +++ b/apps/nshlib/nsh.h @@ -1,7 +1,7 @@ /**************************************************************************** * apps/nshlib/nsh.h * - * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -93,7 +93,9 @@ # elif defined(CONFIG_CDCACM) && defined(CONFIG_CDCACM_CONSOLE) # define HAVE_USB_CONSOLE 1 -/* Check for other USB console. USB console device must be provided in CONFIG_NSH_CONDEV */ +/* Check for a generic USB console. In this case, the USB console device + * must be provided in CONFIG_NSH_CONDEV. + */ # elif defined(CONFIG_NSH_USBCONSOLE) # define HAVE_USB_CONSOLE 1 @@ -106,8 +108,8 @@ /* The default USB console device minor number is 0*/ -# ifndef CONFIG_NSH_UBSDEV_MINOR -# define CONFIG_NSH_UBSDEV_MINOR 0 +# ifndef CONFIG_NSH_USBDEV_MINOR +# define CONFIG_NSH_USBDEV_MINOR 0 # endif /* The default console device is always /dev/console */ @@ -118,43 +120,53 @@ /* USB trace settings */ -#ifdef CONFIG_NSH_USBDEV_TRACEINIT -# define TRACE_INIT_BITS (TRACE_INIT_BIT) -#else -# define TRACE_INIT_BITS (0) -#endif +# ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_NSH_USBDEV_TRACE +# endif -#define TRACE_ERROR_BITS (TRACE_DEVERROR_BIT|TRACE_CLSERROR_BIT) +# ifdef CONFIG_NSH_USBDEV_TRACE +# ifdef CONFIG_NSH_USBDEV_TRACEINIT +# define TRACE_INIT_BITS (TRACE_INIT_BIT) +# else +# define TRACE_INIT_BITS (0) +# endif -#ifdef CONFIG_NSH_USBDEV_TRACECLASS -# define TRACE_CLASS_BITS (TRACE_CLASS_BIT|TRACE_CLASSAPI_BIT|TRACE_CLASSSTATE_BIT) -#else -# define TRACE_CLASS_BITS (0) -#endif +# define TRACE_ERROR_BITS (TRACE_DEVERROR_BIT|TRACE_CLSERROR_BIT) -#ifdef CONFIG_NSH_USBDEV_TRACETRANSFERS -# define TRACE_TRANSFER_BITS (TRACE_OUTREQQUEUED_BIT|TRACE_INREQQUEUED_BIT|TRACE_READ_BIT|\ - TRACE_WRITE_BIT|TRACE_COMPLETE_BIT) -#else -# define TRACE_TRANSFER_BITS (0) -#endif +# ifdef CONFIG_NSH_USBDEV_TRACECLASS +# define TRACE_CLASS_BITS (TRACE_CLASS_BIT|TRACE_CLASSAPI_BIT|\ + TRACE_CLASSSTATE_BIT) +# else +# define TRACE_CLASS_BITS (0) +# endif -#ifdef CONFIG_NSH_USBDEV_TRACECONTROLLER -# define TRACE_CONTROLLER_BITS (TRACE_EP_BIT|TRACE_DEV_BIT) -#else -# define TRACE_CONTROLLER_BITS (0) -#endif +# ifdef CONFIG_NSH_USBDEV_TRACETRANSFERS +# define TRACE_TRANSFER_BITS (TRACE_OUTREQQUEUED_BIT|TRACE_INREQQUEUED_BIT|\ + TRACE_READ_BIT|TRACE_WRITE_BIT|\ + TRACE_COMPLETE_BIT) +# else +# define TRACE_TRANSFER_BITS (0) +# endif -#ifdef CONFIG_NSH_USBDEV_TRACEINTERRUPTS -# define TRACE_INTERRUPT_BITS (TRACE_INTENTRY_BIT|TRACE_INTDECODE_BIT|TRACE_INTEXIT_BIT) -#else -# define TRACE_INTERRUPT_BITS (0) -#endif +# ifdef CONFIG_NSH_USBDEV_TRACECONTROLLER +# define TRACE_CONTROLLER_BITS (TRACE_EP_BIT|TRACE_DEV_BIT) +# else +# define TRACE_CONTROLLER_BITS (0) +# endif -#define TRACE_BITSET (TRACE_INIT_BITS|TRACE_ERROR_BITS|TRACE_CLASS_BITS|\ - TRACE_TRANSFER_BITS|TRACE_CONTROLLER_BITS|TRACE_INTERRUPT_BITS) +# ifdef CONFIG_NSH_USBDEV_TRACEINTERRUPTS +# define TRACE_INTERRUPT_BITS (TRACE_INTENTRY_BIT|TRACE_INTDECODE_BIT|\ + TRACE_INTEXIT_BIT) +# else +# define TRACE_INTERRUPT_BITS (0) +# endif -#endif +# define TRACE_BITSET (TRACE_INIT_BITS|TRACE_ERROR_BITS|\ + TRACE_CLASS_BITS|TRACE_TRANSFER_BITS|\ + TRACE_CONTROLLER_BITS|TRACE_INTERRUPT_BITS) + +# endif /* CONFIG_NSH_USBDEV_TRACE */ +#endif /* HAVE_USB_CONSOLE */ /* If Telnet is selected for the NSH console, then we must configure * the resources used by the Telnet daemon and by the Telnet clients. @@ -232,40 +244,59 @@ # error "Mountpoint support is disabled" # undef CONFIG_NSH_ROMFSETC # endif + # if CONFIG_NFILE_DESCRIPTORS < 4 # error "Not enough file descriptors" # undef CONFIG_NSH_ROMFSETC # endif + # ifndef CONFIG_FS_ROMFS # error "ROMFS support not enabled" # undef CONFIG_NSH_ROMFSETC # endif + # ifndef CONFIG_NSH_ROMFSMOUNTPT # define CONFIG_NSH_ROMFSMOUNTPT "/etc" # endif -# ifdef CONFIG_NSH_INIT -# ifndef CONFIG_NSH_INITSCRIPT -# define CONFIG_NSH_INITSCRIPT "init.d/rcS" -# endif + +# ifndef CONFIG_NSH_INITSCRIPT +# define CONFIG_NSH_INITSCRIPT "init.d/rcS" # endif + # undef NSH_INITPATH # define NSH_INITPATH CONFIG_NSH_ROMFSMOUNTPT "/" CONFIG_NSH_INITSCRIPT + +# ifdef CONFIG_NSH_ROMFSRC +# ifndef CONFIG_NSH_RCSCRIPT +# define CONFIG_NSH_RCSCRIPT ".nshrc" +# endif + +# undef NSH_RCPATH +# define NSH_RCPATH CONFIG_NSH_ROMFSMOUNTPT "/" CONFIG_NSH_RCSCRIPT +# endif + # ifndef CONFIG_NSH_ROMFSDEVNO # define CONFIG_NSH_ROMFSDEVNO 0 # endif + # ifndef CONFIG_NSH_ROMFSSECTSIZE # define CONFIG_NSH_ROMFSSECTSIZE 64 # endif + # define NSECTORS(b) (((b)+CONFIG_NSH_ROMFSSECTSIZE-1)/CONFIG_NSH_ROMFSSECTSIZE) # define STR_RAMDEVNO(m) #m # define MKMOUNT_DEVNAME(m) "/dev/ram" STR_RAMDEVNO(m) # define MOUNT_DEVNAME MKMOUNT_DEVNAME(CONFIG_NSH_ROMFSDEVNO) + #else + +# undef CONFIG_NSH_ROMFSRC # undef CONFIG_NSH_ROMFSMOUNTPT -# undef CONFIG_NSH_INIT # undef CONFIG_NSH_INITSCRIPT +# undef CONFIG_NSH_RCSCRIPT # undef CONFIG_NSH_ROMFSDEVNO # undef CONFIG_NSH_ROMFSSECTSIZE + #endif /* This is the maximum number of arguments that will be accepted for a @@ -474,6 +505,12 @@ int nsh_usbconsole(void); #if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0 && !defined(CONFIG_NSH_DISABLESCRIPT) int nsh_script(FAR struct nsh_vtbl_s *vtbl, const char *cmd, const char *path); +#ifdef CONFIG_NSH_ROMFSETC +int nsh_initscript(FAR struct nsh_vtbl_s *vtbl); +#ifdef CONFIG_NSH_ROMFSRC +int nsh_loginscript(FAR struct nsh_vtbl_s *vtbl); +#endif +#endif #endif /* Architecture-specific initialization */ @@ -484,8 +521,10 @@ int nsh_archinitialize(void); # define nsh_archinitialize() (-ENOSYS) #endif -/* Message handler */ +/* Basic session and message handling */ +struct console_stdio_s; +int nsh_session(FAR struct console_stdio_s *pstate); int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline); /* Application interface */ @@ -515,10 +554,8 @@ void nsh_dumpbuffer(FAR struct nsh_vtbl_s *vtbl, const char *msg, /* USB debug support */ -#if defined(CONFIG_USBDEV_TRACE) && defined(HAVE_USB_CONSOLE) +#ifdef CONFIG_NSH_USBDEV_TRACE void nsh_usbtrace(void); -#else -# define nsh_usbtrace() #endif /* Shell command handlers */ diff --git a/apps/nshlib/nsh_consolemain.c b/apps/nshlib/nsh_consolemain.c index f05447a64..8be44f7aa 100644 --- a/apps/nshlib/nsh_consolemain.c +++ b/apps/nshlib/nsh_consolemain.c @@ -1,7 +1,7 @@ /**************************************************************************** * apps/nshlib/nsh_consolemain.c * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-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 @@ -47,6 +47,8 @@ #include "nsh.h" #include "nsh_console.h" +#ifndef HAVE_USB_CONSOLE + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -76,21 +78,25 @@ ****************************************************************************/ /**************************************************************************** - * Name: nsh_consolemain + * Name: nsh_consolemain (Normal character device version) * * Description: * This interfaces maybe to called or started with task_start to start a - * single an NSH instance that operates on stdin and stdout (/dev/console). - * This function does not return. + * single an NSH instance that operates on stdin and stdout. This + * function does not normally return (see below). * + * This version of nsh_consolmain handles generic /dev/console character + * devices (see nsh_usbdev.c for another version for special USB console + * devices). + * * Input Parameters: - * Standard task start-up arguements. These are not used. argc may be + * Standard task start-up arguments. These are not used. argc may be * zero and argv may be NULL. * * Returned Values: * This function does not normally return. exit() is usually called to * terminate the NSH session. This function will return in the event of - * an error. In that case, a nonzero value is returned (1). + * an error. In that case, a nonzero value is returned (EXIT_FAILURE=1). * ****************************************************************************/ @@ -101,70 +107,26 @@ int nsh_consolemain(int argc, char *argv[]) DEBUGASSERT(pstate); - /* If we are using a USB serial console, then we will have to wait for the - * USB to be connected to the host. - */ - -#ifdef HAVE_USB_CONSOLE - ret = nsh_usbconsole(); - DEBUGASSERT(ret == OK); -#endif - - /* Present a greeting */ - - fputs(g_nshgreeting, pstate->cn_outstream); - fflush(pstate->cn_outstream); - - /* Execute the startup script */ + /* Execute the start-up script */ #ifdef CONFIG_NSH_ROMFSETC - (void)nsh_script(&pstate->cn_vtbl, "init", NSH_INITPATH); + (void)nsh_initscript(&pstate->cn_vtbl); #endif - /* Then enter the command line parsing loop */ - - for (;;) - { - /* For the case of debugging the USB console... dump collected USB trace data */ + /* Initialize any USB tracing options that were requested */ - nsh_usbtrace(); - - /* Display the prompt string */ - - fputs(g_nshprompt, pstate->cn_outstream); - fflush(pstate->cn_outstream); - - /* Get the next line of input */ - - ret = readline(pstate->cn_line, CONFIG_NSH_LINELEN, - INSTREAM(pstate), OUTSTREAM(pstate)); - if (ret > 0) - { - /* Parse process the command */ - - (void)nsh_parse(&pstate->cn_vtbl, pstate->cn_line); - fflush(pstate->cn_outstream); - } +#ifdef CONFIG_NSH_USBDEV_TRACE + usbtrace_enable(TRACE_BITSET); +#endif - /* Readline normally returns the number of characters read, - * but will return 0 on end of file or a negative value - * if an error occurs. Either will cause the session to - * terminate. - */ + /* Execute the session */ - else - { - fprintf(pstate->cn_outstream, g_fmtcmdfailed, "nsh_consolemain", - "readline", NSH_ERRNO_OF(-ret)); - nsh_exit(&pstate->cn_vtbl, 1); - } - } + ret = nsh_session(pstate); - /* Clean up. We do not get here, but this is necessary to keep some - * compilers happy. But others will complain that this code is not - * reachable. - */ + /* Exit upon return */ - nsh_exit(&pstate->cn_vtbl, 0); - return OK; + nsh_exit(&pstate->cn_vtbl, ret); + return ret; } + +#endif /* !HAVE_USB_CONSOLE */ diff --git a/apps/nshlib/nsh_ddcmd.c b/apps/nshlib/nsh_ddcmd.c index 40a3710b1..e6ef2523c 100644 --- a/apps/nshlib/nsh_ddcmd.c +++ b/apps/nshlib/nsh_ddcmd.c @@ -545,7 +545,7 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } #endif - if (dd.skip < 0 || dd.skip > dd.nsectors) + if (dd.skip > dd.nsectors) { nsh_output(vtbl, g_fmtarginvalid, g_dd); goto errout_with_paths; diff --git a/apps/nshlib/nsh_fscmds.c b/apps/nshlib/nsh_fscmds.c index 1a9f2eb57..f47dca896 100644 --- a/apps/nshlib/nsh_fscmds.c +++ b/apps/nshlib/nsh_fscmds.c @@ -1,7 +1,7 @@ /**************************************************************************** * apps/nshlib/nsh_fscmds.c * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-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 @@ -1221,71 +1221,6 @@ int cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) #endif /**************************************************************************** - * Name: nsh_script - ****************************************************************************/ - -#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0 && !defined(CONFIG_NSH_DISABLESCRIPT) -int nsh_script(FAR struct nsh_vtbl_s *vtbl, const char *cmd, const char *path) -{ - char *fullpath; - FILE *stream; - char *buffer; - char *pret; - int ret = ERROR; - - /* The path to the script may be relative to the current working directory */ - - fullpath = nsh_getfullpath(vtbl, path); - if (!fullpath) - { - return ERROR; - } - - /* Get a reference to the common input buffer */ - - buffer = nsh_linebuffer(vtbl); - if (buffer) - { - /* Open the file containing the script */ - - stream = fopen(fullpath, "r"); - if (!stream) - { - nsh_output(vtbl, g_fmtcmdfailed, cmd, "fopen", NSH_ERRNO); - nsh_freefullpath(fullpath); - return ERROR; - } - - /* Loop, processing each command line in the script file (or - * until an error occurs) - */ - - do - { - /* Get the next line of input from the file */ - - fflush(stdout); - pret = fgets(buffer, CONFIG_NSH_LINELEN, stream); - if (pret) - { - /* Parse process the command. NOTE: this is recursive... - * we got to cmd_sh via a call to nsh_parse. So some - * considerable amount of stack may be used. - */ - - ret = nsh_parse(vtbl, buffer); - } - } - while (pret && ret == OK); - fclose(stream); - } - - nsh_freefullpath(fullpath); - return ret; -} -#endif - -/**************************************************************************** * Name: cmd_sh ****************************************************************************/ diff --git a/apps/nshlib/nsh_script.c b/apps/nshlib/nsh_script.c new file mode 100644 index 000000000..3aa698b31 --- /dev/null +++ b/apps/nshlib/nsh_script.c @@ -0,0 +1,195 @@ +/**************************************************************************** + * apps/nshlib/nsh_script.c + * + * Copyright (C) 2007-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 + * 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 "nsh.h" +#include "nsh_console.h" + +#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0 && !defined(CONFIG_NSH_DISABLESCRIPT) + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_script + * + * Description: + * Execute the NSH script at path. + * + ****************************************************************************/ + +int nsh_script(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, + FAR const char *path) +{ + char *fullpath; + FILE *stream; + char *buffer; + char *pret; + int ret = ERROR; + + /* The path to the script may be relative to the current working directory */ + + fullpath = nsh_getfullpath(vtbl, path); + if (!fullpath) + { + return ERROR; + } + + /* Get a reference to the common input buffer */ + + buffer = nsh_linebuffer(vtbl); + if (buffer) + { + /* Open the file containing the script */ + + stream = fopen(fullpath, "r"); + if (!stream) + { + nsh_output(vtbl, g_fmtcmdfailed, cmd, "fopen", NSH_ERRNO); + nsh_freefullpath(fullpath); + return ERROR; + } + + /* Loop, processing each command line in the script file (or + * until an error occurs) + */ + + do + { + /* Get the next line of input from the file */ + + fflush(stdout); + pret = fgets(buffer, CONFIG_NSH_LINELEN, stream); + if (pret) + { + /* Parse process the command. NOTE: this is recursive... + * we got to cmd_sh via a call to nsh_parse. So some + * considerable amount of stack may be used. + */ + + ret = nsh_parse(vtbl, buffer); + } + } + while (pret && ret == OK); + fclose(stream); + } + + nsh_freefullpath(fullpath); + return ret; +} + +/**************************************************************************** + * Name: nsh_initscript + * + * Description: + * Attempt to execute the configured initialization script. This script + * should be executed once when NSH starts. nsh_initscript is idempotent + * and may, however, be called multiple times (the script will be executed + * once. + * + ****************************************************************************/ + +#ifdef CONFIG_NSH_ROMFSETC +int nsh_initscript(FAR struct nsh_vtbl_s *vtbl) +{ + static bool initialized; + bool already; + int ret = OK; + + /* Atomic test and set of the initialized flag */ + + sched_lock(); + already = initialized; + initialized = true; + sched_unlock(); + + /* If we have not already executed the init script, then do so now */ + + if (!already) + { + ret = nsh_script(vtbl, "init", NSH_INITPATH); + } + + return ret; +} + +/**************************************************************************** + * Name: nsh_loginscript + * + * Description: + * Attempt to execute the configured login script. This script + * should be executed when each NSH session starts. + * + ****************************************************************************/ + +#ifdef CONFIG_NSH_ROMFSRC +int nsh_loginscript(FAR struct nsh_vtbl_s *vtbl) +{ + return nsh_script(vtbl, "login", NSH_RCPATH); +} +#endif +#endif /* CONFIG_NSH_ROMFSETC */ + +#endif /* CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0 && !CONFIG_NSH_DISABLESCRIPT */ diff --git a/apps/nshlib/nsh_session.c b/apps/nshlib/nsh_session.c new file mode 100644 index 000000000..8079b2de5 --- /dev/null +++ b/apps/nshlib/nsh_session.c @@ -0,0 +1,163 @@ +/**************************************************************************** + * apps/nshlib/nsh_session.c + * + * Copyright (C) 2007-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 + * 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 Gregory Nutt 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 <stdio.h> +#include <stdlib.h> + +#include <apps/readline.h> + +#include "nsh.h" +#include "nsh_console.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_session + * + * Description: + * This is the common session logic or any NSH session. This function + * return when an error reading from the input stream occurs, presumably + * signaling the end of the session. + * + * This function: + * - Executes the NSH logic script + * - Presents a greeting + * - Then provides a prompt then gets and processes the command line. + * - This continues until an error occurs, then the session returns. + * + * Input Parameters: + * pstate - Abstracts the underlying session. + * + * Returned Values: + * EXIT_SUCESS or EXIT_FAILURE is returned. + * + ****************************************************************************/ + +int nsh_session(FAR struct console_stdio_s *pstate) +{ + int ret; + + DEBUGASSERT(pstate); + + /* Present a greeting */ + + fputs(g_nshgreeting, pstate->cn_outstream); + fflush(pstate->cn_outstream); + + /* Execute the login script */ + +#ifdef CONFIG_NSH_ROMFSRC + (void)nsh_loginscript(&pstate->cn_vtbl); +#endif + + /* Then enter the command line parsing loop */ + + for (;;) + { + /* For the case of debugging the USB console... dump collected USB trace data */ + +#ifdef CONFIG_NSH_USBDEV_TRACE + nsh_usbtrace(); +#endif + + /* Display the prompt string */ + + fputs(g_nshprompt, pstate->cn_outstream); + fflush(pstate->cn_outstream); + + /* Get the next line of input */ + + ret = readline(pstate->cn_line, CONFIG_NSH_LINELEN, + INSTREAM(pstate), OUTSTREAM(pstate)); + if (ret > 0) + { + /* Parse process the command */ + + (void)nsh_parse(&pstate->cn_vtbl, pstate->cn_line); + fflush(pstate->cn_outstream); + } + + /* Readline normally returns the number of characters read, + * but will return 0 on end of file or a negative value + * if an error occurs. Either will cause the session to + * terminate. + */ + + else + { + fprintf(pstate->cn_outstream, g_fmtcmdfailed, "nsh_session", + "readline", NSH_ERRNO_OF(-ret)); + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } + } + + /* We do not get here, but this is necessary to keep some compilers happy. + * But others will complain that this code is not reachable. + */ + + return EXIT_SUCCESS; +} diff --git a/apps/nshlib/nsh_telnetd.c b/apps/nshlib/nsh_telnetd.c index 478935d7f..76ed81086 100644 --- a/apps/nshlib/nsh_telnetd.c +++ b/apps/nshlib/nsh_telnetd.c @@ -1,7 +1,7 @@ /**************************************************************************** * apps/nshlib/nsh_telnetd.c * - * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -198,15 +198,29 @@ int nsh_telnetmain(int argc, char *argv[]) } #endif /* CONFIG_NSH_TELNET_LOGIN */ + /* The following logic mostly the same as the login in nsh_session.c. It + * differs only in that gets() is called to get the command instead of + * readline(). + */ + /* Present the NSH greeting */ fputs(g_nshgreeting, pstate->cn_outstream); fflush(pstate->cn_outstream); - /* Execute the startup script */ + /* Execute the startup script. If standard console is also defined, then + * we will not bother with the initscript here (although it is safe to + * call nshinitscript multiple times). + */ #if defined(CONFIG_NSH_ROMFSETC) && !defined(CONFIG_NSH_CONSOLE) - (void)nsh_script(&pstate->cn_vtbl, "init", NSH_INITPATH); + (void)nsh_initscript(&pstate->cn_vtbl); +#endif + + /* Execute the login script */ + +#ifdef CONFIG_NSH_ROMFSRC + (void)nsh_loginscript(&pstate->cn_vtbl); #endif /* Then enter the command line parsing loop */ @@ -261,8 +275,8 @@ int nsh_telnetmain(int argc, char *argv[]) * NuttX configuration setting. * * Returned Values: - * Zero if the Telnet daemon was successfully started. A negated errno - * value will be returned on failure. + * The task ID of the Telnet daemon was successfully started. A negated + * errno value will be returned on failure. * ****************************************************************************/ @@ -271,6 +285,15 @@ int nsh_telnetstart(void) struct telnetd_config_s config; int ret; + /* Initialize any USB tracing options that were requested. If standard + * console is also defined, then we will defer this step to the standard + * console. + */ + +#if defined(CONFIG_NSH_USBDEV_TRACE) && !defined(CONFIG_NSH_CONSOLE) + usbtrace_enable(TRACE_BITSET); +#endif + /* Configure the telnet daemon */ config.d_port = HTONS(CONFIG_NSH_TELNETD_PORT); diff --git a/apps/nshlib/nsh_usbdev.c b/apps/nshlib/nsh_usbdev.c index 3d123532a..193fe0d79 100644 --- a/apps/nshlib/nsh_usbdev.c +++ b/apps/nshlib/nsh_usbdev.c @@ -1,7 +1,7 @@ /**************************************************************************** * apps/nshlib/nsh_usbdev.c * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -55,15 +55,20 @@ #endif #include "nsh.h" - -#ifdef CONFIG_USBDEV +#include "nsh_console.h" /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ - -#if defined(CONFIG_DEBUG) || defined(CONFIG_NSH_USBCONSOLE) -# define trmessage lib_lowprintf +/* Output USB trace data to the console device using printf() unless (1) + * debug is enabled, then we want to keep the trace output in sync with the + * debug output by using syslog()we are using a USB console. In that case, + * we don't want the trace output on the USB console; let's try sending it + * a SYSLOG device (hopefully one is set up!) + */ + +#if defined(CONFIG_DEBUG) || defined(HAVE_USB_CONSOLE) +# define trmessage syslog #else # define trmessage printf #endif @@ -92,7 +97,15 @@ * Name: nsh_tracecallback ****************************************************************************/ -#ifdef CONFIG_USBDEV_TRACE +/**************************************************************************** + * Name: nsh_tracecallback + * + * Description: + * This is part of the USB trace logic + * + ****************************************************************************/ + +#ifdef CONFIG_NSH_USBDEV_TRACE static int nsh_tracecallback(struct usbtrace_s *trace, void *arg) { usbtrace_trprintf((trprintf_t)trmessage, trace->event, trace->value); @@ -101,45 +114,103 @@ static int nsh_tracecallback(struct usbtrace_s *trace, void *arg) #endif /**************************************************************************** - * Public Functions + * Name: nsh_configstdio + * + * Description: + * Configure standard I/O + * ****************************************************************************/ +#ifdef HAVE_USB_CONSOLE +static void nsh_configstdio(int fd) +{ + /* Make sure the stdin, stdout, and stderr are closed */ + + (void)fclose(stdin); + (void)fclose(stdout); + (void)fclose(stderr); + + /* Dup the fd to create standard fd 0-2 */ + + (void)dup2(fd, 0); + (void)dup2(fd, 1); + (void)dup2(fd, 2); + + /* fdopen to get the stdin, stdout and stderr streams. The following logic depends + * on the fact that the library layer will allocate FILEs in order. And since + * we closed stdin, stdout, and stderr above, that is what we should get. + * + * fd = 0 is stdin (read-only) + * fd = 1 is stdout (write-only, append) + * fd = 2 is stderr (write-only, append) + */ + + (void)fdopen(0, "r"); + (void)fdopen(1, "a"); + (void)fdopen(2, "a"); +} +#endif + /**************************************************************************** - * Name: nsh_usbconsole + * Name: nsh_nullstdio + * + * Description: + * Use /dev/null for standard I/O + * ****************************************************************************/ #ifdef HAVE_USB_CONSOLE -int nsh_usbconsole(void) +static int nsh_nullstdio(void) { - char inch; - ssize_t nbytes; - int nlc; int fd; - int ret; - /* Initialize any USB tracing options that were requested */ + /* Open /dev/null for read/write access */ -#ifdef CONFIG_USBDEV_TRACE - usbtrace_enable(TRACE_BITSET); + fd = open("/dev/null", O_RDWR); + if (fd >= 0) + { + /* Configure standard I/O to use /dev/null */ + + nsh_configstdio(fd); + + /* We can close the original file descriptor now (unless it was one of + * 0-2) + */ + + if (fd > 2) + { + close(fd); + } + + return OK; + } + + return fd; +} #endif +/**************************************************************************** + * Name: nsh_waitusbready + * + * Description: + * Wait for the USB console device to be ready + * + ****************************************************************************/ + +#ifdef HAVE_USB_CONSOLE +static int nsh_waitusbready(void) +{ + char inch; + ssize_t nbytes; + int nlc; + int fd; + /* Don't start the NSH console until the console device is ready. Chances * are, we get here with no functional console. The USB console will not * be available until the device is connected to the host and until the * host-side application opens the connection. */ - /* Initialize the USB serial driver */ - -#if defined(CONFIG_PL2303) || defined(CONFIG_CDCACM) -#ifdef CONFIG_CDCACM - ret = cdcacm_initialize(CONFIG_NSH_UBSDEV_MINOR, NULL); -#else - ret = usbdev_serialinitialize(CONFIG_NSH_UBSDEV_MINOR); -#endif - DEBUGASSERT(ret == OK); -#endif - /* Open the USB serial device for read/write access */ do @@ -193,17 +264,9 @@ int nsh_usbconsole(void) } while (nlc < 3); - /* Make sure the stdin, stdout, and stderr are closed */ - - (void)fclose(stdin); - (void)fclose(stdout); - (void)fclose(stderr); + /* Configure standard I/O */ - /* Dup the fd to create standard fd 0-2 */ - - (void)dup2(fd, 0); - (void)dup2(fd, 1); - (void)dup2(fd, 2); + nsh_configstdio(fd); /* We can close the original file descriptor now (unless it was one of 0-2) */ @@ -212,32 +275,117 @@ int nsh_usbconsole(void) close(fd); } - /* fdopen to get the stdin, stdout and stderr streams. The following logic depends - * on the fact that the library layer will allocate FILEs in order. And since - * we closed stdin, stdout, and stderr above, that is what we should get. - * - * fd = 0 is stdin (read-only) - * fd = 1 is stdout (write-only, append) - * fd = 2 is stderr (write-only, append) - */ - - (void)fdopen(0, "r"); - (void)fdopen(1, "a"); - (void)fdopen(2, "a"); return OK; } +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_consolemain (USB console version) + * + * Description: + * This interfaces maybe to called or started with task_start to start a + * single an NSH instance that operates on stdin and stdout. This + * function does not return. + * + * This function handles generic /dev/console character devices, or + * special USB console devices. The USB console requires some special + * operations to handle the cases where the session is lost when the + * USB device is unplugged and restarted when the USB device is plugged + * in again. + * + * Input Parameters: + * Standard task start-up arguments. These are not used. argc may be + * zero and argv may be NULL. + * + * Returned Values: + * This function does not return nor does it ever exit (unless the user + * executes the NSH exit command). + * + ****************************************************************************/ + +#ifdef HAVE_USB_CONSOLE +int nsh_consolemain(int argc, char *argv[]) +{ + FAR struct console_stdio_s *pstate = nsh_newconsole(); + int ret; + + DEBUGASSERT(pstate); + + /* Initialize any USB tracing options that were requested */ + +#ifdef CONFIG_NSH_USBDEV_TRACE + usbtrace_enable(TRACE_BITSET); +#endif + + /* Initialize the USB serial driver */ -#endif /* HAVE_USB_CONSOLE */ +#if defined(CONFIG_PL2303) || defined(CONFIG_CDCACM) +#ifdef CONFIG_CDCACM + ret = cdcacm_initialize(CONFIG_NSH_USBDEV_MINOR, NULL); +#else + ret = usbdev_serialinitialize(CONFIG_NSH_USBDEV_MINOR); +#endif + DEBUGASSERT(ret == OK); +#endif + + /* Configure to use /dev/null if we do not have a valid console. */ + +#ifndef CONFIG_DEV_CONSOLE + (void)nsh_nullstdio(); +#endif + + /* Execute the one-time start-up script (output may go to /dev/null) */ + +#ifdef CONFIG_NSH_ROMFSETC + (void)nsh_initscript(&pstate->cn_vtbl); +#endif + + /* Now loop, executing creating a session for each USB connection */ + + for (;;) + { + /* Wait for the USB to be connected to the host and switch + * standard I/O to the USB serial device. + */ + + ret = nsh_waitusbready(); + DEBUGASSERT(ret == OK); + + /* Execute the session */ + + (void)nsh_session(pstate); + + /* Switch to /dev/null because we probably no longer have a + * valid console device. + */ + + (void)nsh_nullstdio(); + } +} +#endif /**************************************************************************** * Name: nsh_usbtrace + * + * Description: + * The function is called from the nsh_session() to dump USB data to the + * SYSLOG device. + * + * Input Parameters: + * None + * + * Returned Values: + * None + * ****************************************************************************/ -#if defined(CONFIG_USBDEV_TRACE) && defined(HAVE_USB_CONSOLE) +#ifdef CONFIG_NSH_USBDEV_TRACE void nsh_usbtrace(void) { (void)usbtrace_enumerate(nsh_tracecallback, NULL); } #endif - -#endif /* CONFIG_USBDEV */ diff --git a/apps/px4/tests/tests.h b/apps/px4/tests/tests.h index cc3f5493a..c02ea6808 100644 --- a/apps/px4/tests/tests.h +++ b/apps/px4/tests/tests.h @@ -48,7 +48,7 @@ #ifdef CONFIG_CPP_HAVE_VARARGS # ifdef CONFIG_DEBUG -# define message(...) lib_rawprintf(__VA_ARGS__) +# define message(...) lowsyslog(__VA_ARGS__) # define msgflush() # else # define message(...) printf(__VA_ARGS__) @@ -56,7 +56,7 @@ # endif #else # ifdef CONFIG_DEBUG -# define message lib_rawprintf +# define message lowsyslog # define msgflush() # else # define message printf diff --git a/apps/px4io/mixer.cpp b/apps/px4io/mixer.cpp index 740d8aeb0..93bd4470f 100644 --- a/apps/px4io/mixer.cpp +++ b/apps/px4io/mixer.cpp @@ -195,7 +195,7 @@ mixer_tick(void) rc_channel_data[THROTTLE] = 1000; } - // lib_lowprintf("Tmin: %d Ttrim: %d Tmax: %d T: %d \n", + // lowsyslog("Tmin: %d Ttrim: %d Tmax: %d T: %d \n", // (int)(system_state.rc_min[THROTTLE]), (int)(system_state.rc_trim[THROTTLE]), // (int)(system_state.rc_max[THROTTLE]), (int)(rc_channel_data[THROTTLE])); @@ -207,7 +207,7 @@ mixer_tick(void) // XXX builtin failsafe would activate here control_count = 0; } - //lib_lowprintf("R: %d P: %d Y: %d T: %d \n", control_values[0], control_values[1], control_values[2], control_values[3]); + //lowsyslog("R: %d P: %d Y: %d T: %d \n", control_values[0], control_values[1], control_values[2], control_values[3]); /* this is for multicopters, etc. where manual override does not make sense */ } else { diff --git a/apps/px4io/px4io.c b/apps/px4io/px4io.c index e50022a0c..2683ff1f6 100644 --- a/apps/px4io/px4io.c +++ b/apps/px4io/px4io.c @@ -143,7 +143,7 @@ int user_start(int argc, char *argv[]) hrt_call_every(&serial_dma_call, 1000, 1000, (hrt_callout)stm32_serial_dma_poll, NULL); /* print some startup info */ - debug("\nPX4IO: starting\n"); + lowsyslog("\nPX4IO: starting\n"); /* default all the LEDs to off while we start */ LED_AMBER(false); @@ -167,7 +167,7 @@ int user_start(int argc, char *argv[]) NULL); struct mallinfo minfo = mallinfo(); - debug("free %u largest %u\n", minfo.mxordblk, minfo.fordblks); + lowsyslog("free %u largest %u\n", minfo.mxordblk, minfo.fordblks); debug("debug_level=%u\n", (unsigned)debug_level); @@ -202,3 +202,4 @@ int user_start(int argc, char *argv[]) } } } + diff --git a/apps/px4io/px4io.h b/apps/px4io/px4io.h index 9c5989df7..6944776a9 100644 --- a/apps/px4io/px4io.h +++ b/apps/px4io/px4io.h @@ -58,7 +58,7 @@ #ifdef DEBUG # include <debug.h> -# define debug(fmt, args...) lib_lowprintf(fmt "\n", ##args) +# define debug(fmt, args...) lowsyslog(fmt "\n", ##args) #else # define debug(fmt, args...) do {} while(0) #endif diff --git a/apps/system/Kconfig b/apps/system/Kconfig index d4d434665..6c8651088 100644 --- a/apps/system/Kconfig +++ b/apps/system/Kconfig @@ -34,3 +34,7 @@ endmenu menu "Sysinfo" source "$APPSDIR/system/sysinfo/Kconfig" endmenu + +menu "USB Monitor" +source "$APPSDIR/system/usbmonitor/Kconfig" +endmenu diff --git a/apps/system/Make.defs b/apps/system/Make.defs index 3d10f84e5..3c679f112 100644 --- a/apps/system/Make.defs +++ b/apps/system/Make.defs @@ -66,3 +66,6 @@ ifeq ($(CONFIG_SYSTEM_SYSINFO),y) CONFIGURED_APPS += system/sysinfo endif +ifeq ($(CONFIG_SYSTEM_USBMONITOR),y) +CONFIGURED_APPS += system/usbmonitor +endif diff --git a/apps/system/Makefile b/apps/system/Makefile index 057fbcf77..f39eedec4 100644 --- a/apps/system/Makefile +++ b/apps/system/Makefile @@ -37,7 +37,7 @@ # Sub-directories containing system task -SUBDIRS = free i2c install readline poweroff ramtron sdcard sysinfo +SUBDIRS = free i2c install readline poweroff ramtron sdcard sysinfo usbmonitor # Create the list of installed runtime modules (INSTALLED_DIRS) diff --git a/apps/system/free/README.txt b/apps/system/free/README.txt deleted file mode 100644 index 1c2d380d4..000000000 --- a/apps/system/free/README.txt +++ /dev/null @@ -1,6 +0,0 @@ - -This application provides UNIX style memory free information. - - Source: NuttX - Author: Gregory Nutt <gnutt@nuttx.org> - Date: 17. March 2011 diff --git a/apps/system/readline/readline.c b/apps/system/readline/readline.c index f64049ed7..bac7eee8c 100644 --- a/apps/system/readline/readline.c +++ b/apps/system/readline/readline.c @@ -132,23 +132,33 @@ static inline int readline_rawgetc(int infd) nread = read(infd, &buffer, 1); - /* Return EOF if the end of file (0) or error (-1) occurs. */ + /* Check for end-of-file. */ - if (nread < 1) + if (nread == 0) + { + /* Return zero on end-of-file */ + + return 0; + } + + /* Check if an error occurred */ + + else if (nread < 0) { /* EINTR is not really an error; it simply means that a signal we * received while watiing for intput. */ - if (nread == 0 || errno != EINTR) + int errcode = errno; + if (errcode != EINTR) { - return EOF; + return -errcode; } } } while (nread < 1); - /* On success, returnt he character that was read */ + /* On success, return the character that was read */ return (int)buffer; } @@ -275,9 +285,29 @@ ssize_t readline(FAR char *buf, int buflen, FILE *instream, FILE *outstream) int ch = readline_rawgetc(infd); + /* Check for end-of-file or read error */ + + if (ch <= 0) + { + /* Did we already received some data? */ + + if (nch > 0) + { + /* Yes.. Terminate the line (which might be zero length) + * and return the data that was received. The end-of-file + * or error condition will be reported next time. + */ + + buf[nch] = '\0'; + return nch; + } + + return ch; + } + /* Are we processing a VT100 escape sequence */ - if (escape) + else if (escape) { /* Yes, is it an <esc>[, 3 byte sequence */ @@ -366,16 +396,6 @@ ssize_t readline(FAR char *buf, int buflen, FILE *instream, FILE *outstream) return nch; } - /* Check for end-of-file */ - - else if (ch == EOF) - { - /* Terminate the line (which might be zero length) */ - - buf[nch] = '\0'; - return nch; - } - /* Otherwise, check if the character is printable and, if so, put the * character in the line buffer */ diff --git a/apps/system/usbmonitor/Kconfig b/apps/system/usbmonitor/Kconfig new file mode 100644 index 000000000..bde97de15 --- /dev/null +++ b/apps/system/usbmonitor/Kconfig @@ -0,0 +1,67 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +config SYSTEM_USBMONITOR + bool "USB Monitor" + default n + depends on USBDEV && USBDEV_TRACE && SYSLOG + ---help--- + If USB device tracing is enabled (USBDEV_TRACE), then this option + will select the USB monitor. The USB monitor is a daemon that will + periodically collect the buffered USB trace data and dump it to the + SYSLOG device. + +if SYSTEM_USBMONITOR + +config SYSTEM_USBMONITOR_STACKSIZE + int "USB Monitor daemon stack size" + default 2048 + ---help--- + The stack size to use the the USB monitor daemon. Default: 2048 + +config SYSTEM_USBMONITOR_PRIORITY + int "USB Monitor daemon priority" + default 50 + ---help--- + The priority to use the the USB monitor daemon. Default: 50 + +config SYSTEM_USBMONITOR_INTERVAL + int "USB Monitor dump frequency" + default 2 + ---help--- + The rate in seconds that the USB monitor will wait before dumping + the next set of buffered USB trace data. Default: 2 seconds. + +config SYSTEM_USBMONITOR_TRACEINIT + bool "Show initialization events" + default n + ---help--- + Show initialization events + +config SYSTEM_USBMONITOR_TRACECLASS + bool "Show class driver events" + default n + ---help--- + Show class driver events + +config SYSTEM_USBMONITOR_TRACETRANSFERS + bool "Show data transfer events" + default n + ---help--- + Show data transfer events + +config SYSTEM_USBMONITOR_TRACECONTROLLER + bool "Show controller events" + default n + ---help--- + Show controller events + +config SYSTEM_USBMONITOR_TRACEINTERRUPTS + bool "Show interrupt-related events" + default n + ---help--- + Show interrupt-related events +endif + diff --git a/apps/system/usbmonitor/Makefile b/apps/system/usbmonitor/Makefile new file mode 100644 index 000000000..56b6ccee1 --- /dev/null +++ b/apps/system/usbmonitor/Makefile @@ -0,0 +1,117 @@ +############################################################################ +# apps/system/usbmonitor/Makefile +# +# Copyright (C) 2013 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt <gnutt@nuttx.org> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +ifeq ($(WINTOOL),y) +INCDIROPT = -w +endif + +# USB Monitor Application + +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 768 + +ASRCS = +CSRCS = usbmonitor.c + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ROOTDEPPATH = --dep-path . + +# Common build + +VPATH = + +all: .built +.PHONY: context depend clean distclean + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + $(Q) touch .built + +# Register application + +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) +$(BUILTIN_REGISTRY)$(DELIM)usbmonitor_start.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,"usbmon_start",$(PRIORITY),$(STACKSIZE),usbmonitor_start) + +$(BUILTIN_REGISTRY)$(DELIM)usbmonitor_stop.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,"usbmon_stop",$(PRIORITY),$(STACKSIZE),usbmonitor_stop) + +context: $(BUILTIN_REGISTRY)$(DELIM)usbmonitor_start.bdat $(BUILTIN_REGISTRY)$(DELIM)usbmonitor_stop.bdat +else +context: +endif + +# Create dependencies + +.depend: Makefile $(SRCS) + $(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/apps/system/usbmonitor/usbmonitor.c b/apps/system/usbmonitor/usbmonitor.c new file mode 100644 index 000000000..cde945b43 --- /dev/null +++ b/apps/system/usbmonitor/usbmonitor.c @@ -0,0 +1,234 @@ +/**************************************************************************** + * apps/system/usbmonitor/usbmonitor.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <nuttx/progmem.h> + +#include <sys/types.h> +#include <stdbool.h> +#include <unistd.h> +#include <sched.h> +#include <syslog.h> +#include <errno.h> + +#include <nuttx/usb/usbdev_trace.h> + +#ifdef CONFIG_SYSTEM_USBMONITOR + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define USBMON_PREFIX "USB Monitor: " + +/* Configuration ************************************************************/ + +#ifndef CONFIG_SYSTEM_USBMONITOR_STACKSIZE +# define CONFIG_SYSTEM_USBMONITOR_STACKSIZE 2048 +#endif + +#ifndef CONFIG_SYSTEM_USBMONITOR_PRIORITY +# define CONFIG_SYSTEM_USBMONITOR_PRIORITY 50 +#endif + +#ifndef CONFIG_SYSTEM_USBMONITOR_INTERVAL +# define CONFIG_SYSTEM_USBMONITOR_INTERVAL 2 +#endif + +#ifdef CONFIG_SYSTEM_USBMONITOR_TRACEINIT +# define TRACE_INIT_BITS (TRACE_INIT_BIT) +#else +# define TRACE_INIT_BITS (0) +#endif + +#define TRACE_ERROR_BITS (TRACE_DEVERROR_BIT|TRACE_CLSERROR_BIT) + +#ifdef CONFIG_SYSTEM_USBMONITOR_TRACECLASS +# define TRACE_CLASS_BITS (TRACE_CLASS_BIT|TRACE_CLASSAPI_BIT|\ + TRACE_CLASSSTATE_BIT) +#else +# define TRACE_CLASS_BITS (0) +#endif + +#ifdef CONFIG_SYSTEM_USBMONITOR_TRACETRANSFERS +# define TRACE_TRANSFER_BITS (TRACE_OUTREQQUEUED_BIT|TRACE_INREQQUEUED_BIT|\ + TRACE_READ_BIT|TRACE_WRITE_BIT|\ + TRACE_COMPLETE_BIT) +#else +# define TRACE_TRANSFER_BITS (0) +#endif + +#ifdef CONFIG_SYSTEM_USBMONITOR_TRACECONTROLLER +# define TRACE_CONTROLLER_BITS (TRACE_EP_BIT|TRACE_DEV_BIT) +#else +# define TRACE_CONTROLLER_BITS (0) +#endif + +#ifdef CONFIG_SYSTEM_USBMONITOR_TRACEINTERRUPTS +# define TRACE_INTERRUPT_BITS (TRACE_INTENTRY_BIT|TRACE_INTDECODE_BIT|\ + TRACE_INTEXIT_BIT) +#else +# define TRACE_INTERRUPT_BITS (0) +#endif + +#define TRACE_BITSET (TRACE_INIT_BITS|TRACE_ERROR_BITS|\ + TRACE_CLASS_BITS|TRACE_TRANSFER_BITS|\ + TRACE_CONTROLLER_BITS|TRACE_INTERRUPT_BITS) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct usbmon_state_s +{ + volatile bool started; + volatile bool stop; + pid_t pid; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct usbmon_state_s g_usbmonitor; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int usbmonitor_tracecallback(struct usbtrace_s *trace, void *arg) +{ + usbtrace_trprintf((trprintf_t)syslog, trace->event, trace->value); + return 0; +} + +static int usbmonitor_daemon(int argc, char **argv) +{ + syslog(USBMON_PREFIX "Running: %d\n", g_usbmonitor.pid); + + /* Loop until we detect that there is a request to stop. */ + + while (!g_usbmonitor.stop) + { + sleep(CONFIG_SYSTEM_USBMONITOR_INTERVAL); + (void)usbtrace_enumerate(usbmonitor_tracecallback, NULL); + } + + /* Stopped */ + + g_usbmonitor.stop = false; + g_usbmonitor.started = false; + syslog(USBMON_PREFIX "Stopped: %d\n", g_usbmonitor.pid); + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int usbmonitor_start(int argc, char **argv) +{ + /* Has the monitor already started? */ + + sched_lock(); + if (!g_usbmonitor.started) + { + int ret; + + /* No.. start it now */ + + /* First, initialize any USB tracing options that were requested */ + + usbtrace_enable(TRACE_BITSET); + + /* Then start the USB monitoring daemon */ + + g_usbmonitor.started = true; + g_usbmonitor.stop = false; + + ret = TASK_CREATE("USB Monitor", CONFIG_SYSTEM_USBMONITOR_PRIORITY, + CONFIG_SYSTEM_USBMONITOR_STACKSIZE, + (main_t)usbmonitor_daemon, (const char **)NULL); + if (ret < 0) + { + int errcode = errno; + syslog(USBMON_PREFIX + "ERROR: Failed to start the USB monitor: %d\n", + errcode); + } + else + { + g_usbmonitor.pid = ret; + syslog(USBMON_PREFIX "Started: %d\n", g_usbmonitor.pid); + } + + sched_unlock(); + return 0; + } + + sched_unlock(); + syslog(USBMON_PREFIX "%s: %d\n", + g_usbmonitor.stop ? "Stopping" : "Running", g_usbmonitor.pid); + return 0; +} + +int usbmonitor_stop(int argc, char **argv) +{ + /* Has the monitor already started? */ + + if (g_usbmonitor.started) + { + /* Stop the USB monitor. The next time the monitor wakes up, + * it will see the the stop indication and will exist. + */ + + syslog(USBMON_PREFIX "Stopping: %d\n", g_usbmonitor.pid); + g_usbmonitor.stop = true; + + /* We may as well disable tracing since there is no listener */ + + usbtrace_enable(0); + } + + syslog(USBMON_PREFIX "Stopped: %d\n", g_usbmonitor.pid); + return 0; +} + +#endif /* CONFIG_SYSTEM_USBMONITOR */ diff --git a/apps/systemlib/err.c b/apps/systemlib/err.c index 3011743a1..daf17ef8b 100644 --- a/apps/systemlib/err.c +++ b/apps/systemlib/err.c @@ -85,17 +85,17 @@ warnerr_core(int errcode, const char *fmt, va_list args) fprintf(stderr, "\n"); #elif CONFIG_ARCH_LOWPUTC - lib_lowprintf("%s: ", getprogname()); - lib_lowvprintf(fmt, args); + lowsyslog("%s: ", getprogname()); + lowvyslog(fmt, args); /* convenience as many parts of NuttX use negative errno */ if (errcode < 0) errcode = -errcode; if (errcode < NOCODE) - lib_lowprintf(": %s", strerror(errcode)); + lowsyslog(": %s", strerror(errcode)); - lib_lowprintf("\n"); + lowsyslog("\n"); #endif } diff --git a/apps/systemlib/mixer/mixer_group.cpp b/apps/systemlib/mixer/mixer_group.cpp index 25d19f9ad..60eeff225 100644 --- a/apps/systemlib/mixer/mixer_group.cpp +++ b/apps/systemlib/mixer/mixer_group.cpp @@ -56,7 +56,7 @@ #define debug(fmt, args...) do { } while(0) //#define debug(fmt, args...) do { printf("[mixer] " fmt "\n", ##args); } while(0) //#include <debug.h> -//#define debug(fmt, args...) lib_lowprintf(fmt "\n", ##args) +//#define debug(fmt, args...) lowsyslog(fmt "\n", ##args) MixerGroup::MixerGroup(ControlCallback control_cb, uintptr_t cb_handle) : Mixer(control_cb, cb_handle), diff --git a/apps/systemlib/mixer/mixer_multirotor.cpp b/apps/systemlib/mixer/mixer_multirotor.cpp index f6e91b1bf..4b9cfc023 100644 --- a/apps/systemlib/mixer/mixer_multirotor.cpp +++ b/apps/systemlib/mixer/mixer_multirotor.cpp @@ -57,7 +57,7 @@ #define debug(fmt, args...) do { } while(0) //#define debug(fmt, args...) do { printf("[mixer] " fmt "\n", ##args); } while(0) //#include <debug.h> -//#define debug(fmt, args...) lib_lowprintf(fmt "\n", ##args) +//#define debug(fmt, args...) lowsyslog(fmt "\n", ##args) /* * Clockwise: 1 @@ -217,11 +217,11 @@ unsigned MultirotorMixer::mix(float *outputs, unsigned space) { float roll = get_control(0, 0) * _roll_scale; - //lib_lowprintf("roll: %d, get_control0: %d, %d\n", (int)(roll), (int)(get_control(0, 0)), (int)(_roll_scale)); + //lowsyslog("roll: %d, get_control0: %d, %d\n", (int)(roll), (int)(get_control(0, 0)), (int)(_roll_scale)); float pitch = get_control(0, 1) * _pitch_scale; float yaw = get_control(0, 2) * _yaw_scale; float thrust = get_control(0, 3); - //lib_lowprintf("thrust: %d, get_control3: %d\n", (int)(thrust), (int)(get_control(0, 3))); + //lowsyslog("thrust: %d, get_control3: %d\n", (int)(thrust), (int)(get_control(0, 3))); float max = 0.0f; float fixup_scale; |