You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/01/01 12:38:35 UTC
[incubator-nuttx] branch master updated: serial: add CONFIG_TTY_LAUNCH support
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 75aec04 serial: add CONFIG_TTY_LAUNCH support
75aec04 is described below
commit 75aec04330d0f2b8ba405e292ef34ca1d0253e37
Author: ligd <li...@xiaomi.com>
AuthorDate: Wed Dec 15 13:40:45 2021 +0800
serial: add CONFIG_TTY_LAUNCH support
this allow user start new program from tty
Signed-off-by: ligd <li...@xiaomi.com>
---
.../components/drivers/character/serial.rst | 16 +++++
drivers/serial/Kconfig | 63 ++++++++++++++++
drivers/serial/serial.c | 84 ++++++++++++++++++++++
drivers/serial/serial_dma.c | 14 +++-
drivers/serial/serial_io.c | 11 +++
include/nuttx/serial/serial.h | 13 ++++
tools/cfgdefine.c | 2 +
7 files changed, 200 insertions(+), 3 deletions(-)
diff --git a/Documentation/components/drivers/character/serial.rst b/Documentation/components/drivers/character/serial.rst
index f45e45a..ea259fd 100644
--- a/Documentation/components/drivers/character/serial.rst
+++ b/Documentation/components/drivers/character/serial.rst
@@ -19,6 +19,22 @@ Serial Device Drivers
``/dev/ttyS0``, ``/dev/ttyS1``, etc. See the
``uart_register()`` implementation in ``drivers/serial.c``.
+- **TTY_LAUNCH** this depends on ``CONFIG_TTY_LAUNCH``, this feature
+ allow user launch a new program with a special char input.
+
+ e.g. use ctrl+R to start a nuttx shell.
+ e.g. use ctrl+E to start user entry.
+
+ You can use ``TTY_LAUNCH_CHAR`` to customize which special char.
+
+ You can choose launch method:
+ ``TTY_LAUNCH_ENTRY`` or ``TTY_LAUNCH_FILE``,
+ If``TTY_LAUNCH_ENTRY`` you can set program entery by ``TTY_LAUNCH_ENTRYPOINT``.
+ If``TTY_LAUNCH_FILE`` you can set file path by ``TTY_LAUNCH_FILEPATH``.
+
+ Also, you can customize:
+ ``TTY_LAUNCH_ARGS`` ``TTY_LAUNCH_PRIORITY`` ``TTY_LAUNCH_STACKSIZE``
+
- **User Access**. Serial drivers are, ultimately, normal
`character drivers <#chardrivers>`__ and are accessed as other
character drivers.
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 0a2f7ad..6361321 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -173,6 +173,69 @@ config SERIAL_TERMIOS
If this is not defined, then the terminal settings (baud, parity, etc).
are not configurable at runtime; serial streams cannot be flushed, etc..
+config TTY_LAUNCH
+ bool "Enable feature TTY launch program"
+ default n
+ ---help---
+ If select this, then user can launch a program with a special input.
+
+if TTY_LAUNCH
+
+config TTY_LAUNCH_CHAR
+ hex "TTY launch program characters"
+ default 0x12
+ ---help---
+ Use Ctrl-R 0x12 inputs to determine whether launch a program
+
+config TTY_LAUNCH_ARGS
+ string "TTY launch argument list"
+ default INIT_ARGS
+ ---help---
+ The argument list for user applications. e.g.:
+ "\"arg1\",\"arg2\",\"arg3\""
+
+config TTY_LAUNCH_PRIORITY
+ int "TTY launch program priority"
+ default INIT_PRIORITY
+
+config TTY_LAUNCH_STACKSIZE
+ hex "TTY launch program stack size"
+ default INIT_STACKSIZE
+
+choice
+ prompt "TTY launch method"
+ default TTY_LAUNCH_ENTRY
+
+config TTY_LAUNCH_ENTRY
+ bool "TTY launch program"
+
+config TTY_LAUNCH_FILE
+ bool "TTY launch file"
+ depends on !BINFMT_DISABLE
+
+endchoice
+
+config TTY_LAUNCH_ENTRYPOINT
+ string "TTY launch program entry"
+ depends on TTY_LAUNCH_ENTRY
+ default INIT_ENTRYPOINT
+
+config TTY_LAUNCH_ENTRYNAME
+ string "TTY launch program name"
+ depends on TTY_LAUNCH_ENTRY
+ default TTY_LAUNCH_ENTRYPOINT
+
+config TTY_LAUNCH_FILEPATH
+ string "TTY launch file path"
+ depends on TTY_LAUNCH_FILE
+ default INIT_FILEPATH
+ ---help---
+ The name of the entry point for user applications. For the example
+ applications this is of the form 'app_main' where 'app' is the application
+ name. If not defined, USER_ENTRYPOINT defaults to "main".
+
+endif # TTY_LAUNCH
+
config TTY_FORCE_PANIC
bool "Enable TTY force crash"
default n
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index f02316b..84c58a7 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -45,6 +45,8 @@
#include <nuttx/serial/serial.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/power/pm.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/kthread.h>
/****************************************************************************
* Pre-processor Definitions
@@ -106,6 +108,16 @@ static int uart_poll(FAR struct file *filep,
FAR struct pollfd *fds, bool setup);
/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_TTY_LAUNCH_ENTRY
+/* Lanch program entry, this must be supplied by the application. */
+
+int CONFIG_TTY_LAUNCH_ENTRYPOINT(int argc, char *argv[]);
+#endif
+
+/****************************************************************************
* Private Data
****************************************************************************/
@@ -123,6 +135,10 @@ static const struct file_operations g_serialops =
#endif
};
+#ifdef CONFIG_TTY_LAUNCH
+static struct work_s g_serial_work;
+#endif
+
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -1610,6 +1626,58 @@ errout:
}
/****************************************************************************
+ * Name: uart_nxsched_foreach_cb
+ ****************************************************************************/
+
+#ifdef CONFIG_TTY_LAUNCH
+static void uart_launch_foreach(FAR struct tcb_s *tcb, FAR void *arg)
+{
+#ifdef CONFIG_TTY_LAUNCH_ENTRY
+ if (!strcmp(tcb->name, CONFIG_TTY_LAUNCH_ENTRYNAME))
+#else
+ if (!strcmp(tcb->name, CONFIG_TTY_LAUNCH_FILEPATH))
+#endif
+ {
+ *(int *)arg = 1;
+ }
+}
+
+static void uart_launch_worker(void *arg)
+{
+#ifdef CONFIG_TTY_LAUNCH_ARGS
+ FAR char *const argv[] =
+ {
+ CONFIG_TTY_LAUNCH_ARGS,
+ NULL,
+ };
+#else
+ FAR char *const *argv = NULL;
+#endif
+ int found = 0;
+
+ nxsched_foreach(uart_launch_foreach, &found);
+ if (!found)
+ {
+#ifdef CONFIG_TTY_LAUNCH_ENTRY
+ nxtask_create(CONFIG_TTY_LAUNCH_ENTRYNAME,
+ CONFIG_TTY_LAUNCH_PRIORITY,
+ CONFIG_TTY_LAUNCH_STACKSIZE,
+ (main_t)CONFIG_TTY_LAUNCH_ENTRYPOINT,
+ argv);
+#else
+ posix_spawnattr_t attr;
+
+ posix_spawnattr_init(&attr);
+
+ attr.priority = CONFIG_TTY_LAUNCH_PRIORITY;
+ attr.stacksize = CONFIG_TTY_LAUNCH_STACKSIZE;
+ exec_spawn(CONFIG_TTY_LAUNCH_FILEPATH, argv, NULL, 0, &attr);
+#endif
+ }
+}
+#endif
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -1817,3 +1885,19 @@ void uart_reset_sem(FAR uart_dev_t *dev)
nxsem_reset(&dev->recv.sem, 1);
nxsem_reset(&dev->pollsem, 1);
}
+
+/****************************************************************************
+ * Name: uart_launch
+ *
+ * Description:
+ * This function is called when user want launch a new program by
+ * using a special char.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_TTY_LAUNCH
+void uart_launch(void)
+{
+ work_queue(HPWORK, &g_serial_work, uart_launch_worker, NULL, 0);
+}
+#endif
diff --git a/drivers/serial/serial_dma.c b/drivers/serial/serial_dma.c
index b328c5d..4a0cbb8 100644
--- a/drivers/serial/serial_dma.c
+++ b/drivers/serial/serial_dma.c
@@ -57,7 +57,7 @@
****************************************************************************/
#if defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGTSTP) || \
- defined(CONFIG_TTY_FORCE_PANIC)
+ defined(CONFIG_TTY_FORCE_PANIC) || defined(CONFIG_TTY_LAUNCH)
static int uart_check_signo(int pid, const char *buf, size_t size)
{
size_t i;
@@ -72,6 +72,14 @@ static int uart_check_signo(int pid, const char *buf, size_t size)
}
#endif
+#ifdef CONFIG_TTY_LAUNCH
+ if (buf[i] == CONFIG_TTY_LAUNCH_CHAR)
+ {
+ uart_launch();
+ return 0;
+ }
+#endif
+
#ifdef CONFIG_TTY_SIGINT
if (pid > 0 && buf[i] == CONFIG_TTY_SIGINT_CHAR)
{
@@ -105,7 +113,7 @@ static int uart_check_signo(int pid, const char *buf, size_t size)
#if defined(CONFIG_SERIAL_RXDMA) && \
(defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGTSTP) || \
- defined(CONFIG_TTY_FORCE_PANIC))
+ defined(CONFIG_TTY_FORCE_PANIC) || defined(CONFIG_TTY_LAUNCH))
static int uart_recvchars_signo(FAR uart_dev_t *dev)
{
FAR struct uart_dmaxfer_s *xfer = &dev->dmarx;
@@ -369,7 +377,7 @@ void uart_recvchars_done(FAR uart_dev_t *dev)
FAR struct uart_buffer_s *rxbuf = &dev->recv;
size_t nbytes = xfer->nbytes;
#if defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGTSTP) || \
- defined(CONFIG_TTY_FORCE_PANIC)
+ defined(CONFIG_TTY_FORCE_PANIC) || defined(CONFIG_TTY_LAUNCH)
int signo = 0;
/* Check if the SIGINT character is anywhere in the newly received DMA
diff --git a/drivers/serial/serial_io.c b/drivers/serial/serial_io.c
index 3add7e9..35cf83e4 100644
--- a/drivers/serial/serial_io.c
+++ b/drivers/serial/serial_io.c
@@ -252,6 +252,17 @@ void uart_recvchars(FAR uart_dev_t *dev)
}
else
#endif
+#ifdef CONFIG_TTY_LAUNCH
+ /* Is this the special character that will generate the SIGTSTP
+ * signal?
+ */
+
+ if ((dev->tc_lflag & ISIG) && ch == CONFIG_TTY_LAUNCH_CHAR)
+ {
+ uart_launch();
+ }
+ else
+#endif
/* If the RX buffer becomes full, then the serial data is discarded.
* This is necessary because on most serial hardware, you must read
diff --git a/include/nuttx/serial/serial.h b/include/nuttx/serial/serial.h
index d5aa793..293a1c9 100644
--- a/include/nuttx/serial/serial.h
+++ b/include/nuttx/serial/serial.h
@@ -495,6 +495,19 @@ void uart_recvchars_done(FAR uart_dev_t *dev);
void uart_reset_sem(FAR uart_dev_t *dev);
+/****************************************************************************
+ * Name: uart_lanch
+ *
+ * Description:
+ * This function is called when user want lanch a new program by
+ * using a special char.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_TTY_LAUNCH
+void uart_launch(void);
+#endif
+
#undef EXTERN
#if defined(__cplusplus)
}
diff --git a/tools/cfgdefine.c b/tools/cfgdefine.c
index 87ecb87..0405584 100644
--- a/tools/cfgdefine.c
+++ b/tools/cfgdefine.c
@@ -60,6 +60,8 @@ static const char *dequote_list[] =
"CONFIG_PASS1_BUILDIR", /* Pass1 build directory */
"CONFIG_PASS1_TARGET", /* Pass1 build target */
"CONFIG_PASS1_OBJECT", /* Pass1 build object */
+ "CONFIG_TTY_LAUNCH_ENTRYPOINT", /* Name of entry point from tty launch */
+ "CONFIG_TTY_LAUNCH_ARGS", /* Argument list of entry point from tty launch */
/* NxWidgets/NxWM */