act_log.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. #include <init.h>
  2. #include "act_log_inner.h"
  3. #include <linker/linker-defs.h>
  4. #include <debug/actions_exception.h>
  5. #include <drivers/flash.h>
  6. #include <board_cfg.h>
  7. actlog_ctrl_t actlog_ctrl;
  8. static OS_THREAD_STACK_DEFINE(actlog_thread_stack, ACTLOG_THREAD_STACK_SIZE);
  9. static uint8_t log_line_buf[CONFIG_ACTLOG_LINEBUF_SIZE];
  10. const char * const nano_args = "0123456789abcI";
  11. static const char act_loglevel_info[] =
  12. {
  13. 'N', //NONE
  14. 'E', //Error
  15. 'W', //Warn
  16. 'I', //Info
  17. 'D', //Debug
  18. };
  19. static int actlog_module_id_get(const char *name)
  20. {
  21. uint32_t modules_cnt = actlog_module_num_get();
  22. const char *tmp_name;
  23. uint32_t i;
  24. for (i = 0U; i < modules_cnt; i++) {
  25. tmp_name = actlog_source_name_get(i);
  26. if (tmp_name && strncmp(tmp_name, name, 64) == 0) {
  27. return i;
  28. }
  29. }
  30. return -1;
  31. }
  32. static void act_log_module_level_init(actlog_ctrl_t *ctrl)
  33. {
  34. uint32_t i;
  35. uint8_t compile_level;
  36. uint32_t modules_cnt = actlog_module_num_get();
  37. uint32_t level_bytes = ROUND_UP(modules_cnt, 2) >> 1;
  38. ctrl->module_level = (uint8_t *)mem_malloc(level_bytes);
  39. if(!ctrl->module_level){
  40. return;
  41. }
  42. memset(ctrl->module_level, 0, level_bytes);
  43. for (i = 0; i < modules_cnt; i++) {
  44. compile_level = actlog_compiled_level_get(i);
  45. actlog_dynamic_level_set(ctrl, i, compile_level);
  46. }
  47. }
  48. static int act_log_get_output_mode(void)
  49. {
  50. return actlog_ctrl.output_mode;
  51. }
  52. static uint32_t log_hex_dump_data(const char *data, int length, char *log_buffer, uint32_t buffer_size)
  53. {
  54. int index = 0;
  55. uint32_t curr_index;
  56. curr_index = 0;
  57. for (index = 0; index < length; index++) {
  58. curr_index += snprintk(&log_buffer[curr_index], (buffer_size - curr_index), "%02X", (int)(data[index]));
  59. if ((index + 1) % 16 == 0) {
  60. curr_index += snprintk(&log_buffer[curr_index], (buffer_size - curr_index), "\n");
  61. continue;
  62. }
  63. if (index + 1 != length) {
  64. curr_index += snprintk(&log_buffer[curr_index], (buffer_size - curr_index), " ");
  65. }
  66. }
  67. if (0 != index && 0 != index % 16) {
  68. curr_index += snprintk(&log_buffer[curr_index], (buffer_size - curr_index), "\n");
  69. }
  70. return curr_index;
  71. }
  72. static uint32_t log_nano_dump_data(const char *fmt, int arg_num, uint32_t *arg_value, char *log_buffer, uint32_t buffer_size)
  73. {
  74. int32_t index = 0;
  75. switch (arg_num) {
  76. case 0:
  77. index = strlen(fmt);
  78. if (index > buffer_size) {
  79. index = buffer_size;
  80. }
  81. strncpy(log_buffer, fmt, index);
  82. break;
  83. case 1:
  84. index = snprintk(log_buffer, buffer_size, fmt, arg_value[0]);
  85. break;
  86. case 2:
  87. index = snprintk(log_buffer, buffer_size, fmt, arg_value[0], arg_value[1]);
  88. break;
  89. case 3:
  90. index = snprintk(log_buffer, buffer_size, fmt, arg_value[0], arg_value[1], arg_value[2]);
  91. break;
  92. case 4:
  93. index = snprintk(log_buffer, buffer_size, fmt, arg_value[0], arg_value[1], arg_value[2], arg_value[3]);
  94. break;
  95. case 5:
  96. index = snprintk(log_buffer, buffer_size, fmt, arg_value[0], arg_value[1], arg_value[2], arg_value[3], arg_value[4]);
  97. break;
  98. case 6:
  99. index = snprintk(log_buffer, buffer_size, fmt, arg_value[0], arg_value[1], arg_value[2], arg_value[3], arg_value[4], \
  100. arg_value[5]);
  101. case 7:
  102. index = snprintk(log_buffer, buffer_size, fmt, arg_value[0], arg_value[1], arg_value[2], arg_value[3], arg_value[4], \
  103. arg_value[5], arg_value[6]);
  104. case 8:
  105. index = snprintk(log_buffer, buffer_size, fmt, arg_value[0], arg_value[1], arg_value[2], arg_value[3], arg_value[4], \
  106. arg_value[5], arg_value[6], arg_value[7]);
  107. case 9:
  108. index = snprintk(log_buffer, buffer_size, fmt, arg_value[0], arg_value[1], arg_value[2], arg_value[3], arg_value[4], \
  109. arg_value[5], arg_value[6], arg_value[7], arg_value[8]);
  110. case 10:
  111. index = snprintk(log_buffer, buffer_size, fmt, arg_value[0], arg_value[1], arg_value[2], arg_value[3], arg_value[4], \
  112. arg_value[5], arg_value[6], arg_value[7], arg_value[8], arg_value[9]);
  113. break;
  114. default:
  115. break;
  116. }
  117. if (index < 0) {
  118. index = 0;
  119. }
  120. if (index >= (buffer_size - 3)) {
  121. log_buffer[buffer_size - 3] = '\r';
  122. log_buffer[buffer_size - 2] = '\n';
  123. log_buffer[buffer_size - 1] = '\0';
  124. } else {
  125. log_buffer[index++] = '\r';
  126. log_buffer[index++] = '\n';
  127. log_buffer[index++] = '\0';
  128. }
  129. return index;
  130. }
  131. uint32_t process_log_linebuf(log_message_t *log_msg, char *log_buffer, uint32_t buffer_size)
  132. {
  133. uint32_t curr_index;
  134. curr_index = 0;
  135. #ifdef CONFIG_ACTLOG_SHOW_FUNCTION
  136. if(IS_ENABLED(CONFIG_ACTLOG_SHOW_TIMESTAMP)){
  137. curr_index += snprintk(log_buffer, buffer_size,
  138. "[%u][%s][%c][%s][%d]: ",
  139. log_msg->normal.timestamp,
  140. actlog_source_name_get(log_msg->normal.id),
  141. act_loglevel_info[log_msg->normal.level],
  142. log_msg->normal.func_name,
  143. log_msg->normal.line_number);
  144. }else{
  145. curr_index += snprintk(log_buffer, buffer_size,
  146. "[%s][%c][%s][%d]: ",
  147. actlog_source_name_get(log_msg->normal.id),
  148. act_loglevel_info[log_msg->normal.level],
  149. log_msg->normal.func_name,
  150. log_msg->normal.line_number);
  151. }
  152. #else
  153. if(IS_ENABLED(CONFIG_ACTLOG_SHOW_TIMESTAMP)){
  154. curr_index += snprintk(log_buffer, buffer_size,
  155. "[%u][%s][%c][%d]: ",
  156. log_msg->normal.timestamp,
  157. actlog_source_name_get(log_msg->normal.id),
  158. act_loglevel_info[log_msg->normal.level],
  159. log_msg->normal.line_number);
  160. }else{
  161. curr_index += snprintk(log_buffer, buffer_size,
  162. "[%s][%c][%d]: ",
  163. actlog_source_name_get(log_msg->normal.id),
  164. act_loglevel_info[log_msg->normal.level],
  165. log_msg->normal.line_number);
  166. }
  167. #endif
  168. if(log_msg->normal.type == ACTLOG_MSG_LOG){
  169. curr_index += snprintk(&log_buffer[curr_index], (buffer_size - curr_index),
  170. "%s\n", log_msg->normal.fmt_data);
  171. }else if(log_msg->normal.type == ACTLOG_MSG_HEXDUMP){
  172. curr_index += log_hex_dump_data(log_msg->hex.data, log_msg->hex.data_len, &log_buffer[curr_index], (buffer_size - curr_index));
  173. }else if(log_msg->normal.type == ACTLOG_MSG_NANO_LOG){
  174. curr_index += log_nano_dump_data(log_msg->nano.fmt, log_msg->nano.arg_num, log_msg->nano.arg_value, \
  175. &log_buffer[curr_index], (buffer_size - curr_index));
  176. }
  177. return curr_index;
  178. }
  179. static void save_log_message(log_message_t *log_msg)
  180. {
  181. uint32_t log_line_cnt;
  182. log_line_cnt = process_log_linebuf(log_msg, log_line_buf, sizeof(log_line_buf));
  183. act_log_backend_output(log_msg, log_line_buf, log_line_cnt);
  184. }
  185. static void process_log_message(log_message_t *log_msg)
  186. {
  187. save_log_message(log_msg);
  188. }
  189. void actlog_log_handler(actlog_ctrl_t *ctrl)
  190. {
  191. int len = 0;
  192. uint32_t irq_flag;
  193. uint32_t buf_size;
  194. log_message_t log_msg;
  195. #ifdef CONFIG_ACTLOG_PRINT_DROP_COUNT
  196. uint32_t drop_cnt;
  197. irq_flag = irq_lock();
  198. drop_cnt = ctrl->drop_cnt;
  199. if (ctrl->drop_cnt) {
  200. ctrl->drop_cnt = 0;
  201. }
  202. irq_unlock(irq_flag);
  203. if (IS_ENABLED(CONFIG_ACTLOG_PRINT_DROP_COUNT)){
  204. if (drop_cnt){
  205. printk("\t\t>>>log drop:%u\r\n\n", drop_cnt);
  206. }
  207. }
  208. #endif
  209. while (ring_buf_size_get(&ctrl->rbuf) >= sizeof(log_message_head_t)) {
  210. buf_size = ring_buf_size_get(&ctrl->rbuf);
  211. if (ring_buf_get(&ctrl->rbuf, (uint8_t *)&log_msg, sizeof(log_message_head_t)) != sizeof(log_message_head_t)) {
  212. printk("read head data err\n");
  213. continue;
  214. }
  215. if (log_msg.nano.type >= ACTLOG_MAX_MSG_TYPE || log_msg.nano.level == 0) {
  216. printk("read head err:%x %x %x %x\n", log_msg.nano.type, log_msg.nano.level, ring_buf_size_get(&ctrl->rbuf), buf_size);
  217. irq_flag = irq_lock();
  218. ring_buf_reset(&ctrl->rbuf);
  219. irq_unlock(irq_flag);
  220. ctrl->err_cnt++;
  221. break;
  222. }
  223. if (log_msg.nano.type == ACTLOG_MSG_NANO_LOG){
  224. len = (log_msg.nano.arg_num + 1) << 2;
  225. if (ring_buf_get(&ctrl->rbuf, (uint8_t *)&log_msg.nano.fmt, len) != len) {
  226. printk("read data err:%x %x\n", log_msg.nano.arg_num, len);
  227. continue;
  228. }
  229. }else if(log_msg.normal.type == ACTLOG_MSG_LOG){
  230. len = log_msg.normal.str_len;
  231. if (ring_buf_get(&ctrl->rbuf, (uint8_t *)&log_msg.normal.fmt_data, len) != len) {
  232. printk("read data err: %x\n", len);
  233. continue;
  234. }
  235. }else{
  236. continue;
  237. }
  238. process_log_message(&log_msg);
  239. }
  240. }
  241. static void actlog_task_entry(void *p1, void *p2, void *p3)
  242. {
  243. actlog_ctrl.task_ready = true;
  244. while(1){
  245. os_sem_take(&actlog_ctrl.log_sem, OS_FOREVER);
  246. actlog_log_handler(&actlog_ctrl);
  247. }
  248. }
  249. void actlog_exception_init_cb(void)
  250. {
  251. if(actlog_ctrl.panic){
  252. return;
  253. }
  254. #ifdef CONFIG_ACTIONS_PRINTK_DMA
  255. printk_dma_switch(0);
  256. #endif
  257. if (IS_ENABLED(CONFIG_ACTLOG_OUTPUT_BINARY)) {
  258. if((act_log_get_output_mode() & ACTLOG_OUTPUT_MODE_BINARY) == 0){
  259. act_log_output_binary_init();
  260. }
  261. actlog_ctrl.output_mode = ACTLOG_OUTPUT_MODE_FLOW | ACTLOG_OUTPUT_MODE_BINARY;
  262. }
  263. printk("%s ringbuf size %d\n", __FUNCTION__, ring_buf_size_get(&actlog_ctrl.rbuf));
  264. actlog_ctrl.panic = true;
  265. actlog_log_handler(&actlog_ctrl);
  266. //flush flash ringbuf data to flash
  267. act_log_backend_flush();
  268. }
  269. int cmd_print_actlog(int file_id);
  270. #if IS_ENABLED(CONFIG_SIM_FLASH_ACTS)
  271. static void save_log_to_sram(void)
  272. {
  273. struct device *sim_dev;
  274. char *sram_buf = __sim_flash_ram_start;
  275. sim_dev = (struct device *)device_get_binding(CONFIG_SIM_FLASH_NAME);
  276. if (!sim_dev) {
  277. printk("log save err\n");
  278. return;
  279. }
  280. printk("system panic! save simflash log 0x%p,0x%x\n", sram_buf, CONFIG_SIM_FLASH_SIZE);
  281. flash_read(sim_dev, 0, sram_buf, CONFIG_SIM_FLASH_SIZE);
  282. }
  283. #endif
  284. void actlog_exception_run_cb(void)
  285. {
  286. printk("%s ringbuf size %d\n", __FUNCTION__, ring_buf_size_get(&actlog_ctrl.rbuf));
  287. actlog_log_handler(&actlog_ctrl);
  288. //flush flash ringbuf data to flash
  289. act_log_backend_flush();
  290. //extra data only print by flow, not save in flash
  291. actlog_ctrl.output_mode = ACTLOG_OUTPUT_MODE_FLOW;
  292. //cmd_print_actlog(ACTLOG_FILE_TYPE_LOG);
  293. #if IS_ENABLED(CONFIG_SIM_FLASH_ACTS)
  294. save_log_to_sram();
  295. #endif
  296. }
  297. int act_log_init(void)
  298. {
  299. actlog_ctrl_t *ctrl = (actlog_ctrl_t *)&actlog_ctrl;
  300. actions_exception_callback_routine_t actlog_exc_cb;
  301. //only init once
  302. if(ctrl->init_flag){
  303. return 0;
  304. }
  305. os_sem_init(&ctrl->log_sem, 0, 1);
  306. ring_buf_init(&ctrl->rbuf, 4096, ctrl->cache_buffer);
  307. ctrl->module_cnt = actlog_module_num_get();
  308. ctrl->task_ready = false;
  309. ctrl->output_mode = 0;
  310. ctrl->level = ACTLOG_LEVEL_INFO;
  311. ctrl->thread_id = os_thread_create((char *)actlog_thread_stack,
  312. ACTLOG_THREAD_STACK_SIZE,
  313. actlog_task_entry,
  314. NULL, NULL, NULL,
  315. K_LOWEST_APPLICATION_THREAD_PRIO, 0, OS_NO_WAIT);
  316. os_thread_name_set((struct k_thread *)ctrl->thread_id, "actlog");
  317. act_log_backend_init();
  318. printk("log used size %d\n", act_log_backend_get_used_size(0));
  319. act_log_module_level_init(ctrl);
  320. ctrl->init_flag = true;
  321. actlog_exc_cb.init_cb = actlog_exception_init_cb;
  322. actlog_exc_cb.run_cb = actlog_exception_run_cb;
  323. exception_register_callbacks(&actlog_exc_cb);
  324. return 0;
  325. }
  326. int act_log_register_output_backend(uint8_t mode, actlog_backend_callback_t callback, void *user_data)
  327. {
  328. int ret;
  329. if (callback == NULL) {
  330. return -EINVAL;
  331. }
  332. if (actlog_ctrl.output_mode & mode) {
  333. return -EALREADY;
  334. }
  335. ret = act_log_backend_register(mode, callback, user_data);
  336. if (ret == 0) {
  337. actlog_ctrl.output_mode |= mode;
  338. }
  339. return ret;
  340. }
  341. int act_log_unregister_output_backend(uint8_t mode)
  342. {
  343. if (actlog_ctrl.output_mode & mode) {
  344. act_log_backend_unregister(mode);
  345. actlog_ctrl.output_mode &= ~mode;
  346. return 0;
  347. }
  348. return -EINVAL;
  349. }
  350. uint32_t act_log_check_filter(uint8_t module_id, uint8_t level)
  351. {
  352. uint8_t log_num;
  353. uint32_t cur_time;
  354. act_log_num_filter_t *filter;
  355. if (!actlog_ctrl.init_flag){
  356. return false;
  357. }
  358. if ((level > actlog_ctrl.level) || (module_id >= actlog_ctrl.module_cnt)) {
  359. return true;
  360. }
  361. if (level > actlog_dynamic_level_get(&actlog_ctrl, module_id)){
  362. return true;
  363. }
  364. filter = &actlog_ctrl.filter;
  365. if (!filter->enable || filter->id != module_id){
  366. return false;
  367. }
  368. if (filter->base_time == 0) {
  369. filter->base_time = os_uptime_get_32();
  370. }
  371. cur_time = os_uptime_get_32();
  372. filter->line_num++;
  373. log_num = filter->line_num;
  374. if ((cur_time < filter->base_time) || ((cur_time - filter->base_time) >= filter->limit_time)) {
  375. filter->base_time = cur_time;
  376. filter->line_num = 0;
  377. } else {
  378. if (log_num > filter->max_line_num) {
  379. return true;
  380. }
  381. }
  382. return false;
  383. }
  384. int actlog_set_level_filter(const char *module_name, uint32_t dynamic_level)
  385. {
  386. int id;
  387. if (dynamic_level >= ACTLOG_LEVEL_MAX){
  388. printk("invalid level %d\n", dynamic_level);
  389. return -EINVAL;
  390. }
  391. printk("set module %s level %d\n", module_name, dynamic_level);
  392. if (strcmp(module_name, "all") == 0) {
  393. actlog_ctrl.level = dynamic_level;
  394. } else {
  395. id = actlog_module_id_get(module_name);
  396. /* no match tag name found */
  397. if (id < 0) {
  398. return -1;
  399. }
  400. actlog_dynamic_level_set(&actlog_ctrl, id, dynamic_level);
  401. }
  402. return 0;
  403. }
  404. int actlog_set_module_num_filter(const char *module_name, uint8_t enable, uint8_t max_log_num, uint16_t limit_time)
  405. {
  406. int id;
  407. act_log_num_filter_t *filter;
  408. id = actlog_module_id_get(module_name);
  409. /* no match tag name found */
  410. if (id < 0) {
  411. return -1;
  412. }
  413. filter = &actlog_ctrl.filter;
  414. filter->id = id;
  415. filter->enable = enable;
  416. filter->limit_time = limit_time;
  417. filter->max_line_num = max_log_num;
  418. return 0;
  419. }
  420. int act_log_is_const_ptr(const char *fmt)
  421. {
  422. return ((fmt >= (const char *)__rom_region_start) &&
  423. (fmt < (const char *)__rom_region_end));
  424. }
  425. //parse:%x,%X,%d,%u,%i,%c,%p,%s
  426. uint32_t act_log_check_fmt_string_is_valid(va_list args, const char *fmt, uint8_t *arg_num)
  427. {
  428. int i, j, parse_end;
  429. const char *ptr;
  430. int parse_arg_num = 0;
  431. if(!arg_num){
  432. return true;
  433. }
  434. for (i = 0; fmt[i] != '\0'; i++) {
  435. if (fmt[i] != '%') {
  436. continue;
  437. }
  438. if (fmt[i + 1] == '%') {
  439. continue;
  440. }
  441. parse_arg_num++;
  442. j = i;
  443. parse_end = false;
  444. while(fmt[j] != '\0' && !parse_end){
  445. switch(fmt[j]){
  446. case 's':
  447. if ((fmt[j - 1] == '%' || (fmt[j - 1] >= '0' && fmt[j - 1] <= '9'))){
  448. ptr = (const char *)va_arg(args, uint32_t);
  449. if(!act_log_is_const_ptr(ptr)){
  450. return false;
  451. }
  452. parse_end = true;
  453. }
  454. break;
  455. case 'x':
  456. case 'd':
  457. case 'p':
  458. case 'u':
  459. case 'c':
  460. case 'i':
  461. case 'X':
  462. if ((fmt[j - 1] == '%' || (fmt[j - 1] >= '0' && fmt[j - 1] <= '9'))){
  463. ptr = (const char *)va_arg(args, uint32_t);
  464. parse_end = true;
  465. }
  466. break;
  467. default:
  468. break;
  469. }
  470. j++;
  471. }
  472. }
  473. if(parse_arg_num == 0){
  474. *arg_num = 0;
  475. }
  476. return true;
  477. }
  478. void act_log_put_data(void *data, uint32_t len)
  479. {
  480. int irq_flag;
  481. actlog_ctrl_t *ctrl = &actlog_ctrl;
  482. irq_flag = irq_lock();
  483. uint32_t free_space = ring_buf_space_get(&ctrl->rbuf);
  484. if (free_space >= len) {
  485. ring_buf_put(&ctrl->rbuf, data, len);
  486. }else{
  487. ctrl->drop_cnt++;
  488. }
  489. if (k_is_in_isr()){
  490. ctrl->irq_cnt++;
  491. }
  492. irq_unlock(irq_flag);
  493. if(ctrl->panic){
  494. actlog_log_handler(ctrl);
  495. }else{
  496. os_sem_give(&ctrl->log_sem);
  497. }
  498. return;
  499. }
  500. //static char nano_tips[] = "args num err";
  501. static void act_nano_log(uint8_t module_id, uint8_t level, const char *func, uint16_t line, uint8_t arg_num, const char *fmt, va_list args)
  502. {
  503. uint8_t i;
  504. nano_log_message_t nano;
  505. memset(&nano, 0, sizeof(nano_log_message_t));
  506. nano.type = ACTLOG_MSG_NANO_LOG;
  507. nano.id = module_id;
  508. nano.level = level;
  509. nano.line_number = line;
  510. #ifdef CONFIG_ACTLOG_SHOW_FUNCTION
  511. nano.func_name = func;
  512. #endif
  513. if(IS_ENABLED(CONFIG_ACTLOG_SHOW_TIMESTAMP)){
  514. nano.timestamp = os_uptime_get_32();
  515. }
  516. nano.fmt = fmt;
  517. nano.arg_num = arg_num;
  518. for(i = 0; i < arg_num; i++){
  519. nano.arg_value[i] = va_arg(args, uint32_t);
  520. }
  521. //printk("nano %d fmt %s arg %d %x %x\n", line, fmt, arg_num, nano.arg_value[0], nano.arg_value[1]);
  522. //k_fifo_put(&actlog_ctrl.log_input_fifo, (void *)log_msg);
  523. act_log_put_data(&nano, sizeof(log_message_head_t) + ((arg_num + 1) * sizeof(uint32_t)));
  524. }
  525. static void act_normal_log(uint8_t module_id, uint8_t level, const char *func, uint16_t line, const char *fmt, va_list args)
  526. {
  527. int strlen;
  528. int buf_size;
  529. normal_log_message_t normal;
  530. memset(&normal, 0, sizeof(normal));
  531. normal.type = ACTLOG_MSG_LOG;
  532. normal.id = module_id;
  533. normal.level = level;
  534. normal.line_number = line;
  535. #ifdef CONFIG_ACTLOG_SHOW_FUNCTION
  536. normal.func_name = func;
  537. #endif
  538. if(IS_ENABLED(CONFIG_ACTLOG_SHOW_TIMESTAMP)){
  539. normal.timestamp = os_uptime_get_32();
  540. }
  541. strlen = vsnprintk(normal.fmt_data, CONFIG_ACTLOG_FMT_DATA_SIZE, fmt, args);
  542. buf_size = sizeof(normal.fmt_data);
  543. if (strlen >= (buf_size - 3)) {
  544. normal.fmt_data[buf_size - 3] = '\r';
  545. normal.fmt_data[buf_size - 2] = '\n';
  546. normal.fmt_data[buf_size - 1] = '\0';
  547. strlen = buf_size;
  548. } else {
  549. normal.fmt_data[strlen++] = '\r';
  550. normal.fmt_data[strlen++] = '\n';
  551. normal.fmt_data[strlen++] = '\0';
  552. }
  553. normal.str_len = strlen;
  554. act_log_put_data(&normal, sizeof(log_message_head_t) + strlen);
  555. }
  556. #ifdef CONFIG_ACTLOG_SHOW_FUNCTION
  557. void actlog_printk(uint32_t pack_data, const char *func, const char *fmt, ...)
  558. #else
  559. void actlog_printk(uint32_t pack_data, const char *fmt, ...)
  560. #endif
  561. {
  562. act_log_pack_data log_data;
  563. log_data.data = pack_data;
  564. va_list args;
  565. va_start(args, fmt);
  566. if(act_log_check_filter(log_data.bit_data.id, log_data.bit_data.level)){
  567. return;
  568. }
  569. if(!actlog_ctrl.task_ready){
  570. printk("[%s][%c][%d*]:", actlog_source_name_get(log_data.bit_data.id), act_loglevel_info[log_data.bit_data.level], log_data.bit_data.line);
  571. vprintk(fmt, args);
  572. printk("\r\n");
  573. return;
  574. }
  575. #ifdef CONFIG_ACTLOG_SHOW_FUNCTION
  576. act_normal_log(log_data.bit_data.id, log_data.bit_data.level, func, log_data.bit_data.line, fmt, args);
  577. #else
  578. act_normal_log(log_data.bit_data.id, log_data.bit_data.level, NULL, log_data.bit_data.line, fmt, args);
  579. #endif
  580. va_end(args);
  581. }
  582. #ifdef CONFIG_ACTLOG_SHOW_FUNCTION
  583. void actlog_printk_nano(uint32_t pack_data, const char *func, const char *fmt, ...)
  584. #else
  585. void actlog_printk_nano(uint32_t pack_data, const char *fmt, ...)
  586. #endif
  587. {
  588. act_log_pack_data log_data;
  589. log_data.data = pack_data;
  590. uint8_t arg_num;
  591. va_list args;
  592. va_start(args, fmt);
  593. if(act_log_check_filter(log_data.bit_data.id, log_data.bit_data.level)){
  594. //printk("filter print:%d %d\n", log_data.bit_data.id, log_data.bit_data.line);
  595. //vprintk(fmt, args);
  596. //printk("\r\n");
  597. return;
  598. }
  599. if(!actlog_ctrl.task_ready){
  600. printk("[%s][%c][%d*]:", actlog_source_name_get(log_data.bit_data.id), act_loglevel_info[log_data.bit_data.level], log_data.bit_data.line);
  601. vprintk(fmt, args);
  602. printk("\r\n");
  603. return;
  604. }
  605. arg_num = log_data.bit_data.arg_num;
  606. if (arg_num > MAX_NANO_ARG_NUM || !act_log_check_fmt_string_is_valid(args, fmt, &arg_num)){
  607. #ifdef CONFIG_ACTLOG_SHOW_FUNCTION
  608. act_normal_log(log_data.bit_data.id, log_data.bit_data.level, func, log_data.bit_data.line, fmt, args);
  609. #else
  610. act_normal_log(log_data.bit_data.id, log_data.bit_data.level, NULL, log_data.bit_data.line, fmt, args);
  611. #endif
  612. return;
  613. }
  614. #ifdef CONFIG_ACTLOG_SHOW_FUNCTION
  615. act_nano_log(log_data.bit_data.id, log_data.bit_data.level, func, log_data.bit_data.line, arg_num, fmt, args);
  616. #else
  617. act_nano_log(log_data.bit_data.id, log_data.bit_data.level, NULL, log_data.bit_data.line, arg_num, fmt, args);
  618. #endif
  619. va_end(args);
  620. }
  621. void actlog_dump_runtime_info(void)
  622. {
  623. uint32_t i;
  624. actlog_ctrl_t *ctrl = (actlog_ctrl_t *)&actlog_ctrl;
  625. printk("module cnt %d level %d\n", ctrl->module_cnt, ctrl->level);
  626. printk("drop cnt %d err cnt %d\n", ctrl->drop_cnt, ctrl->err_cnt);
  627. printk("rbuf size %d\n", ring_buf_size_get(&ctrl->rbuf));
  628. printk("out mode %d\n", ctrl->output_mode);
  629. printk("filter %s enable:%d log num %d limit time %d\n", actlog_source_name_get(ctrl->filter.id),\
  630. ctrl->filter.enable, ctrl->filter.max_line_num, ctrl->filter.limit_time);
  631. for(i = 0; i < ctrl->module_cnt; i++){
  632. if (actlog_dynamic_level_get(&actlog_ctrl, i) < 5) {
  633. printk("%s level:%c\n", actlog_source_name_get(i), act_loglevel_info[actlog_dynamic_level_get(&actlog_ctrl, i)]);
  634. }
  635. }
  636. }
  637. typedef int (*bt_api_transfer_cb)(uint8_t *data, uint32_t max_len);
  638. bt_api_transfer_cb g_bt_cb = NULL;
  639. static int actlog_bt_callback(uint8_t *data, uint32_t len)
  640. {
  641. uint32_t read_len = 0;
  642. uint32_t str_len;
  643. while(read_len < len){
  644. if(*data){
  645. str_len = actlog_strnlen(data, len - read_len);
  646. //flow output,do not use printk
  647. if(g_bt_cb)
  648. g_bt_cb(data, str_len);
  649. read_len += str_len;
  650. data += str_len;
  651. }else{
  652. data++;
  653. read_len++;
  654. }
  655. }
  656. return 0;
  657. }
  658. int actlog_syslog_transfer(int log_type, int (*traverse_cb)(uint8_t *data, uint32_t max_len))
  659. {
  660. int traverse_len;
  661. int file_id;
  662. /* Print buffer */
  663. char print_buf[CONFIG_ACTLOG_LINEBUF_SIZE];
  664. if(traverse_cb == NULL)
  665. return 0;
  666. if(log_type == LOG_TYPE_SYSLOG)
  667. file_id = ACTLOG_FILE_TYPE_LOG_SAVE;
  668. else
  669. file_id = ACTLOG_FILE_TYPE_RUNTIME_LOG;
  670. //flush flash ringbuf data to flash
  671. act_log_backend_flush();
  672. g_bt_cb = traverse_cb;
  673. traverse_len = act_log_backend_traverse(file_id, actlog_bt_callback, print_buf, sizeof(print_buf));
  674. g_bt_cb = NULL;
  675. return traverse_len;
  676. }
  677. /* The log process thread has the K_LOWEST_APPLICATION_THREAD_PRIO, adjust it
  678. * to a higher priority to increase the chances of being scheduled to handle
  679. * log message as soon as possible
  680. */
  681. void actlog_increase_log_thread_priority(void)
  682. {
  683. actlog_ctrl_t *ctrl = (actlog_ctrl_t *)&actlog_ctrl;
  684. k_thread_priority_set((k_tid_t)ctrl->thread_id, 4);
  685. }
  686. void actlog_decrease_log_thread_priority(void)
  687. {
  688. actlog_ctrl_t *ctrl = (actlog_ctrl_t *)&actlog_ctrl;
  689. k_thread_priority_set((k_tid_t)ctrl->thread_id, K_LOWEST_APPLICATION_THREAD_PRIO);
  690. }