[drivers/serial] Introduce hooker for TTY (#8733)

In this patch, a hook list has been introduced to address the concerns
regarding coupling issues arising from modifications to the serial code
for integrating TTY logic.

Signed-off-by: Shell <smokewood@qq.com>
This commit is contained in:
Shell 2024-04-09 21:36:16 +08:00 committed by GitHub
parent 38204386b3
commit 4b0f42c24a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 90 additions and 35 deletions

View File

@ -102,6 +102,14 @@
0 \ 0 \
} }
/**
* @brief Sets a hook function when RX indicate is called
*
* @param thread is the target thread that initializing
*/
typedef void (*rt_hw_serial_rxind_hookproto_t)(rt_device_t dev, rt_size_t size);
RT_OBJECT_HOOKLIST_DECLARE(rt_hw_serial_rxind_hookproto_t, rt_hw_serial_rxind);
struct serial_configure struct serial_configure
{ {
rt_uint32_t baud_rate; rt_uint32_t baud_rate;
@ -186,4 +194,5 @@ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
void *data); void *data);
rt_err_t rt_hw_serial_register_tty(struct rt_serial_device *serial); rt_err_t rt_hw_serial_register_tty(struct rt_serial_device *serial);
#endif #endif

View File

@ -103,6 +103,14 @@
0 \ 0 \
} }
/**
* @brief Sets a hook function when RX indicate is called
*
* @param thread is the target thread that initializing
*/
typedef void (*rt_hw_serial_rxind_hookproto_t)(rt_device_t dev, rt_size_t size);
RT_OBJECT_HOOKLIST_DECLARE(rt_hw_serial_rxind_hookproto_t, rt_hw_serial_rxind);
struct serial_configure struct serial_configure
{ {
rt_uint32_t baud_rate; rt_uint32_t baud_rate;

View File

@ -12,7 +12,7 @@
#include <rtdevice.h> #include <rtdevice.h>
#include <drivers/platform.h> #include <drivers/platform.h>
#include <drivers/core/bus.h> #include <drivers/core/bus.h>
#include "../serial/serial_dm.h" #include <drivers/serial_dm.h>
#define DBG_TAG "rtdm.ofw" #define DBG_TAG "rtdm.ofw"
#define DBG_LVL DBG_INFO #define DBG_LVL DBG_INFO

View File

@ -57,10 +57,14 @@
#undef putc #undef putc
#endif #endif
RT_OBJECT_HOOKLIST_DEFINE(rt_hw_serial_rxind);
static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size) static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size)
{ {
rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN); rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN);
RT_OBJECT_HOOKLIST_CALL(rt_hw_serial_rxind, (dev, size));
return RT_EOK; return RT_EOK;
} }
@ -1388,14 +1392,6 @@ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
return ret; return ret;
} }
#if defined(RT_USING_SMART) && defined(LWP_DEBUG)
static volatile int _early_input = 0;
int lwp_startup_debug_request(void)
{
return _early_input;
}
#endif
/* ISR for serial interrupt */ /* ISR for serial interrupt */
void rt_hw_serial_isr(struct rt_serial_device *serial, int event) void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
{ {
@ -1441,7 +1437,7 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
/** /**
* Invoke callback. * Invoke callback.
* First try notify if any, and if notify is existed, rx_indicate() * First try notify if any, and if notify is existed, rx_indicate()
* is not callback. This seperate the priority and makes the reuse * is not callback. This separate the priority and makes the reuse
* of same serial device reasonable for RT console. * of same serial device reasonable for RT console.
*/ */
if (serial->rx_notify.notify) if (serial->rx_notify.notify)
@ -1463,9 +1459,6 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
serial->parent.rx_indicate(&serial->parent, rx_length); serial->parent.rx_indicate(&serial->parent, rx_length);
} }
} }
#if defined(RT_USING_SMART) && defined(LWP_DEBUG)
_early_input = 1;
#endif
break; break;
} }
case RT_SERIAL_EVENT_TX_DONE: case RT_SERIAL_EVENT_TX_DONE:

View File

@ -9,7 +9,7 @@
*/ */
#include <rtatomic.h> #include <rtatomic.h>
#include "serial_dm.h" #include <drivers/serial_dm.h>
int serial_dev_set_name(struct rt_serial_device *sdev) int serial_dev_set_name(struct rt_serial_device *sdev)
{ {
@ -82,8 +82,9 @@ void *serial_base_from_args(char *str)
return (void *)base; return (void *)base;
} }
struct serial_configure serial_cfg_from_args(char *str) struct serial_configure serial_cfg_from_args(char *_str)
{ {
char *str = _str;
struct serial_configure cfg = RT_SERIAL_CONFIG_DEFAULT; struct serial_configure cfg = RT_SERIAL_CONFIG_DEFAULT;
/* Format baudrate/parity/bits/flow (BBBBPNF), Default is 115200n8 */ /* Format baudrate/parity/bits/flow (BBBBPNF), Default is 115200n8 */

View File

@ -63,6 +63,37 @@ static char *alloc_device_name(void)
return tty_dev_name; return tty_dev_name;
} }
#ifdef LWP_DEBUG_INIT
static volatile int _early_input = 0;
static void _set_debug(rt_device_t dev, rt_size_t size);
RT_OBJECT_HOOKLIST_DEFINE_NODE(rt_hw_serial_rxind, _set_debug_node, _set_debug);
static void _set_debug(rt_device_t dev, rt_size_t size)
{
rt_list_remove(&_set_debug_node.list_node);
_early_input = 1;
}
static void _setup_debug_rxind_hook(void)
{
rt_hw_serial_rxind_sethook(&_set_debug_node);
}
int lwp_startup_debug_request(void)
{
return _early_input;
}
#else /* !LWP_DEBUG_INIT */
static void _setup_debug_rxind_hook(void)
{
return ;
}
#endif /* LWP_DEBUG_INIT */
static void _tty_rx_notify(struct rt_device *device) static void _tty_rx_notify(struct rt_device *device)
{ {
lwp_tty_t tp; lwp_tty_t tp;
@ -325,6 +356,8 @@ static int _tty_workqueue_init(void)
LWP_TTY_WORKQUEUE_PRIORITY); LWP_TTY_WORKQUEUE_PRIORITY);
RT_ASSERT(_ttyworkq != RT_NULL); RT_ASSERT(_ttyworkq != RT_NULL);
_setup_debug_rxind_hook();
return RT_EOK; return RT_EOK;
} }
INIT_PREV_EXPORT(_tty_workqueue_init); INIT_PREV_EXPORT(_tty_workqueue_init);

View File

@ -35,10 +35,14 @@
#undef putc #undef putc
#endif #endif
RT_OBJECT_HOOKLIST_DEFINE(rt_hw_serial_rxind);
static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size) static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size)
{ {
rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN); rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN);
RT_OBJECT_HOOKLIST_CALL(rt_hw_serial_rxind, (dev, size));
return RT_EOK; return RT_EOK;
} }

View File

@ -6,10 +6,17 @@ menuconfig RT_USING_LWP
The lwP is a light weight process running in user mode. The lwP is a light weight process running in user mode.
if RT_USING_LWP if RT_USING_LWP
config LWP_DEBUG menuconfig LWP_DEBUG
bool "Enable debugging features of LwP" bool "Enable debugging features of LwP"
default y default y
if LWP_DEBUG
config LWP_DEBUG_INIT
select RT_USING_HOOKLIST
bool "Enable debug mode of init process"
default n
endif
config RT_LWP_MAX_NR config RT_LWP_MAX_NR
int "The max number of light-weight process" int "The max number of light-weight process"
default 30 default 30

View File

@ -137,7 +137,7 @@ static int lwp_startup(void)
char *argv[] = {0, "&"}; char *argv[] = {0, "&"};
char *envp[] = {LWP_CONSOLE_PATH, 0}; char *envp[] = {LWP_CONSOLE_PATH, 0};
#ifdef LWP_DEBUG #ifdef LWP_DEBUG_INIT
int command; int command;
int countdown = LATENCY_TIMES; int countdown = LATENCY_TIMES;
while (countdown) while (countdown)
@ -152,7 +152,7 @@ static int lwp_startup(void)
rt_thread_mdelay(LATENCY_IN_MSEC); rt_thread_mdelay(LATENCY_IN_MSEC);
} }
rt_kprintf("Starting init ...\n"); rt_kprintf("Starting init ...\n");
#endif #endif /* LWP_DEBUG_INIT */
for (size_t i = 0; i < sizeof(init_search_path)/sizeof(init_search_path[0]); i++) for (size_t i = 0; i < sizeof(init_search_path)/sizeof(init_search_path[0]); i++)
{ {

View File

@ -528,13 +528,13 @@ struct rt_object_information
#define _RT_OBJECT_HOOKLIST_CALL(nodetype, nested, list, lock, argv) \ #define _RT_OBJECT_HOOKLIST_CALL(nodetype, nested, list, lock, argv) \
do \ do \
{ \ { \
nodetype iter; \ nodetype iter, next; \
rt_ubase_t level = rt_spin_lock_irqsave(&lock); \ rt_ubase_t level = rt_spin_lock_irqsave(&lock); \
nested += 1; \ nested += 1; \
rt_spin_unlock_irqrestore(&lock, level); \ rt_spin_unlock_irqrestore(&lock, level); \
if (!rt_list_isempty(&list)) \ if (!rt_list_isempty(&list)) \
{ \ { \
rt_list_for_each_entry(iter, &list, list_node) \ rt_list_for_each_entry_safe(iter, next, &list, list_node) \
{ \ { \
iter->handler argv; \ iter->handler argv; \
} \ } \