rt_printf.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: rt_printf.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2020-06-18
  7. 功能说明: 打印输出功能。
  8. 其它说明:
  9. 修改记录:
  10. */
  11. /*------------------------------- 头文件 --------------------------------------
  12. */
  13. #include <rt.h>
  14. #include <sys/time.h>
  15. #include <stdarg.h>
  16. #include "head.h"
  17. #include <arpa/inet.h>
  18. #include "rt_printf.h"
  19. #include <sys/prctl.h>
  20. /*------------------------------- 宏定义 --------------------------------------
  21. */
  22. #define PRINTF_BUF_SIZE (16 * 1024)
  23. /*------------------------------ 类型结构 -------------------------------------
  24. */
  25. typedef struct
  26. {
  27. unsigned short year;
  28. unsigned char month;
  29. unsigned char day;
  30. unsigned char hour;
  31. unsigned char minute;
  32. unsigned char second;
  33. unsigned char week;
  34. unsigned int us; // 微锟斤拷
  35. } CO_TIME;
  36. static pthread_t printf_tid = 0;
  37. static int exit_flag = 0;
  38. static uint8_t p_buf[PRINTF_BUF_SIZE]; // 输出
  39. static uint8_t p_buf_s[PRINTF_BUF_SIZE]; // 源
  40. static char printf_buf[PRINTF_BUF_SIZE];
  41. static uint32_t w_p = 0; // 写指针
  42. static uint32_t r_p = 0; // 读指针
  43. static pthread_mutex_t printf_mutex;
  44. extern int main_mod_is_exit(void);
  45. void sys_gettime_tm(CO_TIME *tm_t)
  46. {
  47. struct tm *p;
  48. struct timeval tv;
  49. gettimeofday(&tv, NULL);
  50. // p=gmtime(&tv.tv_sec);
  51. p = localtime(&tv.tv_sec);
  52. tm_t->year = 1900 + p->tm_year; // tm_year锟斤拷锟斤拷1900为锟斤拷愕斤拷锟斤拷诘锟斤拷锟斤拷锟斤拷锟?
  53. // printf("year=%d",tm_t->year);
  54. tm_t->month = p->tm_mon + 1; // tm_mon锟斤拷值锟斤拷围0-11锟斤拷
  55. // printf("month=%d",tm_t->month);
  56. tm_t->day = p->tm_mday;
  57. // printf("day=%d",tm_t->day);
  58. tm_t->hour = p->tm_hour;
  59. // printf("hour=%d",tm_t->hour);
  60. tm_t->minute = p->tm_min;
  61. // printf("minute=%d",tm_t->minute);
  62. tm_t->second = p->tm_sec;
  63. // printf("second=%d",tm_t->second);
  64. tm_t->week = p->tm_wday;
  65. // printf("week=%d",tm_t->week);
  66. tm_t->us = tv.tv_usec;
  67. // printf("us=%d\n",tm_t->us);
  68. }
  69. void sys_gettime_CP56(CP56_TIME2A *tm_t)
  70. {
  71. CO_TIME co_tm_t;
  72. sys_gettime_tm(&co_tm_t);
  73. tm_t->time_t.year = (unsigned char)(co_tm_t.year - 2000);
  74. tm_t->time_t.month = co_tm_t.month;
  75. tm_t->time_t.day = co_tm_t.day;
  76. tm_t->time_t.week = co_tm_t.week;
  77. tm_t->time_t.hour = co_tm_t.hour;
  78. tm_t->time_t.min = co_tm_t.minute;
  79. tm_t->time_t.ms = co_tm_t.second * 1000 + co_tm_t.us / 1000;
  80. }
  81. // 把印时间,具体在那个文件和行号
  82. void co_printf(const char *fp, const int line)
  83. {
  84. char sDebug[1024];
  85. char *ptr = NULL;
  86. struct timespec ts;
  87. struct rtc_time_t pt;
  88. // CP56_TIME2A Clock_u;
  89. memset(sDebug, '\0', sizeof(sDebug));
  90. // sys_gettime_CP56(&Clock_u);
  91. gps_get_time(&ts);
  92. timespec_to_rtc(ts, &pt, 1);
  93. sprintf(sDebug, "%04d-%02d-%02d %02d:%02d:%02d:%03d ", pt.year + 2000, pt.month,
  94. pt.day, pt.hour, pt.min, pt.ms / 1000, pt.ms % 1000);
  95. ptr = strrchr(fp, '/');
  96. if (ptr)
  97. {
  98. sprintf(sDebug + strlen(sDebug), "%s[%d]:", ptr + 1, line);
  99. }
  100. else
  101. {
  102. sprintf(sDebug + strlen(sDebug), "%s[%d]:", fp, line);
  103. }
  104. rt_printf(sDebug);
  105. }
  106. // 可变参形式进行实现myprintf
  107. int myprintf(const char *fmt, ...)
  108. {
  109. char buf[1024];
  110. va_list args;
  111. int printed;
  112. va_start(args, fmt);
  113. printed = vsprintf(buf, fmt, args);
  114. va_end(args);
  115. rt_printf(buf);
  116. return printed;
  117. }
  118. void rt_printf_time2(struct timespec ts)
  119. {
  120. struct rtc_time_t tm;
  121. timespec_to_rtc(ts, &tm, 0);
  122. rt_printf("%04d-%02d-%02d %02d:%02d:%02d:%09d!\r\n",
  123. tm.year + 2000,
  124. tm.month,
  125. tm.day,
  126. tm.hour,
  127. tm.min,
  128. tm.ms / 1000,
  129. ts.tv_nsec);
  130. return;
  131. }
  132. /******************************************************************************
  133. 函数名称: print_mem
  134. 函数版本: 01.01
  135. 创建作者: sunxi
  136. 创建日期: 2020-06-18
  137. 函数说明: 以十六进制的方式显示内存的内容
  138. 参数说明:
  139. addr: 输出内容的起始地址
  140. len: 输出内容的长度
  141. 返回值: 无
  142. 修改记录:
  143. */
  144. void print_mem(char *name, void *addr, unsigned int len)
  145. {
  146. int once;
  147. int i, name_len;
  148. if (name)
  149. {
  150. rt_printf(name);
  151. name_len = strlen(name);
  152. }
  153. else
  154. {
  155. rt_printf("addr=0x%08x,len=%d\r\n", (unsigned int)addr, len);
  156. name_len = 10;
  157. }
  158. while (1)
  159. {
  160. once = len < 16 ? len : 16;
  161. if (!name)
  162. {
  163. rt_printf("%08x:", (unsigned int)addr);
  164. }
  165. for (i = 0; i < once; i++)
  166. {
  167. if (i == 8)
  168. rt_printf(" "); // 使用2个空格,不使用"-",因为规约解析工具不支持"-".
  169. rt_printf(" %02x", *(unsigned char *)addr++);
  170. }
  171. rt_printf("\r\n");
  172. len -= once;
  173. if (len == 0)
  174. {
  175. break;
  176. }
  177. // 打印对齐空格
  178. for (i = 0; i < name_len; i++)
  179. {
  180. rt_printf(" ");
  181. }
  182. }
  183. return;
  184. }
  185. void print_mem_time(char *name, void *addr, unsigned int len)
  186. {
  187. struct rtc_time_t tm;
  188. struct timespec ts;
  189. char buf[64];
  190. clk_time_get(&ts);
  191. timespec_to_rtc(ts, &tm, 0);
  192. if (name)
  193. {
  194. sprintf(buf,
  195. "%s(%04d-%02d-%02d %02d:%02d:%02d:%06ld)",
  196. name,
  197. tm.year + 2000,
  198. tm.month,
  199. tm.day,
  200. tm.hour,
  201. tm.min,
  202. tm.ms / 1000,
  203. ts.tv_nsec / 1000);
  204. }
  205. else
  206. {
  207. sprintf(buf,
  208. "mem(%04d-%02d-%02d %02d:%02d:%05d)",
  209. tm.year + 2000,
  210. tm.month,
  211. tm.day,
  212. tm.hour,
  213. tm.min,
  214. tm.ms);
  215. }
  216. print_mem(buf, addr, len);
  217. }
  218. // int g_print_time = 0;
  219. void print_msg(char *name, void *addr, unsigned int len)
  220. {
  221. if (g_print_time)
  222. {
  223. print_mem_time(name, addr, len);
  224. }
  225. else
  226. {
  227. print_mem(name, addr, len);
  228. }
  229. }
  230. int rt_printf(const char *fmt, ...)
  231. {
  232. #if 0
  233. char pbuf[1024];
  234. va_list args;
  235. int printed;
  236. va_start(args, fmt);
  237. printed = vsprintf(pbuf, fmt, args);
  238. va_end(args);
  239. //直接打印
  240. printf(pbuf);
  241. #else
  242. // 放入显示缓冲区
  243. va_list args;
  244. int length, byte;
  245. va_start(args, fmt);
  246. vsnprintf(printf_buf, PRINTF_BUF_SIZE, (char *)fmt, args);
  247. va_end(args);
  248. length = strlen(printf_buf);
  249. pthread_mutex_lock(&printf_mutex);
  250. if ((w_p + length) < PRINTF_BUF_SIZE)
  251. {
  252. memcpy((uint8_t *)&p_buf_s[w_p], (uint8_t *)printf_buf, length);
  253. w_p += length;
  254. }
  255. else
  256. {
  257. byte = PRINTF_BUF_SIZE - w_p;
  258. memcpy((uint8_t *)&p_buf_s[w_p], (uint8_t *)printf_buf, byte);
  259. w_p = length - byte;
  260. memcpy((uint8_t *)p_buf_s, (uint8_t *)&printf_buf[byte], w_p);
  261. }
  262. // printf("-----test printf----wp=%d---%s",w_p, printf_buf);
  263. pthread_mutex_unlock(&printf_mutex);
  264. #endif
  265. return 0;
  266. }
  267. /******************************************************************************
  268. 函数名称: rt_printf_func
  269. 函数版本: 01.01
  270. 创建作者: sunxi
  271. 创建日期: 2022-5-31
  272. 函数说明: 打印工作函数.
  273. 参数说明:
  274. 返回值: 返回0
  275. 修改记录:
  276. */
  277. static int rt_printf_func(void *arg)
  278. {
  279. int len = 0;
  280. int len_1 = 0;
  281. memset(p_buf, 0, sizeof(p_buf));
  282. memset(p_buf_s, 0, sizeof(p_buf_s));
  283. w_p = 0;
  284. r_p = 0;
  285. pthread_mutex_init(&printf_mutex, NULL);
  286. #if 0
  287. strcpy(&p_buf[w_p],test_1);
  288. w_p += strlen(test_1);
  289. strcpy(&p_buf[w_p],test_2);
  290. w_p += strlen(test_2);
  291. strcpy(&p_buf[w_p],test_3);
  292. w_p += strlen(test_3);
  293. rt_printf(p_buf);
  294. #endif
  295. uint32_t wdt_id;
  296. int rc = watchdog_add_item("rt_printf_func", &wdt_id, 120);
  297. if (rc != 0)
  298. {
  299. printf("can not add rt_printf_func task to wdt\r\n");
  300. return 0;
  301. }
  302. prctl(PR_SET_NAME, "rt_printf_func");
  303. while (!exit_flag)
  304. {
  305. msleep(10);
  306. watchdog_feed(wdt_id);
  307. if (main_mod_is_exit())
  308. {
  309. break;
  310. }
  311. // rt_printf("w_p = %d, r_p = %d\r\n",w_p,r_p);
  312. pthread_mutex_lock(&printf_mutex);
  313. len = 0;
  314. len_1 = 0;
  315. if (w_p != r_p)
  316. {
  317. memset(p_buf, 0, sizeof(p_buf));
  318. // 获取打印信息
  319. if (w_p > r_p)
  320. {
  321. len = w_p - r_p;
  322. memcpy(p_buf, &p_buf_s[r_p], len);
  323. r_p += len;
  324. }
  325. else
  326. {
  327. // w_p指针翻滚,过0
  328. // 分两段读取,再合并
  329. len = PRINTF_BUF_SIZE - r_p;
  330. memcpy(p_buf, &p_buf_s[r_p], len);
  331. r_p += len;
  332. len_1 = w_p;
  333. memcpy(&p_buf[len], p_buf_s, len_1);
  334. r_p = len_1;
  335. }
  336. if (r_p >= PRINTF_BUF_SIZE)
  337. r_p = 0;
  338. p_buf[sizeof(p_buf) - 1] = 0; // 保证结束
  339. }
  340. pthread_mutex_unlock(&printf_mutex);
  341. if ((len > 0) || (len_1 > 0))
  342. {
  343. // noted by sunxi: 20221122 重定向6000端口打印
  344. if (g_print_to_net)
  345. {
  346. net_debug_send(p_buf, sizeof(p_buf));
  347. // return 0;
  348. }
  349. else
  350. {
  351. printf(p_buf);
  352. // printf("\r\n");
  353. }
  354. }
  355. }
  356. watchdog_remove_item(wdt_id);
  357. return 0;
  358. }
  359. /******************************************************************************
  360. 函数名称: rt_printf_init
  361. 函数版本: 01.01
  362. 创建作者: sunxi
  363. 创建日期: 2022-5-31
  364. 函数说明: 初始化.
  365. 参数说明:
  366. 返回值: 成功返回0, 失败返回-1
  367. 修改记录:
  368. */
  369. int rt_printf_init(void)
  370. {
  371. int ret;
  372. ret = pthread_create(&printf_tid, NULL, (void *)rt_printf_func, NULL);
  373. if (ret)
  374. {
  375. printf("ret = %d, err = %s\r\n", ret, strerror(ret));
  376. printf_tid = 0;
  377. return ret;
  378. }
  379. return 0;
  380. }
  381. /******************************************************************************
  382. 函数名称: rt_printf_exit
  383. 函数版本: 01.01
  384. 创建作者: sunxi
  385. 创建日期: 2022-5-31
  386. 函数说明: 反初始化.
  387. 参数说明:
  388. 返回值: 总是返回0.
  389. 修改记录:
  390. */
  391. int rt_printf_exit(void)
  392. {
  393. exit_flag = 1;
  394. pthread_join(printf_tid, NULL);
  395. return 0;
  396. }
  397. /*------------------------------ 测试函数 -------------------------------------
  398. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  399. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  400. */
  401. /*------------------------------ 文件结束 -------------------------------------
  402. */