rt_log.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: rt_log.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2020-6-18
  7. 功能说明: 日志记录
  8. 其它说明: 没有资源竞争保护处理,只能在大循环级别使用。
  9. 修改记录:
  10. */
  11. #include <rt.h>
  12. #include "my_rtc.h"
  13. #include <semaphore.h>
  14. struct log_file g_log_file[] =
  15. {
  16. {"/app/data/log_err.txt", 50*1024,0,0},
  17. {"/app/data/log_operate.txt", 50*1024,0,0},
  18. {"/app/data/log_soe.txt", 50*1024,0,0},
  19. {"/app/data/log_yx.txt", 50*1024,0,0},
  20. {"/app/data/log_printf.txt", 100*1024,0,0},
  21. };
  22. #define LOG_FILE_NUM ((int)(sizeof(g_log_file)/sizeof(g_log_file[0])))
  23. #define LOG_FILE_BUFSIZE 1024
  24. int g_logfile_update[LOG_FILE_NUM];
  25. static char writebuf[LOG_FILE_NUM][LOG_FILE_BUFSIZE]; //数据缓存区
  26. static int writebuf_count[LOG_FILE_NUM]; //缓存已存字节数
  27. static char g_malloc_buf[LOG_FILE_NUM][LOG_FILE_BUFSIZE]; //数据缓存区
  28. sem_t log_sem_buf[LOG_FILE_NUM]; // 信号量 对空指针进行读写操作会导致编译错误
  29. static sem_t *log_sem[LOG_FILE_NUM];
  30. int sem_for_type = 0;
  31. int log_init(void)
  32. {
  33. int i,j,file_length,max_length;
  34. char * file_buf;
  35. off_t pos;
  36. int err,ret;
  37. int len;
  38. pos=0;
  39. //找到最大的文件长度
  40. max_length = 0;
  41. for(i = 0; i< LOG_FILE_NUM; i++)
  42. {
  43. log_sem[i]=&log_sem_buf[i];
  44. if(g_log_file[i].size > max_length)
  45. {
  46. max_length = g_log_file[i].size;
  47. }
  48. writebuf_count[i] = 0; //清零
  49. //if(sem_init(log_sem[i], sem_for_type, 0))
  50. if(sem_init(log_sem[i], sem_for_type, 1)) //先创建一个1值信号量
  51. return -1;
  52. }
  53. //分配内存
  54. file_buf = (char *)rt_malloc(max_length);
  55. if(file_buf == NULL)
  56. {
  57. return -111;
  58. }
  59. //循环打开文件,找到00的位置
  60. err = 0;
  61. for(i = 0; i< LOG_FILE_NUM; i++)
  62. {
  63. //打开文件
  64. g_log_file[i].handle = rt_file_open(g_log_file[i].name, O_CREAT|O_RDWR, 0);
  65. if(IS_ERR(g_log_file[i].handle))
  66. {
  67. printf("%s open error!\r\n",g_log_file[i].name);
  68. err++;
  69. continue;
  70. }
  71. len = rt_file_getfile_size(g_log_file[i].handle);
  72. if(len < 0)
  73. {
  74. printf("%s fstat error!\r\n", g_log_file[i].name);
  75. rt_file_close(g_log_file[i].handle, 0);
  76. g_log_file[i].handle = -1;
  77. err++;
  78. continue;
  79. }
  80. //得到文件长度
  81. file_length = len;
  82. //读出文件内容
  83. pos = 0;
  84. ret = rt_file_read(g_log_file[i].handle, file_buf, file_length, &pos);
  85. if(ret != file_length) //读出log内容
  86. {
  87. rt_file_close(g_log_file[i].handle, 0);
  88. g_log_file[i].handle = -1;
  89. printf("%s read error:file_length=%d,ret=%d!\r\n",g_log_file[i].name,file_length,ret);
  90. err++;
  91. continue;
  92. }
  93. g_log_file[i].offset = 0;
  94. //如果文件长度,偏移量为0
  95. if(file_length == 0)
  96. {
  97. g_log_file[i].offset = 0;
  98. continue;
  99. }
  100. //找到00位置,得到偏移量
  101. for(j = 0; j < file_length-1; j++)
  102. {
  103. if(file_buf[j] == 0 && (file_buf[j+1] == 0))
  104. {
  105. g_log_file[i].offset = j+1;
  106. break;
  107. }
  108. }
  109. }
  110. //释放内存
  111. rt_free(file_buf);
  112. log_str_time(LOG_ERR,"装置上电",1,1);
  113. memset (g_logfile_update, 0, sizeof(g_logfile_update));
  114. return -err;
  115. }
  116. //退出函数
  117. int log_exit(void)
  118. {
  119. int i;
  120. //循环关闭文件
  121. for(i = 0; i< LOG_FILE_NUM; i++)
  122. {
  123. if(log_sem[i])
  124. {
  125. sem_destroy(log_sem[i]);
  126. log_sem[i] = NULL;
  127. }
  128. if(g_log_file[i].handle != 0)
  129. {
  130. rt_file_close(g_log_file[i].handle, 0);
  131. g_log_file[i].handle = -1;
  132. }
  133. }
  134. return 0;
  135. }
  136. static int _log_str(int index, char *log_buf,int log_len)
  137. {
  138. char flag[2],*buf,read_buf[2];
  139. int end_len,over_len,file_length;
  140. off_t pos;
  141. off_t write_pos;
  142. int write_len;
  143. int tmp = 0;
  144. int ret=0;
  145. if(log_len == 0)
  146. {
  147. return 0;
  148. }
  149. if(log_len > LOG_FILE_BUFSIZE)
  150. {
  151. return -1;
  152. }
  153. // 检查参数
  154. if(index > LOG_FILE_NUM)
  155. {
  156. return -1;
  157. }
  158. if(g_log_file[index].handle < 0)
  159. {
  160. return -2;
  161. }
  162. if(log_buf == NULL)
  163. {
  164. return -3;
  165. }
  166. //初始化
  167. end_len = 0;
  168. over_len = 0;
  169. memset(flag,0x0,sizeof(flag));
  170. pos=g_log_file[index].offset;
  171. buf=g_malloc_buf[index];
  172. //判断是否记录长度超过文件长度
  173. if(g_log_file[index].offset + log_len + 6 >= g_log_file[index].size)
  174. {
  175. //得到最后剩余的长度
  176. end_len = g_log_file[index].size-g_log_file[index].offset;
  177. memset(buf,0,end_len);
  178. //将最后部分填0
  179. if(rt_file_write(g_log_file[index].handle,buf,end_len,&pos) != end_len)
  180. {
  181. return -5;
  182. }
  183. //从头开始写入
  184. pos = 0;
  185. }
  186. write_pos = pos;
  187. pos = pos + 2 + log_len + 2;
  188. g_log_file[index].offset = pos-1;
  189. pos += 2;
  190. write_len = 2 + log_len + 2 + 2;
  191. memcpy(buf, "\r\n", 2);
  192. tmp += 2;
  193. memcpy(buf+tmp, log_buf, log_len);
  194. tmp += log_len;
  195. memcpy(buf+tmp, flag, 2);
  196. tmp += 2;
  197. memcpy(buf+tmp, "\r\n", 2);
  198. memcpy(writebuf[index], buf, write_len);
  199. //在文件长度小于最大长度时,需要找到当前文件长度
  200. fsync(g_log_file[index].handle);
  201. file_length = rt_file_getfile_size(g_log_file[index].handle);
  202. rt_file_llseek(g_log_file[index].handle, 0, SEEK_SET);
  203. //从换行后开始查找,找到被覆盖剩余记录部分长度
  204. pos = g_log_file[index].offset + 3;
  205. while(pos <= (file_length - 2))
  206. {
  207. if(rt_file_read(g_log_file[index].handle,read_buf, 2,&pos) != 2)
  208. {
  209. rt_printf("%s read error!\r\n",g_log_file[index].name);
  210. ret = -10;
  211. goto END;
  212. }
  213. if(read_buf[0] == 0 && read_buf[1] != 0)
  214. {
  215. break;
  216. }
  217. pos -= 1;
  218. }
  219. over_len = pos - g_log_file[index].offset - 4;
  220. if(over_len < 0)
  221. {
  222. goto END;
  223. }
  224. //将被覆盖剩余记录填0
  225. memset(writebuf[index]+write_len,0,over_len);
  226. write_len += over_len;
  227. END:
  228. if(rt_file_write(g_log_file[index].handle,writebuf[index],write_len,&write_pos) != write_len)
  229. {
  230. rt_printf("%s write error!\r\n",g_log_file[index].name);
  231. return -12;
  232. }
  233. // 文件已更新
  234. g_logfile_update[index] = 1;
  235. return ret;
  236. }
  237. int log_str(int index, char *log_buf)
  238. {
  239. int ret = 0,len;
  240. len = strlen(log_buf);
  241. sem_wait(log_sem[index]);
  242. ret = _log_str(index, log_buf,len); //写内容到文件
  243. sem_post(log_sem[index]);
  244. return ret;
  245. }
  246. int log_str_len(int index, char *log_buf,int len)
  247. {
  248. int ret = 0;
  249. sem_wait(log_sem[index]);
  250. ret = _log_str(index, log_buf,len); //写内容到文件
  251. sem_post(log_sem[index]);
  252. return ret;
  253. }
  254. static int log_str_flush(int index, char *log_buf, int log_len)
  255. {
  256. char flag[2],*buf,read_buf[2];
  257. int end_len,over_len,file_length;
  258. off_t pos;
  259. if(log_len == 0)
  260. {
  261. return 0;
  262. }
  263. // 检查参数
  264. if(index > LOG_FILE_NUM)
  265. {
  266. return -1;
  267. }
  268. if(g_log_file[index].handle == 0)
  269. {
  270. return -2;
  271. }
  272. if(log_buf == NULL)
  273. {
  274. return -3;
  275. }
  276. //初始化
  277. end_len = 0;
  278. over_len = 0;
  279. memset(flag,0x0,sizeof(flag));
  280. //log_len = strlen(log_buf);
  281. pos=g_log_file[index].offset;
  282. //判断是否记录长度超过文件长度
  283. if(g_log_file[index].offset + log_len >= g_log_file[index].size)
  284. {
  285. //得到最后剩余的长度
  286. end_len = g_log_file[index].size-g_log_file[index].offset;
  287. //分配内存
  288. buf = (char *)rt_malloc(end_len);
  289. if(buf == 0)
  290. {
  291. return -4;
  292. }
  293. memset(buf,0,end_len);
  294. //将最后部分填0
  295. if(rt_file_write(g_log_file[index].handle,buf,end_len,&pos) != end_len)
  296. {
  297. rt_free(buf);
  298. return -5;
  299. }
  300. rt_free(buf);
  301. //从头开始写入
  302. pos = 0;
  303. }
  304. //写文件
  305. if(rt_file_write(g_log_file[index].handle,log_buf, log_len ,&pos) != log_len)
  306. {
  307. return -9;
  308. }
  309. g_log_file[index].offset = pos-3;
  310. //在文件长度小于最大长度时,需要找到当前文件长度
  311. fsync(g_log_file[index].handle);
  312. file_length= rt_file_getfile_size(g_log_file[index].handle);
  313. rt_file_llseek(g_log_file[index].handle, 0, SEEK_SET);
  314. //rt_free(buf);
  315. //从换行后开始查找,找到被覆盖剩余记录部分长度
  316. pos = g_log_file[index].offset + 3;
  317. while(pos <= (file_length - 2))
  318. {
  319. if(rt_file_read(g_log_file[index].handle,read_buf, 2,&pos) != 2)
  320. {
  321. rt_printf("%s read error!\r\n",g_log_file[index].name);
  322. return -10;
  323. }
  324. if(read_buf[0] == 0 && read_buf[1] != 0)
  325. {
  326. break;
  327. }
  328. pos -= 1;
  329. }
  330. over_len = pos - g_log_file[index].offset - 4;
  331. if(over_len < 0)
  332. {
  333. goto END;
  334. }
  335. //分配内存
  336. buf = (char *)rt_malloc(over_len);
  337. if(buf == 0)
  338. {
  339. return -11;
  340. }
  341. memset(buf,0,over_len);
  342. pos = g_log_file[index].offset + 3;
  343. //将被覆盖剩余记录填0
  344. if(rt_file_write(g_log_file[index].handle,buf,over_len,&pos) != over_len)
  345. {
  346. rt_free(buf);
  347. rt_printf("%s write error!\r\n",g_log_file[index].name);
  348. return -12;
  349. }
  350. rt_free(buf);
  351. END:
  352. // 文件已更新
  353. g_logfile_update[index] = 1;
  354. return 0;
  355. }
  356. int log_str_ext(int index, char *log_buf)
  357. {
  358. int log_len= strlen(log_buf);
  359. sem_wait(log_sem[index]);
  360. //缓存数据内容已经足够大,写到文件中
  361. if((log_len+3+writebuf_count[index]) >= LOG_FILE_BUFSIZE)
  362. {
  363. //最后一行结束字符00 00 0D 0A
  364. writebuf[index][writebuf_count[index]-2]=0;
  365. writebuf[index][writebuf_count[index]-1]=(unsigned char)'\r';
  366. writebuf[index][writebuf_count[index]]=(unsigned char)'\n';
  367. //写到文件中
  368. log_str_flush(index, writebuf[index], writebuf_count[index]+1);
  369. writebuf_count[index] = 0;//清零
  370. }
  371. //文件开头填充0D 0A
  372. if(writebuf_count[index]==0)
  373. {
  374. //数据末尾00 00 0D 0A
  375. //填充 0D 0A 数据
  376. writebuf[index][0] = '\r';
  377. writebuf[index][1] = '\n';
  378. writebuf_count[index] += 2;
  379. }
  380. //缓存数据内容
  381. memcpy(writebuf[index]+writebuf_count[index], log_buf, log_len);
  382. writebuf_count[index] += log_len;
  383. //一行内容以 00 0D 0A作为结束
  384. writebuf[index][writebuf_count[index] ] = 0;
  385. writebuf_count[index] ++;
  386. memcpy(writebuf[index]+writebuf_count[index], "\r\n", 2);
  387. writebuf_count[index] +=2;
  388. sem_post(log_sem[index]);
  389. return 0;
  390. }
  391. void log_str_ext_flush(int index)
  392. {
  393. sem_wait(log_sem[index]);
  394. if(writebuf_count[index] > 0)
  395. {
  396. //结束字符00 00 0D 0A
  397. writebuf[index][writebuf_count[index]-2]=0;
  398. writebuf[index][writebuf_count[index]-1]=(unsigned char)'\r';
  399. writebuf[index][writebuf_count[index]]=(unsigned char)'\n';
  400. log_str_flush(index, writebuf[index], writebuf_count[index]+1);
  401. writebuf_count[index] = 0;
  402. }
  403. sem_post(log_sem[index]);
  404. }
  405. int log_str_time(int index, char *log_buf,int is_rtc,u8 val)
  406. {
  407. char * wirte_buf;
  408. int log_len;
  409. struct timespec ts={0,0};
  410. struct rtc_time_t tm;
  411. #if 0 //jack.liu 20200911 获取rtc时间失能
  412. if(is_rtc) // 装置上电时才用到
  413. {
  414. // rtc_time_read(&tm);
  415. }
  416. else
  417. #endif
  418. {
  419. clk_time_get(&ts);
  420. timespec_to_rtc(ts,&tm,0);
  421. }
  422. // 检查参数
  423. if(index > LOG_FILE_NUM)
  424. {
  425. return -1;
  426. }
  427. if(log_buf == NULL)
  428. {
  429. return -2;
  430. }
  431. //得到待写入字符串长度
  432. log_len = strlen(log_buf)+16;
  433. wirte_buf = (char *)rt_malloc(log_len+strlen("2020-07-01 01:01:01.000000 "));
  434. if((wirte_buf) == NULL)
  435. {
  436. return -1;
  437. }
  438. //得到系统时间
  439. sprintf(wirte_buf,"20%02hu-%02hu-%02hu %02hu:%02hu:%02hu.%06lu ",
  440. tm.year,tm.month,tm.day,tm.hour,tm.min,tm.ms/1000,ts.tv_nsec/1000);
  441. strcat(wirte_buf,log_buf);
  442. log_str(index,wirte_buf);
  443. rt_free(wirte_buf);
  444. return 0;
  445. }
  446. int log_file_check(s8 * name)
  447. {
  448. int i;
  449. for(i=0; i<LOG_FILE_NUM; i++)
  450. {
  451. if(strstr(name,g_log_file[i].name) == 0)
  452. {
  453. return i;
  454. }
  455. }
  456. return -1;
  457. }
  458. int log_file_is_overrun(int index)
  459. {
  460. int file_length;
  461. if(index >= LOG_FILE_NUM)
  462. {
  463. return 1;
  464. }
  465. if(g_log_file[index].handle == 0)
  466. {
  467. return 1;
  468. }
  469. //得到文件长度
  470. fsync(g_log_file[index].handle);
  471. file_length= rt_file_getfile_size(g_log_file[index].handle);
  472. rt_file_llseek(g_log_file[index].handle, 0, SEEK_SET);
  473. if(g_log_file[index].offset + 128 > g_log_file[index].size)
  474. {
  475. return 1;
  476. }
  477. return 0;
  478. }