[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:
parent
0655742ccf
commit
a79176b0ae
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1390,14 +1394,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)
|
||||||
{
|
{
|
||||||
|
@ -1443,7 +1439,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)
|
||||||
|
@ -1465,9 +1461,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:
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -526,23 +526,23 @@ struct rt_object_information
|
||||||
* do_other_things();
|
* do_other_things();
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
#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; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
level = rt_spin_lock_irqsave(&lock); \
|
level = rt_spin_lock_irqsave(&lock); \
|
||||||
nested -= 1; \
|
nested -= 1; \
|
||||||
rt_spin_unlock_irqrestore(&lock, level); \
|
rt_spin_unlock_irqrestore(&lock, level); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#define RT_OBJECT_HOOKLIST_CALL(name, argv) \
|
#define RT_OBJECT_HOOKLIST_CALL(name, argv) \
|
||||||
_RT_OBJECT_HOOKLIST_CALL(name##_hooklistnode_t, name##_nested, \
|
_RT_OBJECT_HOOKLIST_CALL(name##_hooklistnode_t, name##_nested, \
|
||||||
|
|
Loading…
Reference in New Issue