serial: add CONFIG_TTY_LAUNCH support
this allow user start new program from tty Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
parent
cff2bc05e0
commit
75aec04330
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -105,6 +107,16 @@ static int uart_ioctl(FAR struct file *filep,
|
||||
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
|
||||
****************************************************************************/
|
||||
@ -1609,6 +1625,58 @@ errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user