summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--components/drivers/serial/serial_tty.c63
-rw-r--r--components/lwp/lwp.c29
-rw-r--r--components/lwp/terminal/terminal.h5
-rw-r--r--include/rtdef.h9
-rw-r--r--include/rtthread.h1
-rw-r--r--src/object.c67
6 files changed, 134 insertions, 40 deletions
diff --git a/components/drivers/serial/serial_tty.c b/components/drivers/serial/serial_tty.c
index 36692a9300..f75123eba2 100644
--- a/components/drivers/serial/serial_tty.c
+++ b/components/drivers/serial/serial_tty.c
@@ -404,3 +404,66 @@ static int _tty_workqueue_init(void)
return RT_EOK;
}
INIT_PREV_EXPORT(_tty_workqueue_init);
+
+static rt_err_t _match_tty_iter(struct rt_object *obj, void *data)
+{
+ rt_device_t target = *(rt_device_t *)data;
+ rt_device_t device = rt_container_of(obj, struct rt_device, parent);
+ if (device->type == RT_Device_Class_Char)
+ {
+ lwp_tty_t tp;
+ if (rt_strncmp(obj->name, "tty"TTY_NAME_PREFIX,
+ sizeof("tty"TTY_NAME_PREFIX) - 1) == 0)
+ {
+ struct serial_tty_context *softc;
+
+ tp = rt_container_of(device, struct lwp_tty, parent);
+ softc = tty_softc(tp);
+
+ if (&softc->parent->parent == target)
+ {
+ /* matched, early return */
+ *(rt_device_t *)data = device;
+ return 1;
+ }
+ }
+ }
+
+ return RT_EOK;
+}
+
+/**
+ * @brief The default console is only a backup device with lowest priority.
+ * It's always recommended to scratch the console from the boot arguments.
+ * And dont forget to register the device with a higher priority.
+ */
+static int _default_console_setup(void)
+{
+ rt_err_t rc;
+ rt_device_t bakdev;
+ rt_device_t ttydev;
+
+ bakdev = rt_console_get_device();
+ if (!bakdev)
+ {
+ return -RT_ENOENT;
+ }
+
+ ttydev = bakdev;
+ rt_object_for_each(RT_Object_Class_Device, _match_tty_iter, &ttydev);
+
+ if (ttydev != bakdev)
+ {
+ LOG_I("Using /dev/%.*s as default console", RT_NAME_MAX, ttydev->parent.name);
+ lwp_console_register_backend(ttydev, LWP_CONSOLE_LOWEST_PRIOR);
+ rc = RT_EOK;
+ }
+ else
+ {
+ rc = -RT_EINVAL;
+ }
+
+ return rc;
+}
+
+INIT_COMPONENT_EXPORT(_default_console_setup);
diff --git a/components/lwp/lwp.c b/components/lwp/lwp.c
index 87629cc890..c33bbfdc5f 100644
--- a/components/lwp/lwp.c
+++ b/components/lwp/lwp.c
@@ -17,7 +17,7 @@
*/
#define DBG_TAG "lwp"
-#define DBG_LVL DBG_WARNING
+#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#include <rthw.h>
@@ -62,29 +62,6 @@ static const char elf_magic[] = {0x7f, 'E', 'L', 'F'};
extern char working_directory[];
#endif
-/**
- * @brief The default console is only a backup device with lowest priority.
- * It's always recommended to scratch the console from the boot arguments.
- * And dont forget to register the device with a higher priority.
- */
-static rt_err_t lwp_default_console_setup(void)
-{
- rt_device_t bakdev = rt_device_find("ttyS0");
- rt_err_t rc;
-
- if (bakdev)
- {
- lwp_console_register_backend(bakdev, LWP_CONSOLE_LOWEST_PRIOR);
- rc = RT_EOK;
- }
- else
- {
- rc = -RT_EINVAL;
- }
-
- return rc;
-}
-
static int lwp_component_init(void)
{
int rc;
@@ -104,10 +81,6 @@ static int lwp_component_init(void)
{
LOG_E("%s: lwp_futex_init() failed", __func__);
}
- else if ((rc = lwp_default_console_setup()) != RT_EOK)
- {
- LOG_E("%s: lwp_default_console_setup() failed", __func__);
- }
return rc;
}
INIT_COMPONENT_EXPORT(lwp_component_init);
diff --git a/components/lwp/terminal/terminal.h b/components/lwp/terminal/terminal.h
index df0dc04128..69ed66d5ff 100644
--- a/components/lwp/terminal/terminal.h
+++ b/components/lwp/terminal/terminal.h
@@ -212,9 +212,8 @@ void tty_rel_gone(struct lwp_tty *tp);
#define tty_lock_notrecused(tp) (rt_mutex_get_hold(tty_getlock(tp)) == 1)
#define tty_assert_locked(tp) RT_ASSERT(tty_lock_owned(tp))
#define tty_lock_assert(tp, option) \
- (((option) == (MA_OWNED | MA_NOTRECURSED)) \
- ? (tty_lock_owned(tp) && tty_lock_notrecused(tp)) \
- : rt_assert_handler("Operation not allowed", __func__, __LINE__))
+ RT_ASSERT(((option) == (MA_OWNED | MA_NOTRECURSED)) && \
+ (tty_lock_owned(tp) && tty_lock_notrecused(tp)))
/* System messages. */
int tty_checkoutq(struct lwp_tty *tp);
diff --git a/include/rtdef.h b/include/rtdef.h
index 06fcfcb8b8..f0918d5dd6 100644
--- a/include/rtdef.h
+++ b/include/rtdef.h
@@ -356,6 +356,15 @@ struct rt_object
typedef struct rt_object *rt_object_t; /**< Type for kernel objects. */
/**
+ * iterator of rt_object_for_each()
+ *
+ * data is the data passing in to rt_object_for_each(). iterator can return
+ * RT_EOK to continue the iteration; or any positive value to break the loop
+ * successfully; or any negative errno to break the loop on failure.
+ */
+typedef rt_err_t (*rt_object_iter_t)(rt_object_t object, void *data);
+
+/**
* The object type can be one of the follows with specific
* macros enabled:
* - Thread
diff --git a/include/rtthread.h b/include/rtthread.h
index c2174cce42..1cad47931a 100644
--- a/include/rtthread.h
+++ b/include/rtthread.h
@@ -75,6 +75,7 @@ rt_err_t rt_custom_object_destroy(rt_object_t obj);
#endif /* RT_USING_HEAP */
rt_bool_t rt_object_is_systemobject(rt_object_t object);
rt_uint8_t rt_object_get_type(rt_object_t object);
+rt_err_t rt_object_for_each(rt_uint8_t type, rt_object_iter_t iter, void *data);
rt_object_t rt_object_find(const char *name, rt_uint8_t type);
rt_err_t rt_object_get_name(rt_object_t object, char *name, rt_uint8_t name_size);
diff --git a/src/object.c b/src/object.c
index bdb69364ce..ae62be1fa3 100644
--- a/src/object.c
+++ b/src/object.c
@@ -575,29 +575,32 @@ rt_uint8_t rt_object_get_type(rt_object_t object)
}
/**
- * @brief This function will find specified name object from object
+ * @brief This function will iterate through each object from object
* container.
*
- * @param name is the specified name of object.
- *
* @param type is the type of object
+ * @param iter is the iterator
+ * @param data is the specified data passed to iterator
*
- * @return the found object or RT_NULL if there is no this object
- * in object container.
+ * @return RT_EOK on succeed, otherwise the error from `iter`
*
* @note this function shall not be invoked in interrupt status.
*/
-rt_object_t rt_object_find(const char *name, rt_uint8_t type)
+rt_err_t rt_object_for_each(rt_uint8_t type, rt_object_iter_t iter, void *data)
{
struct rt_object *object = RT_NULL;
struct rt_list_node *node = RT_NULL;
struct rt_object_information *information = RT_NULL;
rt_base_t level;
+ rt_err_t error;
information = rt_object_get_information((enum rt_object_class_type)type);
/* parameter check */
- if ((name == RT_NULL) || (information == RT_NULL)) return RT_NULL;
+ if (information == RT_NULL)
+ {
+ return -RT_EINVAL;
+ }
/* which is invoke in interrupt status */
RT_DEBUG_NOT_IN_INTERRUPT;
@@ -609,16 +612,62 @@ rt_object_t rt_object_find(const char *name, rt_uint8_t type)
rt_list_for_each(node, &(information->object_list))
{
object = rt_list_entry(node, struct rt_object, list);
- if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
+ if ((error = iter(object, data)) != RT_EOK)
{
rt_spin_unlock_irqrestore(&(information->spinlock), level);
- return object;
+ return error >= 0 ? RT_EOK : error;
}
}
rt_spin_unlock_irqrestore(&(information->spinlock), level);
+ return RT_EOK;
+}
+
+static rt_err_t _match_name(struct rt_object *obj, void *data)
+{
+ const char *name = *(const char **)data;
+ if (rt_strncmp(obj->name, name, RT_NAME_MAX) == 0)
+ {
+ *(rt_object_t *)data = obj;
+
+ /* notify an early break of loop, but not on error */
+ return 1;
+ }
+
+ return RT_EOK;
+}
+
+/**
+ * @brief This function will find specified name object from object
+ * container.
+ *
+ * @param name is the specified name of object.
+ *
+ * @param type is the type of object
+ *
+ * @return the found object or RT_NULL if there is no this object
+ * in object container.
+ *
+ * @note this function shall not be invoked in interrupt status.
+ */
+rt_object_t rt_object_find(const char *name, rt_uint8_t type)
+{
+ void *data = (void *)name;
+
+ /* parameter check */
+ if (name == RT_NULL) return RT_NULL;
+
+ /* which is invoke in interrupt status */
+ RT_DEBUG_NOT_IN_INTERRUPT;
+
+ rt_object_for_each(type, _match_name, &data);
+ if (data != name)
+ {
+ return data;
+ }
+
return RT_NULL;
}