act_log_shell.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #include <init.h>
  2. #include "act_log_inner.h"
  3. #include <linker/linker-defs.h>
  4. #ifdef CONFIG_DEBUG_ACTLOG_SHELL
  5. #include <shell/shell.h>
  6. #include <stdlib.h>
  7. #define ACTLOG_PREFIX_STR "#LOG:"
  8. #define ACTLOG_BEGIN_STR "BEGIN#"
  9. #define ACTLOG_END_STR "END#"
  10. #define ACTLOG_ERROR_STR "ERROR CANNOT DUMP#"
  11. #define MAX_LINE_LENGTH_BYTES (64)
  12. #define DEFAULT_LINE_LENGTH_BYTES (16)
  13. void actlog_print_buffer(const uint8_t *addr, int width, int count, int linelen, unsigned long disp_addr)
  14. {
  15. int i, thislinelen;
  16. const uint8_t *data;
  17. /* linebuf as a union causes proper alignment */
  18. union linebuf {
  19. u32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(u32_t) + 1];
  20. u16_t us[MAX_LINE_LENGTH_BYTES/sizeof(u16_t) + 1];
  21. u8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(u8_t) + 1];
  22. }lb;
  23. if (linelen * width > MAX_LINE_LENGTH_BYTES)
  24. linelen = MAX_LINE_LENGTH_BYTES / width;
  25. if (linelen < 1)
  26. linelen = DEFAULT_LINE_LENGTH_BYTES / width;
  27. if (disp_addr == -1)
  28. disp_addr = (unsigned long)addr;
  29. while (count) {
  30. thislinelen = linelen;
  31. data = (const void *)addr;
  32. printk("%08x:", (unsigned int)disp_addr);
  33. /* check for overflow condition */
  34. if (count < thislinelen)
  35. thislinelen = count;
  36. /* Copy from memory into linebuf and print hex values */
  37. for (i = 0; i < thislinelen; i++) {
  38. if (width == 4) {
  39. lb.ui[i] = *(volatile u32_t *)data;
  40. printk(" %08x", lb.ui[i]);
  41. } else if (width == 2) {
  42. lb.us[i] = *(volatile u16_t *)data;
  43. printk(" %04x", lb.us[i]);
  44. } else {
  45. lb.uc[i] = *(volatile u8_t *)data;
  46. printk(" %02x", lb.uc[i]);
  47. }
  48. data += width;
  49. }
  50. while (thislinelen < linelen) {
  51. /* fill line with whitespace for nice ASCII print */
  52. for (i = 0; i < width * 2 + 1; i++)
  53. printk(" ");
  54. linelen--;
  55. }
  56. /* Print data in ASCII characters */
  57. for (i = 0; i < thislinelen * width; i++) {
  58. if (lb.uc[i] < 0x20 || lb.uc[i] > 0x7e)
  59. lb.uc[i] = '.';
  60. }
  61. lb.uc[i] = '\0';
  62. printk(" %s\n", lb.uc);
  63. /* update references */
  64. addr += thislinelen * width;
  65. disp_addr += thislinelen * width;
  66. count -= thislinelen;
  67. }
  68. }
  69. int actlog_dump_callback(uint8_t *data, uint32_t len)
  70. {
  71. uint32_t read_len = 0;
  72. uint32_t str_len;
  73. while(read_len < len) {
  74. if(*data) {
  75. str_len = actlog_strnlen(data, len - read_len);
  76. //flow output,do not use printk
  77. act_log_output_flow_write(NULL, data, str_len);
  78. read_len += str_len;
  79. data += str_len;
  80. } else {
  81. data++;
  82. read_len++;
  83. }
  84. }
  85. k_busy_wait(10);
  86. return 0;
  87. }
  88. int cmd_print_actlog(int file_id)
  89. {
  90. int traverse_len;
  91. /* Print buffer */
  92. char print_buf[CONFIG_ACTLOG_LINEBUF_SIZE];
  93. traverse_len = act_log_backend_traverse(file_id, actlog_dump_callback, print_buf, sizeof(print_buf));
  94. return traverse_len;
  95. }
  96. static int cmd_print_stored_actlog(const struct shell *shell,
  97. size_t argc, char **argv)
  98. {
  99. int traverse_len;
  100. int file_len;
  101. if (argc < 2) {
  102. goto err_ret;
  103. }
  104. uint32_t file_id = strtoul(argv[1], NULL, 16);
  105. shell_print(shell, "%s%s", ACTLOG_PREFIX_STR, ACTLOG_BEGIN_STR);
  106. traverse_len = cmd_print_actlog(file_id);
  107. shell_print(shell, "%s%s", ACTLOG_PREFIX_STR, ACTLOG_END_STR);
  108. file_len = act_log_backend_get_used_size(file_id);
  109. if (traverse_len) {
  110. shell_print(shell, "Stored actlog printed origin len %d print len %d.", file_len, traverse_len);
  111. } else {
  112. err_ret:
  113. shell_print(shell, "Stored actlog verification failed "
  114. "or there is no stored actlog.");
  115. }
  116. return 0;
  117. }
  118. static int cmd_erase_actlog_dump(const struct shell *shell,
  119. size_t argc, char **argv)
  120. {
  121. int ret = 0;
  122. if (argc < 2) {
  123. goto err_ret;
  124. }
  125. uint32_t file_id = strtoul(argv[1], NULL, 16);
  126. ret = act_log_backend_clear(file_id);
  127. if (ret == 0) {
  128. shell_print(shell, "Stored actlog %d erased.", file_id);
  129. } else {
  130. err_ret:
  131. shell_print(shell, "Failed to perform erase command: %d", ret);
  132. }
  133. return 0;
  134. }
  135. static int cmd_query_stored_actlog(const struct shell *shell,
  136. size_t argc, char **argv)
  137. {
  138. int ret = 0;
  139. if (argc < 2) {
  140. goto err_ret;
  141. }
  142. uint32_t file_id = strtoul(argv[1], NULL, 16);
  143. ret = act_log_backend_get_used_size(file_id);
  144. shell_print(shell, "Stored actlog found %d bytes.", ret);
  145. return 0;
  146. err_ret:
  147. shell_print(shell, "Failed to perform query: %d", ret);
  148. return 0;
  149. }
  150. static int cmd_set_level_actlog(const struct shell *shell,
  151. size_t argc, char **argv)
  152. {
  153. int ret = 0;
  154. if (argc < 3) {
  155. goto err_ret;
  156. }
  157. uint32_t level = strtoul(argv[2], NULL, 16);
  158. ret = actlog_set_level_filter(argv[1], level);
  159. shell_print(shell, "Set actlog module %s level %d ret %d", argv[1], level, ret);
  160. return 0;
  161. err_ret:
  162. shell_print(shell, "Failed to set level: %d", ret);
  163. return 0;
  164. }
  165. static int cmd_set_num_actlog(const struct shell *shell,
  166. size_t argc, char **argv)
  167. {
  168. int ret = 0;
  169. if (argc < 5) {
  170. goto err_ret;
  171. }
  172. uint8_t enable = strtoul(argv[2], NULL, 16);
  173. uint16_t log_num = strtoul(argv[3], NULL, 16);
  174. uint16_t limit_time = strtoul(argv[4], NULL, 16);
  175. ret = actlog_set_module_num_filter(argv[1], enable, log_num, limit_time);
  176. shell_print(shell, "Set actlog module %s enable %d max num %d time %d ret %d", argv[1], enable, log_num, limit_time, ret);
  177. return 0;
  178. err_ret:
  179. shell_print(shell, "Failed to set num: %d", ret);
  180. return 0;
  181. }
  182. static int cmd_get_info_actlog(const struct shell *shell,
  183. size_t argc, char **argv)
  184. {
  185. actlog_dump_runtime_info();
  186. return 0;
  187. }
  188. void act_log_runtime_flush_enable(int enable);
  189. static int cmd_runtime_log_enable(const struct shell *shell,
  190. size_t argc, char **argv)
  191. {
  192. if (argc != 2) {
  193. printk("usage: rt_log enable/disable\n");
  194. return -1;
  195. }
  196. #ifdef CONFIG_ACTLOG_OUTPUT_BINARY
  197. if (!strcmp(argv[1], "enable")) {
  198. act_log_runtime_flush_enable(1);
  199. }else{
  200. act_log_runtime_flush_enable(0);
  201. }
  202. #endif
  203. return 0;
  204. }
  205. #if 0
  206. static int cmd_test_actlog(const struct shell *shell,
  207. size_t argc, char **argv)
  208. {
  209. log_test();
  210. return 0;
  211. }
  212. #endif
  213. SHELL_STATIC_SUBCMD_SET_CREATE(sub_actlog,
  214. SHELL_CMD(find, NULL,
  215. "Query if there is a stored actlog",
  216. cmd_query_stored_actlog),
  217. SHELL_CMD(erase, NULL,
  218. "Erase stored actlog",
  219. cmd_erase_actlog_dump),
  220. SHELL_CMD(print, NULL,
  221. "Print stored actlog to shell",
  222. cmd_print_stored_actlog),
  223. SHELL_CMD(level, NULL,
  224. "Set level filter actlog to shell",
  225. cmd_set_level_actlog),
  226. SHELL_CMD(num, NULL,
  227. "Set num filter actlog to shell",
  228. cmd_set_num_actlog),
  229. SHELL_CMD(info, NULL,
  230. "get actlog info to shell",
  231. cmd_get_info_actlog),
  232. SHELL_CMD(rt_log, NULL,
  233. "runtime log enable/disable save log to flash",
  234. cmd_runtime_log_enable),
  235. #if 0
  236. SHELL_CMD(test, NULL,
  237. "test actlog",
  238. cmd_test_actlog),
  239. #endif
  240. SHELL_SUBCMD_SET_END /* Array terminated. */
  241. );
  242. SHELL_CMD_REGISTER(actlog, &sub_actlog,
  243. "actlog commands (flash partition backend)", NULL);
  244. #endif /* CONFIG_DEBUG_COREDUMP_SHELL */