rt_printf.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  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 4096
  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. );
  131. return;
  132. }
  133. /******************************************************************************
  134. 函数名称: print_mem
  135. 函数版本: 01.01
  136. 创建作者: sunxi
  137. 创建日期: 2020-06-18
  138. 函数说明: 以十六进制的方式显示内存的内容
  139. 参数说明:
  140. addr: 输出内容的起始地址
  141. len: 输出内容的长度
  142. 返回值: 无
  143. 修改记录:
  144. */
  145. void print_mem(char *name,void * addr,unsigned int len)
  146. {
  147. int once;
  148. int i,name_len;
  149. if(name)
  150. {
  151. rt_printf(name);
  152. name_len = strlen(name);
  153. }
  154. else
  155. {
  156. rt_printf("addr=0x%08x,len=%d\r\n",(unsigned int)addr,len);
  157. name_len = 10;
  158. }
  159. while(1)
  160. {
  161. once = len < 16 ? len : 16;
  162. if(!name)
  163. {
  164. rt_printf("%08x:",(unsigned int)addr);
  165. }
  166. for(i=0;i<once;i++)
  167. {
  168. if(i == 8)
  169. rt_printf(" "); // 使用2个空格,不使用"-",因为规约解析工具不支持"-".
  170. rt_printf(" %02x",*(unsigned char *)addr++);
  171. }
  172. rt_printf("\r\n");
  173. len -= once;
  174. if(len == 0)
  175. {
  176. break;
  177. }
  178. // 打印对齐空格
  179. for(i=0;i<name_len;i++)
  180. {
  181. rt_printf(" ");
  182. }
  183. }
  184. return;
  185. }
  186. void print_mem_time(char *name,void * addr,unsigned int len)
  187. {
  188. struct rtc_time_t tm;
  189. struct timespec ts;
  190. char buf[64];
  191. clk_time_get(&ts);
  192. timespec_to_rtc(ts,&tm,0);
  193. if(name)
  194. {
  195. sprintf(buf,
  196. "%s(%04d-%02d-%02d %02d:%02d:%02d:%06ld)",
  197. name,
  198. tm.year + 2000,
  199. tm.month,
  200. tm.day,
  201. tm.hour,
  202. tm.min,
  203. tm.ms/1000,
  204. ts.tv_nsec/1000
  205. );
  206. }
  207. else
  208. {
  209. sprintf(buf,
  210. "mem(%04d-%02d-%02d %02d:%02d:%05d)",
  211. tm.year + 2000,
  212. tm.month,
  213. tm.day,
  214. tm.hour,
  215. tm.min,
  216. tm.ms
  217. );
  218. }
  219. print_mem(buf,addr,len);
  220. }
  221. // int g_print_time = 0;
  222. void print_msg(char *name,void * addr,unsigned int len)
  223. {
  224. if(g_print_time)
  225. {
  226. print_mem_time(name,addr,len);
  227. }
  228. else
  229. {
  230. print_mem(name,addr,len);
  231. }
  232. }
  233. int rt_printf(const char *fmt, ...)
  234. {
  235. #if 0
  236. char pbuf[1024];
  237. va_list args;
  238. int printed;
  239. va_start(args, fmt);
  240. printed = vsprintf(pbuf, fmt, args);
  241. va_end(args);
  242. //直接打印
  243. printf(pbuf);
  244. #else
  245. //放入显示缓冲区
  246. va_list args;
  247. int length, byte;
  248. va_start(args, fmt);
  249. vsnprintf(printf_buf, PRINTF_BUF_SIZE, (char *)fmt, args);
  250. va_end(args);
  251. length = strlen(printf_buf);
  252. pthread_mutex_lock(&printf_mutex);
  253. if((w_p + length) < PRINTF_BUF_SIZE)
  254. {
  255. memcpy((uint8_t *)&p_buf_s[w_p],(uint8_t *)printf_buf,length);
  256. w_p += length;
  257. }
  258. else
  259. {
  260. byte = PRINTF_BUF_SIZE - w_p;
  261. memcpy((uint8_t *)&p_buf_s[w_p],(uint8_t *)printf_buf,byte);
  262. w_p = length - byte;
  263. memcpy((uint8_t *)p_buf_s,(uint8_t *)&printf_buf[byte],w_p);
  264. }
  265. //printf("-----test printf----wp=%d---%s",w_p, printf_buf);
  266. pthread_mutex_unlock(&printf_mutex);
  267. #endif
  268. return 0;
  269. }
  270. /******************************************************************************
  271. 函数名称: rt_printf_func
  272. 函数版本: 01.01
  273. 创建作者: sunxi
  274. 创建日期: 2022-5-31
  275. 函数说明: 打印工作函数.
  276. 参数说明:
  277. 返回值: 返回0
  278. 修改记录:
  279. */
  280. static int rt_printf_func(void *arg)
  281. {
  282. int len = 0;
  283. int len_1 = 0;
  284. memset(p_buf,0,sizeof(p_buf));
  285. memset(p_buf_s,0,sizeof(p_buf_s));
  286. w_p = 0;
  287. r_p = 0;
  288. pthread_mutex_init(&printf_mutex, NULL);
  289. #if 0
  290. strcpy(&p_buf[w_p],test_1);
  291. w_p += strlen(test_1);
  292. strcpy(&p_buf[w_p],test_2);
  293. w_p += strlen(test_2);
  294. strcpy(&p_buf[w_p],test_3);
  295. w_p += strlen(test_3);
  296. rt_printf(p_buf);
  297. #endif
  298. uint32_t wdt_id;
  299. int rc = watchdog_add_item("rt_printf_func", &wdt_id,120);
  300. if(rc != 0) {
  301. printf("can not add rt_printf_func task to wdt\r\n");
  302. return 0;
  303. }
  304. prctl(PR_SET_NAME, "rt_printf_func");
  305. while(!exit_flag)
  306. {
  307. msleep(10);
  308. watchdog_feed(wdt_id);
  309. if(main_mod_is_exit())
  310. {
  311. break;
  312. }
  313. //rt_printf("w_p = %d, r_p = %d\r\n",w_p,r_p);
  314. pthread_mutex_lock(&printf_mutex);
  315. len = 0;
  316. len_1 = 0;
  317. if(w_p != r_p)
  318. {
  319. memset(p_buf,0,sizeof(p_buf));
  320. //获取打印信息
  321. if(w_p > r_p)
  322. {
  323. len = w_p - r_p;
  324. memcpy(p_buf,&p_buf_s[r_p],len);
  325. r_p += len;
  326. }
  327. else
  328. {
  329. //w_p指针翻滚,过0
  330. //分两段读取,再合并
  331. len = PRINTF_BUF_SIZE-r_p;
  332. memcpy(p_buf,&p_buf_s[r_p],len);
  333. r_p += len;
  334. len_1 = w_p;
  335. memcpy(&p_buf[len],p_buf_s,len_1);
  336. r_p = len_1;
  337. }
  338. if(r_p >= PRINTF_BUF_SIZE)
  339. r_p = 0;
  340. p_buf[sizeof(p_buf)-1] = 0;//保证结束
  341. }
  342. pthread_mutex_unlock(&printf_mutex);
  343. if((len > 0) || (len_1 > 0))
  344. {
  345. //noted by sunxi: 20221122 重定向6000端口打印
  346. if(g_print_to_net)
  347. {
  348. net_debug_send(p_buf,sizeof(p_buf));
  349. // return 0;
  350. }
  351. else
  352. {
  353. printf(p_buf);
  354. //printf("\r\n");
  355. }
  356. }
  357. }
  358. watchdog_remove_item(wdt_id);
  359. return 0;
  360. }
  361. /******************************************************************************
  362. 函数名称: rt_printf_init
  363. 函数版本: 01.01
  364. 创建作者: sunxi
  365. 创建日期: 2022-5-31
  366. 函数说明: 初始化.
  367. 参数说明:
  368. 返回值: 成功返回0, 失败返回-1
  369. 修改记录:
  370. */
  371. int rt_printf_init(void)
  372. {
  373. int ret;
  374. ret = pthread_create(&printf_tid, NULL, (void *)rt_printf_func, NULL);
  375. if(ret)
  376. {
  377. printf("ret = %d, err = %s\r\n", ret, strerror(ret));
  378. printf_tid = 0;
  379. return ret;
  380. }
  381. return 0;
  382. }
  383. /******************************************************************************
  384. 函数名称: rt_printf_exit
  385. 函数版本: 01.01
  386. 创建作者: sunxi
  387. 创建日期: 2022-5-31
  388. 函数说明: 反初始化.
  389. 参数说明:
  390. 返回值: 总是返回0.
  391. 修改记录:
  392. */
  393. int rt_printf_exit(void)
  394. {
  395. exit_flag = 1;
  396. pthread_join(printf_tid, NULL);
  397. return 0;
  398. }
  399. /*------------------------------ 测试函数 -------------------------------------
  400. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  401. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  402. */
  403. /*------------------------------ 文件结束 -------------------------------------
  404. */