From e64b7e3367eb7356bc7699a6d82c37eb0ec2fade Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Jul 2014 16:25:02 -0600 Subject: NSH: Add an option to take stdin from a USB keyboard device --- apps/nshlib/Kconfig | 52 ++++-- apps/nshlib/Makefile | 10 +- apps/nshlib/README.txt | 17 +- apps/nshlib/nsh.h | 32 +++- apps/nshlib/nsh_consolemain.c | 8 +- apps/nshlib/nsh_usbconsole.c | 337 +++++++++++++++++++++++++++++++++++ apps/nshlib/nsh_usbdev.c | 395 ------------------------------------------ apps/nshlib/nsh_usbkeyboard.c | 222 ++++++++++++++++++++++++ apps/nshlib/nsh_usbtrace.c | 127 ++++++++++++++ 9 files changed, 782 insertions(+), 418 deletions(-) create mode 100644 apps/nshlib/nsh_usbconsole.c delete mode 100644 apps/nshlib/nsh_usbdev.c create mode 100644 apps/nshlib/nsh_usbkeyboard.c create mode 100644 apps/nshlib/nsh_usbtrace.c (limited to 'apps/nshlib') diff --git a/apps/nshlib/Kconfig b/apps/nshlib/Kconfig index d4bca38e7..966856516 100644 --- a/apps/nshlib/Kconfig +++ b/apps/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/apps/nshlib/Makefile b/apps/nshlib/Makefile index c5eb5c53d..a78299222 100644 --- a/apps/nshlib/Makefile +++ b/apps/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/apps/nshlib/README.txt b/apps/nshlib/README.txt index d894c9deb..91cb19983 100644 --- a/apps/nshlib/README.txt +++ b/apps/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/apps/nshlib/nsh.h b/apps/nshlib/nsh.h index 9546155cd..f15eaf5d6 100644 --- a/apps/nshlib/nsh.h +++ b/apps/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/apps/nshlib/nsh_consolemain.c b/apps/nshlib/nsh_consolemain.c index 42353d3f4..a8e7bd72a 100644 --- a/apps/nshlib/nsh_consolemain.c +++ b/apps/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/apps/nshlib/nsh_usbconsole.c b/apps/nshlib/nsh_usbconsole.c new file mode 100644 index 000000000..800b36413 --- /dev/null +++ b/apps/nshlib/nsh_usbconsole.c @@ -0,0 +1,337 @@ +/**************************************************************************** + * apps/nshlib/nsh_usbconsole.c + * + * Copyright (C) 2012-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 + +#ifdef CONFIG_CDCACM +# include +#endif + +#ifdef CONFIG_CDCACM +# include +#endif + +#include "nsh.h" +#include "nsh_console.h" + +#ifdef HAVE_USB_CONSOLE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + + /**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_configstdio + * + * Description: + * Configure standard I/O + * + ****************************************************************************/ + +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"); +} + +/**************************************************************************** + * Name: nsh_nullstdio + * + * Description: + * Use /dev/null for standard I/O + * + ****************************************************************************/ + +static int nsh_nullstdio(void) +{ + int fd; + + /* Open /dev/null for read/write access */ + + 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; +} + +/**************************************************************************** + * Name: nsh_waitusbready + * + * Description: + * Wait for the USB console device to be ready + * + ****************************************************************************/ + +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. + */ + + /* Open the USB serial device for read/write access */ + + do + { + /* Try to open the console */ + + fd = open(CONFIG_NSH_USBCONDEV, O_RDWR); + if (fd < 0) + { + /* ENOTCONN means that the USB device is not yet connected. Anything + * else is bad. + */ + + DEBUGASSERT(errno == ENOTCONN); + + /* Sleep a bit and try again */ + + sleep(2); + } + } + while (fd < 0); + + /* Now wait until we successfully read a carriage return a few times. + * That is a sure way of know that there is something at the other end of + * the USB serial connection that is ready to talk with us. The user needs + * to hit ENTER a few times to get things started. + */ + + nlc = 0; + do + { + /* Read one byte */ + + inch = 0; + nbytes = read(fd, &inch, 1); + + /* Is it a carriage return (or maybe a newline)? */ + + if (nbytes == 1 && (inch == '\n' || inch == '\r')) + { + /* Yes.. increment the count */ + + nlc++; + } + else + { + /* No.. Reset the count. We need to see 3 in a row to continue. */ + + nlc = 0; + } + } + while (nlc < 3); + + /* Configure standard I/O */ + + 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; +} + +/**************************************************************************** + * 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). + * + ****************************************************************************/ + +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 */ + +#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 + + UNUSED(ret); /* Eliminate warning if not used */ + 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(); + + (void)ret; /* Eliminate warning if not used */ + 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 /* HAVE_USB_CONSOLE */ diff --git a/apps/nshlib/nsh_usbdev.c b/apps/nshlib/nsh_usbdev.c deleted file mode 100644 index ec80df481..000000000 --- a/apps/nshlib/nsh_usbdev.c +++ /dev/null @@ -1,395 +0,0 @@ -/**************************************************************************** - * apps/nshlib/nsh_usbdev.c - * - * Copyright (C) 2012-2013 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 - -#ifdef CONFIG_CDCACM -# include -#endif - -#ifdef CONFIG_CDCACM -# include -#endif - -#include "nsh.h" -#include "nsh_console.h" - -/**************************************************************************** - * 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 - * - ****************************************************************************/ - -#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 - * - * 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_nullstdio - * - * Description: - * Use /dev/null for standard I/O - * - ****************************************************************************/ - -#ifdef HAVE_USB_CONSOLE -static int nsh_nullstdio(void) -{ - int fd; - - /* Open /dev/null for read/write access */ - - 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. - */ - - /* Open the USB serial device for read/write access */ - - do - { - /* Try to open the console */ - - fd = open(CONFIG_NSH_USBCONDEV, O_RDWR); - if (fd < 0) - { - /* ENOTCONN means that the USB device is not yet connected. Anything - * else is bad. - */ - - DEBUGASSERT(errno == ENOTCONN); - - /* Sleep a bit and try again */ - - sleep(2); - } - } - while (fd < 0); - - /* Now wait until we successfully read a carriage return a few times. - * That is a sure way of know that there is something at the other end of - * the USB serial connection that is ready to talk with us. The user needs - * to hit ENTER a few times to get things started. - */ - - nlc = 0; - do - { - /* Read one byte */ - - inch = 0; - nbytes = read(fd, &inch, 1); - - /* Is it a carriage return (or maybe a newline)? */ - - if (nbytes == 1 && (inch == '\n' || inch == '\r')) - { - /* Yes.. increment the count */ - - nlc++; - } - else - { - /* No.. Reset the count. We need to see 3 in a row to continue. */ - - nlc = 0; - } - } - while (nlc < 3); - - /* Configure standard I/O */ - - 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; -} -#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 */ - -#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 - - (void)ret; /* Eliminate warning if not used */ - 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(); - - (void)ret; /* Eliminate warning if not used */ - 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 - * - ****************************************************************************/ - -#ifdef CONFIG_NSH_USBDEV_TRACE -void nsh_usbtrace(void) -{ - (void)usbtrace_enumerate(nsh_tracecallback, NULL); -} -#endif diff --git a/apps/nshlib/nsh_usbkeyboard.c b/apps/nshlib/nsh_usbkeyboard.c new file mode 100644 index 000000000..845d56a88 --- /dev/null +++ b/apps/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/apps/nshlib/nsh_usbtrace.c b/apps/nshlib/nsh_usbtrace.c new file mode 100644 index 000000000..09f4df7e6 --- /dev/null +++ b/apps/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 */ -- cgit v1.2.3