device_service.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Copyright (c) 2018 Nordic Semiconductor ASA
  3. * Copyright (c) 2016 Intel Corporation
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. */
  7. #include <shell/shell.h>
  8. #include <init.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <device.h>
  12. #include <sys/arch_interface.h>
  13. extern const struct device __device_PRE_KERNEL_1_start[];
  14. extern const struct device __device_PRE_KERNEL_2_start[];
  15. extern const struct device __device_POST_KERNEL_start[];
  16. extern const struct device __device_APPLICATION_start[];
  17. extern const struct device __device_end[];
  18. #ifdef CONFIG_SMP
  19. extern const struct device __device_SMP_start[];
  20. #endif
  21. static const struct device *levels[] = {
  22. __device_PRE_KERNEL_1_start,
  23. __device_PRE_KERNEL_2_start,
  24. __device_POST_KERNEL_start,
  25. __device_APPLICATION_start,
  26. #ifdef CONFIG_SMP
  27. __device_SMP_start,
  28. #endif
  29. /* End marker */
  30. __device_end,
  31. };
  32. static const char *get_device_name(const struct device *dev,
  33. char *buf,
  34. size_t len)
  35. {
  36. const char *name = dev->name;
  37. if ((name == NULL) || (name[0] == 0)) {
  38. snprintf(buf, len, "[%p]", dev);
  39. name = buf;
  40. }
  41. return name;
  42. }
  43. static bool device_get_config_level(const struct shell *shell, int level)
  44. {
  45. const struct device *dev;
  46. bool devices = false;
  47. char buf[20];
  48. for (dev = levels[level]; dev < levels[level+1]; dev++) {
  49. if (device_is_ready(dev)) {
  50. devices = true;
  51. shell_fprintf(shell, SHELL_NORMAL, "- %s\n",
  52. get_device_name(dev, buf, sizeof(buf)));
  53. }
  54. }
  55. return devices;
  56. }
  57. static int cmd_device_levels(const struct shell *shell,
  58. size_t argc, char **argv)
  59. {
  60. ARG_UNUSED(argc);
  61. ARG_UNUSED(argv);
  62. bool ret;
  63. shell_fprintf(shell, SHELL_NORMAL, "PRE KERNEL 1:\n");
  64. ret = device_get_config_level(shell, _SYS_INIT_LEVEL_PRE_KERNEL_1);
  65. if (ret == false) {
  66. shell_fprintf(shell, SHELL_NORMAL, "- None\n");
  67. }
  68. shell_fprintf(shell, SHELL_NORMAL, "PRE KERNEL 2:\n");
  69. ret = device_get_config_level(shell, _SYS_INIT_LEVEL_PRE_KERNEL_2);
  70. if (ret == false) {
  71. shell_fprintf(shell, SHELL_NORMAL, "- None\n");
  72. }
  73. shell_fprintf(shell, SHELL_NORMAL, "POST_KERNEL:\n");
  74. ret = device_get_config_level(shell, _SYS_INIT_LEVEL_POST_KERNEL);
  75. if (ret == false) {
  76. shell_fprintf(shell, SHELL_NORMAL, "- None\n");
  77. }
  78. shell_fprintf(shell, SHELL_NORMAL, "APPLICATION:\n");
  79. ret = device_get_config_level(shell, _SYS_INIT_LEVEL_APPLICATION);
  80. if (ret == false) {
  81. shell_fprintf(shell, SHELL_NORMAL, "- None\n");
  82. }
  83. #ifdef CONFIG_SMP
  84. shell_fprintf(shell, SHELL_NORMAL, "SMP:\n");
  85. ret = device_get_config_level(shell, _SYS_INIT_LEVEL_SMP);
  86. if (ret == false) {
  87. shell_fprintf(shell, SHELL_NORMAL, "- None\n");
  88. }
  89. #endif /* CONFIG_SMP */
  90. return 0;
  91. }
  92. struct cmd_device_list_visitor_context {
  93. const struct shell *shell;
  94. char *buf;
  95. size_t buf_size;
  96. };
  97. static int cmd_device_list_visitor(const struct device *dev,
  98. void *context)
  99. {
  100. const struct cmd_device_list_visitor_context *ctx = context;
  101. shell_fprintf(ctx->shell, SHELL_NORMAL, " requires: %s\n",
  102. get_device_name(dev, ctx->buf, ctx->buf_size));
  103. return 0;
  104. }
  105. static int cmd_device_list(const struct shell *shell,
  106. size_t argc, char **argv)
  107. {
  108. const struct device *devlist;
  109. size_t devcnt = z_device_get_all_static(&devlist);
  110. const struct device *devlist_end = devlist + devcnt;
  111. const struct device *dev;
  112. ARG_UNUSED(argc);
  113. ARG_UNUSED(argv);
  114. shell_fprintf(shell, SHELL_NORMAL, "devices:\n");
  115. for (dev = devlist; dev < devlist_end; dev++) {
  116. char buf[20];
  117. const char *name = get_device_name(dev, buf, sizeof(buf));
  118. const char *state = "READY";
  119. shell_fprintf(shell, SHELL_NORMAL, "- %s", name);
  120. if (!device_is_ready(dev)) {
  121. state = "DISABLED";
  122. } else {
  123. #ifdef CONFIG_PM_DEVICE
  124. enum pm_device_state st = PM_DEVICE_STATE_ACTIVE;
  125. int err = pm_device_state_get(dev, &st);
  126. if (!err) {
  127. state = pm_device_state_str(st);
  128. }
  129. #endif /* CONFIG_PM_DEVICE */
  130. }
  131. shell_fprintf(shell, SHELL_NORMAL, " (%s)\n", state);
  132. if (!k_is_user_context()) {
  133. struct cmd_device_list_visitor_context ctx = {
  134. .shell = shell,
  135. .buf = buf,
  136. .buf_size = sizeof(buf),
  137. };
  138. (void)device_required_foreach(dev, cmd_device_list_visitor, &ctx);
  139. }
  140. }
  141. return 0;
  142. }
  143. SHELL_STATIC_SUBCMD_SET_CREATE(sub_device,
  144. SHELL_CMD(levels, NULL, "List configured devices by levels", cmd_device_levels),
  145. SHELL_CMD(list, NULL, "List configured devices", cmd_device_list),
  146. SHELL_SUBCMD_SET_END /* Array terminated. */
  147. );
  148. SHELL_CMD_REGISTER(device, &sub_device, "Device commands", NULL);