1
0

tty_cons.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-12-11 Shell init ver.
  9. */
  10. #define DBG_TAG "lwp.tty"
  11. #define DBG_LVL DBG_INFO
  12. #include <rtdbg.h>
  13. #include "tty_config.h"
  14. #include "tty_internal.h"
  15. #include "bsd_porting.h"
  16. #include "terminal.h"
  17. #include <fcntl.h>
  18. #ifdef RT_USING_DEVICE_OPS
  19. const static struct rt_device_ops cons_rtdev_ops;
  20. #endif
  21. struct backend_entry
  22. {
  23. rt_list_t bakend_list_node;
  24. int prio;
  25. rt_device_t bakdev;
  26. };
  27. static rt_list_t _bakend_list;
  28. static void _bent_enqueue(struct backend_entry *bent)
  29. {
  30. struct backend_entry *idx;
  31. rt_bool_t inserted = RT_FALSE;
  32. rt_list_for_each_entry(idx, &_bakend_list, bakend_list_node)
  33. {
  34. if (idx->prio < bent->prio)
  35. {
  36. rt_list_insert_before(&idx->bakend_list_node, &bent->bakend_list_node);
  37. inserted = RT_TRUE;
  38. break;
  39. }
  40. }
  41. if (!inserted)
  42. rt_list_insert_after(&_bakend_list, &bent->bakend_list_node);
  43. return ;
  44. }
  45. rt_err_t lwp_console_register_backend(struct rt_device *bakdev, int prio)
  46. {
  47. rt_err_t ret = RT_EOK;
  48. struct backend_entry *bent;
  49. bent = rt_malloc(sizeof(struct backend_entry));
  50. if (bent)
  51. {
  52. rt_list_init(&bent->bakend_list_node);
  53. bent->prio = prio;
  54. bent->bakdev = bakdev;
  55. _bent_enqueue(bent);
  56. }
  57. else
  58. {
  59. ret = -RT_ENOMEM;
  60. }
  61. return ret;
  62. }
  63. static struct rt_device _cons_rtdev;
  64. static int fops_open(struct dfs_file *file)
  65. {
  66. return -EINVAL;
  67. }
  68. static struct dfs_file_ops _cons_fops = {
  69. .open = fops_open,
  70. };
  71. static rt_err_t _cons_readlink(struct rt_device *dev, char *buf, int len)
  72. {
  73. int rc = -EIO;
  74. struct backend_entry *bent;
  75. if (!rt_list_isempty(&_bakend_list))
  76. {
  77. bent = rt_list_first_entry(&_bakend_list, struct backend_entry, bakend_list_node);
  78. if (bent)
  79. {
  80. RT_ASSERT(bent->bakdev);
  81. strncpy(buf, bent->bakdev->parent.name, MIN(len, RT_NAME_MAX));
  82. LOG_D("%s: backend device %s", __func__, buf);
  83. rc = 0;
  84. }
  85. }
  86. if (rc != 0)
  87. {
  88. LOG_W("%s: No backend device", __func__);
  89. }
  90. return rc;
  91. }
  92. static int _cons_init(void)
  93. {
  94. rt_err_t rc;
  95. rt_list_init(&_bakend_list);
  96. /* setup system level device */
  97. _cons_rtdev.type = RT_Device_Class_Char;
  98. _cons_rtdev.ops = &cons_rtdev_ops;
  99. rc = rt_device_register(&_cons_rtdev, "console", RT_DEVICE_FLAG_DYNAMIC);
  100. if (rc == RT_EOK)
  101. {
  102. _cons_rtdev.readlink = &_cons_readlink;
  103. _cons_rtdev.fops = &_cons_fops;
  104. }
  105. return rc;
  106. }
  107. INIT_DEVICE_EXPORT(_cons_init);