rt_printf.c 8.9 KB

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