Bladeren bron

[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>
Shell 1 jaar geleden
bovenliggende
commit
4b0f42c24a

+ 9 - 0
components/drivers/include/drivers/serial.h

@@ -102,6 +102,14 @@
     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
 {
     rt_uint32_t baud_rate;
@@ -186,4 +194,5 @@ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
                                void                    *data);
 
 rt_err_t rt_hw_serial_register_tty(struct rt_serial_device *serial);
+
 #endif

+ 0 - 0
components/drivers/serial/serial_dm.h → components/drivers/include/drivers/serial_dm.h


+ 8 - 0
components/drivers/include/drivers/serial_v2.h

@@ -103,6 +103,14 @@
     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
 {
     rt_uint32_t baud_rate;

+ 1 - 1
components/drivers/ofw/ofw.c

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

+ 5 - 12
components/drivers/serial/serial.c

@@ -57,10 +57,14 @@
 #undef putc
 #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)
 {
     rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN);
 
+    RT_OBJECT_HOOKLIST_CALL(rt_hw_serial_rxind, (dev, size));
+
     return RT_EOK;
 }
 
@@ -1388,14 +1392,6 @@ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
     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 */
 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.
              * 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.
              */
             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);
                 }
             }
-        #if defined(RT_USING_SMART) && defined(LWP_DEBUG)
-            _early_input = 1;
-        #endif
             break;
         }
         case RT_SERIAL_EVENT_TX_DONE:

+ 3 - 2
components/drivers/serial/serial_dm.c

@@ -9,7 +9,7 @@
  */
 
 #include <rtatomic.h>
-#include "serial_dm.h"
+#include <drivers/serial_dm.h>
 
 int serial_dev_set_name(struct rt_serial_device *sdev)
 {
@@ -82,8 +82,9 @@ void *serial_base_from_args(char *str)
     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;
 
     /* Format baudrate/parity/bits/flow (BBBBPNF), Default is 115200n8 */

+ 33 - 0
components/drivers/serial/serial_tty.c

@@ -63,6 +63,37 @@ static char *alloc_device_name(void)
     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)
 {
     lwp_tty_t tp;
@@ -325,6 +356,8 @@ static int _tty_workqueue_init(void)
                                     LWP_TTY_WORKQUEUE_PRIORITY);
     RT_ASSERT(_ttyworkq != RT_NULL);
 
+    _setup_debug_rxind_hook();
+
     return RT_EOK;
 }
 INIT_PREV_EXPORT(_tty_workqueue_init);

+ 4 - 0
components/drivers/serial/serial_v2.c

@@ -35,10 +35,14 @@
 #undef putc
 #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)
 {
     rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN);
 
+    RT_OBJECT_HOOKLIST_CALL(rt_hw_serial_rxind, (dev, size));
+
     return RT_EOK;
 }
 

+ 8 - 1
components/lwp/Kconfig

@@ -6,10 +6,17 @@ menuconfig RT_USING_LWP
         The lwP is a light weight process running in user mode.
 
 if RT_USING_LWP
-    config LWP_DEBUG
+    menuconfig LWP_DEBUG
         bool "Enable debugging features of LwP"
         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
         int "The max number of light-weight process"
         default 30

+ 2 - 2
components/lwp/lwp.c

@@ -137,7 +137,7 @@ static int lwp_startup(void)
     char *argv[] = {0, "&"};
     char *envp[] = {LWP_CONSOLE_PATH, 0};
 
-#ifdef LWP_DEBUG
+#ifdef LWP_DEBUG_INIT
     int command;
     int countdown = LATENCY_TIMES;
     while (countdown)
@@ -152,7 +152,7 @@ static int lwp_startup(void)
         rt_thread_mdelay(LATENCY_IN_MSEC);
     }
     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++)
     {

+ 17 - 17
include/rtdef.h

@@ -525,23 +525,23 @@ struct rt_object_information
  *     do_other_things();
  * }
  */
-#define _RT_OBJECT_HOOKLIST_CALL(nodetype, nested, list, lock, argv) \
-    do                                                               \
-    {                                                                \
-        nodetype iter;                                               \
-        rt_ubase_t level = rt_spin_lock_irqsave(&lock);              \
-        nested += 1;                                                 \
-        rt_spin_unlock_irqrestore(&lock, level);                     \
-        if (!rt_list_isempty(&list))                                 \
-        {                                                            \
-            rt_list_for_each_entry(iter, &list, list_node)           \
-            {                                                        \
-                iter->handler argv;                                  \
-            }                                                        \
-        }                                                            \
-        level = rt_spin_lock_irqsave(&lock);                         \
-        nested -= 1;                                                 \
-        rt_spin_unlock_irqrestore(&lock, level);                     \
+#define _RT_OBJECT_HOOKLIST_CALL(nodetype, nested, list, lock, argv)  \
+    do                                                                \
+    {                                                                 \
+        nodetype iter, next;                                          \
+        rt_ubase_t level = rt_spin_lock_irqsave(&lock);               \
+        nested += 1;                                                  \
+        rt_spin_unlock_irqrestore(&lock, level);                      \
+        if (!rt_list_isempty(&list))                                  \
+        {                                                             \
+            rt_list_for_each_entry_safe(iter, next, &list, list_node) \
+            {                                                         \
+                iter->handler argv;                                   \
+            }                                                         \
+        }                                                             \
+        level = rt_spin_lock_irqsave(&lock);                          \
+        nested -= 1;                                                  \
+        rt_spin_unlock_irqrestore(&lock, level);                      \
     } while (0)
 #define RT_OBJECT_HOOKLIST_CALL(name, argv)                        \
     _RT_OBJECT_HOOKLIST_CALL(name##_hooklistnode_t, name##_nested, \