diff --git a/nshlib/Kconfig b/nshlib/Kconfig index d4bca38e7..966856516 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -597,34 +597,60 @@ config NSH_CONSOLE serial device as the NSH console (not necessarily dev/console). config NSH_USBCONSOLE - bool "Use a USB console" + bool "Use a USB serial console" default n - depends on NSH_CONSOLE && USBDEV + depends on NSH_CONSOLE && USBDEV && (CDCACM || PL2303) ---help--- - If defined, then the an arbitrary USB device may be used - to as the NSH console. In this case, NSH_USBCONDEV must - be defined to indicate which USB device to use as the - console. + If defined, then the an arbitrary USB serial device may be used + to as the NSH console. In this case, NSH_USBCONDEV must be defined + to indicate which USB serial device to use as the console. + +if NSH_USBCONSOLE config NSH_USBCONDEV - string "USB console device" - default "/dev/ttyACM0" - depends on NSH_USBCONSOLE + string "USB serial console device" + default "/dev/ttyACM0" if CDCACM + default "/dev/ttyUSB0" if !CDCACM ---help--- If NSH_USBCONSOLE is set to 'y', then NSH_USBCONDEV must also be set to select the USB device used to support the NSH console. This should be set to the quoted name of a - readable/write-able USB driver such as: - NSH_USBCONDEV="/dev/ttyACM0". + read-/write-able USB driver. Default: "/dev/ttyACM0". config USBDEV_MINOR - int "USB console device minor number" + int "USB serial console device minor number" default 0 - depends on NSH_USBCONSOLE ---help--- If there are more than one USB devices, then a USB device minor number may also need to be provided. Default: 0 +endif # NSH_USBCONSOLE + +config NSH_USBKBD + bool "Use a USB keyboard input" + default n + depends on NSH_CONSOLE && USBHOST_HIDKBD && !NSH_USBCONSOLE + ---help--- + Normally NSH uses the same device for stdin, stdout, and stderr. By + default, that device is /dev/console. If this option is selected, + then NSH will use a USB HID keyboard for stdin. In this case, the + keyboard is connected directly to the target (via a USB host + interface) and the data from the keyboard will drive NSH. NSH + output (stdout and stderr) will still go to /dev/console. + +if NSH_USBKBD + +config NSH_USBKBD_DEVNAME + string "USB keyboard device" + default "/dev/kbda" + ---help--- + If NSH_USBKBD is set to 'y', then NSH_USBKBD_DEVNAME must also be + set to select the USB keyboard device used to support the NSH + console input. This should be set to the quoted name of a read- + able keyboard driver. Default: "/dev/kbda". + +endif #NSH_USBKBD + comment "USB Trace Support" config NSH_USBDEV_TRACE diff --git a/nshlib/Makefile b/nshlib/Makefile index c5eb5c53d..a78299222 100644 --- a/nshlib/Makefile +++ b/nshlib/Makefile @@ -90,7 +90,15 @@ CSRCS += nsh_test.c endif ifeq ($(CONFIG_USBDEV),y) -CSRCS += nsh_usbdev.c +CSRCS += nsh_usbconsole.c +endif + +ifeq ($(CONFIG_USBHOST),y) +CSRCS += nsh_usbkeyboard.c +endif + +ifeq ($(CONFIG_NSH_USBDEV_TRACE),y) +CSRCS += nsh_usbtrace.c endif ifeq ($(CONFIG_NETUTILS_CODECS),y) diff --git a/nshlib/README.txt b/nshlib/README.txt index d894c9deb..91cb19983 100644 --- a/nshlib/README.txt +++ b/nshlib/README.txt @@ -1183,8 +1183,7 @@ NSH-Specific Configuration Settings If CONFIG_NSH_USBCONSOLE is set to 'y', then CONFIG_NSH_USBCONDEV must also be set to select the USB device used to support the NSH console. This should be set to the quoted name of a - readable/write-able USB driver such as: - CONFIG_NSH_USBCONDEV="/dev/ttyACM0". + read-/write-able USB driver. Default: "/dev/ttyACM0". If there are more than one USB devices, then a USB device minor number may also need to be provided: @@ -1192,6 +1191,20 @@ NSH-Specific Configuration Settings CONFIG_NSH_USBDEV_MINOR The minor device number of the USB device. Default: 0 + CONFIG_NSH_USBKBD + Normally NSH uses the same device for stdin, stdout, and stderr. By + default, that device is /dev/console. If this option is selected, + then NSH will use a USB HID keyboard for stdin. In this case, the + keyboard is connected directly to the target (via a USB host + interface) and the data from the keyboard will drive NSH. NSH + output (stdout and stderr) will still go to /dev/console. + + CONFIG_NSH_USBKBD_DEVNAME + If NSH_USBKBD is set to 'y', then NSH_USBKBD_DEVNAME must also be + set to select the USB keyboard device used to support the NSH + console input. This should be set to the quoted name of a read- + able keyboard driver. Default: "/dev/kbda". + 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 diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 9546155cd..f15eaf5d6 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -146,20 +146,46 @@ #ifdef HAVE_USB_CONSOLE -/* The default USB console device minor number is 0*/ +/* The default USB console device minor number is 0 */ # ifndef CONFIG_NSH_USBDEV_MINOR # define CONFIG_NSH_USBDEV_MINOR 0 # endif -/* The default console device is always /dev/console */ +/* The default USB serial console device */ # ifndef CONFIG_NSH_USBCONDEV -# define CONFIG_NSH_USBCONDEV "/dev/console" +# if defined(CONFIG_CDCACM) +# define CONFIG_NSH_USBCONDEV "/dev/ttyACM0" +# elif defined(CONFIG_PL2303) +# define CONFIG_NSH_USBCONDEV "/dev/ttyUSB0" +# else +# define CONFIG_NSH_USBCONDEV "/dev/console" +# endif # endif #endif /* HAVE_USB_CONSOLE */ +/* If a USB keyboard device is selected for NSH input then we need to handle + * some special start-up conditions. + */ + +#undef HAVE_USB_KEYBOARD +#if defined(CONFIG_USBHOST) && !defined(HAVE_USB_CONSOLE) + +/* Check for a USB HID keyboard in the configuration */ + +# ifdef CONFIG_USBHOST_HIDKBD +# define HAVE_USB_KEYBOARD 1 + +/* The default keyboard device is /dev/kbda */ + +# ifndef NSH_USBKBD_DEVNAME +# define NSH_USBKBD_DEVNAME "/dev/kbda" +# endif +# endif +#endif /* HAVE_USB_KEYBOARD */ + /* USB trace settings */ #ifndef CONFIG_USBDEV_TRACE diff --git a/nshlib/nsh_consolemain.c b/nshlib/nsh_consolemain.c index 42353d3f4..a8e7bd72a 100644 --- a/nshlib/nsh_consolemain.c +++ b/nshlib/nsh_consolemain.c @@ -45,7 +45,7 @@ #include "nsh.h" #include "nsh_console.h" -#ifndef HAVE_USB_CONSOLE +#if !defined(HAVE_USB_CONSOLE) && !defined(HAVE_USB_KEYBOARD) /**************************************************************************** * Pre-processor Definitions @@ -84,8 +84,8 @@ * 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). + * devices (see nsh_usbconsole.c and usb_usbkeyboard for other versions + * for special USB console devices). * * Input Parameters: * Standard task start-up arguments. These are not used. argc may be @@ -127,4 +127,4 @@ int nsh_consolemain(int argc, char *argv[]) return ret; } -#endif /* !HAVE_USB_CONSOLE */ +#endif /* !HAVE_USB_CONSOLE && !HAVE_USB_KEYBOARD */ diff --git a/nshlib/nsh_usbdev.c b/nshlib/nsh_usbconsole.c similarity index 83% rename from nshlib/nsh_usbdev.c rename to nshlib/nsh_usbconsole.c index ec80df481..800b36413 100644 --- a/nshlib/nsh_usbdev.c +++ b/nshlib/nsh_usbconsole.c @@ -1,7 +1,7 @@ /**************************************************************************** - * apps/nshlib/nsh_usbdev.c + * apps/nshlib/nsh_usbconsole.c * - * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2012-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -57,23 +57,13 @@ #include "nsh.h" #include "nsh_console.h" +#ifdef HAVE_USB_CONSOLE + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -/* 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 - -/**************************************************************************** + /**************************************************************************** * Private Types ****************************************************************************/ @@ -93,26 +83,6 @@ * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: nsh_tracecallback - ****************************************************************************/ - -/**************************************************************************** - * 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); - return 0; -} -#endif - /**************************************************************************** * Name: nsh_configstdio * @@ -121,7 +91,6 @@ static int nsh_tracecallback(struct usbtrace_s *trace, void *arg) * ****************************************************************************/ -#ifdef HAVE_USB_CONSOLE static void nsh_configstdio(int fd) { /* Make sure the stdin, stdout, and stderr are closed */ @@ -149,7 +118,6 @@ static void nsh_configstdio(int fd) (void)fdopen(1, "a"); (void)fdopen(2, "a"); } -#endif /**************************************************************************** * Name: nsh_nullstdio @@ -159,7 +127,6 @@ static void nsh_configstdio(int fd) * ****************************************************************************/ -#ifdef HAVE_USB_CONSOLE static int nsh_nullstdio(void) { int fd; @@ -187,7 +154,6 @@ static int nsh_nullstdio(void) return fd; } -#endif /**************************************************************************** * Name: nsh_waitusbready @@ -197,7 +163,6 @@ static int nsh_nullstdio(void) * ****************************************************************************/ -#ifdef HAVE_USB_CONSOLE static int nsh_waitusbready(void) { char inch; @@ -277,7 +242,6 @@ static int nsh_waitusbready(void) return OK; } -#endif /**************************************************************************** * Public Functions @@ -307,7 +271,6 @@ static int nsh_waitusbready(void) * ****************************************************************************/ -#ifdef HAVE_USB_CONSOLE int nsh_consolemain(int argc, char *argv[]) { FAR struct console_stdio_s *pstate = nsh_newconsole(); @@ -330,7 +293,7 @@ int nsh_consolemain(int argc, char *argv[]) ret = usbdev_serialinitialize(CONFIG_NSH_USBDEV_MINOR); #endif - (void)ret; /* Eliminate warning if not used */ + UNUSED(ret); /* Eliminate warning if not used */ DEBUGASSERT(ret == OK); #endif @@ -370,26 +333,5 @@ int nsh_consolemain(int argc, char *argv[]) (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 - * - ****************************************************************************/ - -#ifdef CONFIG_NSH_USBDEV_TRACE -void nsh_usbtrace(void) -{ - (void)usbtrace_enumerate(nsh_tracecallback, NULL); -} -#endif +#endif /* HAVE_USB_CONSOLE */ diff --git a/nshlib/nsh_usbkeyboard.c b/nshlib/nsh_usbkeyboard.c new file mode 100644 index 000000000..845d56a88 --- /dev/null +++ b/nshlib/nsh_usbkeyboard.c @@ -0,0 +1,222 @@ +/**************************************************************************** + * apps/nshlib/nsh_usbkeyboard.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include +#include +#include + +#include "nsh.h" +#include "nsh_console.h" + +#if defined(HAVE_USB_KEYBOARD) && !defined(HAVE_USB_CONSOLE) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + + /**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_wait_usbready + * + * Description: + * Wait for the USB keyboard device to be ready + * + ****************************************************************************/ + +static int nsh_wait_usbready(FAR const char *msg) +{ + int fd; + + /* Don't start the NSH console until the keyboard device is ready. Chances + * are, we get here with no functional stdin. The USB keyboard device will + * not be available until the device is connected to the host and enumerated. + */ + + /* Open the USB keyboard device for read-only access */ + + do + { + /* Try to open the console */ + + fd = open(NSH_USBKBD_DEVNAME, O_RDONLY); + if (fd < 0) + { + /* ENOENT means that the USB device is not yet connected and, + * hence, has no entry under /dev. Anything else would be bad. + */ + + DEBUGASSERT(errno == ENOENT); + + /* Let the user know that we are waiting */ + + if (msg) + { + /* Show the waiting message only one time after the failure + * to open the keyboard device. + */ + + puts(msg); + fflush(stdout); + msg = NULL; + } + + /* Sleep a bit and try again */ + + sleep(2); + } + } + while (fd < 0); + + /* Okay.. we have successfully opened a keyboard device + * + * Close standard fd 0. Unbeknownst to stdin. + * NOTE: This might not be portable behavior! + */ + + (void)close(0); + + /* Dup the fd to create standard fd 0. stdin should not know */ + + (void)dup2(fd, 0); + + /* Close the keyboard device that we just opened */ + + close(fd); + return OK; +} + +/**************************************************************************** + * 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 for output + * but uses a special USB keyboard device for input. The USB keyboard + * requires some special operations to handle the cases where the session + * input is lost when the USB keyboard is unplugged and restarted when the + * USB keyboard 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). + * + ****************************************************************************/ + +int nsh_consolemain(int argc, char *argv[]) +{ + FAR struct console_stdio_s *pstate = nsh_newconsole(); + FAR const char *msg; + int ret; + + DEBUGASSERT(pstate); + + /* Initialize any USB tracing options that were requested */ + +#ifdef CONFIG_NSH_USBDEV_TRACE + usbtrace_enable(TRACE_BITSET); +#endif + + /* Execute the one-time start-up script. Any output will go to /dev/console. */ + +#ifdef CONFIG_NSH_ROMFSETC + (void)nsh_initscript(&pstate->cn_vtbl); +#endif + + /* Now loop, executing creating a session for each USB connection */ + + msg = "Waiting for keyboard to be connected...\n"; + for (;;) + { + /* Wait for the USB to be connected to the host and switch + * standard I/O to the USB serial device. + */ + + ret = nsh_wait_usbready(msg); + + (void)ret; /* Eliminate warning if not used */ + DEBUGASSERT(ret == OK); + + /* Execute the session */ + + (void)nsh_session(pstate); + + /* We lost the connection. Wait for the keyboard to + * be re-connected. + */ + + msg = "Please re-connect the keyboard...\n"; + } +} + +#endif /* HAVE_USB_KEYBOARD && !HAVE_USB_CONSOLE */ diff --git a/nshlib/nsh_usbtrace.c b/nshlib/nsh_usbtrace.c new file mode 100644 index 000000000..09f4df7e6 --- /dev/null +++ b/nshlib/nsh_usbtrace.c @@ -0,0 +1,127 @@ +/**************************************************************************** + * apps/nshlib/nsh_usbtrace.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#include + +#ifdef CONFIG_NSH_USBDEV_TRACE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* 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 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_tracecallback + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_tracecallback + * + * Description: + * This is part of the USB trace logic + * + ****************************************************************************/ + +static int nsh_tracecallback(struct usbtrace_s *trace, void *arg) +{ + usbtrace_trprintf((trprintf_t)trmessage, trace->event, trace->value); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 + * + ****************************************************************************/ + +void nsh_usbtrace(void) +{ + (void)usbtrace_enumerate(nsh_tracecallback, NULL); +} + +#endif /* CONFIG_NSH_USBDEV_TRACE */