log.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. #include "log.h"
  2. #include "rtc.h"
  3. #include "ringfs.h"
  4. #include "spi_flash.h"
  5. #include "FreeRTOS.h"
  6. #include "task.h"
  7. #include "semphr.h"
  8. #include <string.h>
  9. #undef DBG
  10. #define DBG if(1)
  11. #define LOG_ENTRY_VERSION 1
  12. #define LOG_FLASH_SECTOR_OFFSET 4
  13. #define ALARM_LOG_FLASH_SECTOR_OFFSET 258
  14. #define SECTOR_COUNT (spi_flash_desc.sector_count/2 - LOG_FLASH_SECTOR_OFFSET)
  15. static int op_sector_erase(struct ringfs_flash_partition *flash, int address) {
  16. (void)flash;
  17. int ret;
  18. ret = spi_flash_erase_sector(address, 0);
  19. return ret;
  20. }
  21. static ssize_t op_program(struct ringfs_flash_partition *flash, int address, const void *data, size_t size) {
  22. (void)flash;
  23. int ret;
  24. ret = spi_flash_write(address, data, size, 0);
  25. return ret;
  26. }
  27. static ssize_t op_read(struct ringfs_flash_partition *flash, int address, void *data, size_t size) {
  28. (void)flash;
  29. int ret;
  30. ret = spi_flash_read(address, data, size, 0);
  31. return ret;
  32. }
  33. static struct ringfs_flash_partition ringfs_flash =
  34. {
  35. .sector_offset = LOG_FLASH_SECTOR_OFFSET,
  36. .sector_erase = op_sector_erase,
  37. .program = op_program,
  38. .read = op_read,
  39. };
  40. static struct ringfs fs;
  41. static struct ringfs_flash_partition ringfs_flash2 =
  42. {
  43. .sector_offset = ALARM_LOG_FLASH_SECTOR_OFFSET,
  44. .sector_erase = op_sector_erase,
  45. .program = op_program,
  46. .read = op_read,
  47. };
  48. static struct ringfs fs2;
  49. //
  50. void log_init(bool format)
  51. {
  52. DBG printf("[LOG] Init...\r\n");
  53. if (!spi_flash_desc.present)
  54. return;
  55. ringfs_flash.sector_size = spi_flash_desc.sector_size;
  56. ringfs_flash.sector_count = SECTOR_COUNT;
  57. ringfs_init(&fs, &ringfs_flash, LOG_ENTRY_VERSION, sizeof(log_entry_t));
  58. if (format || ringfs_scan(&fs) != 0){
  59. DBG printf("FAT1 false\r\n");
  60. ringfs_format(&fs);
  61. }
  62. DBG printf("FAT1 true\r\n");
  63. ringfs_flash2.sector_size = spi_flash_desc.sector_size;
  64. ringfs_flash2.sector_count = SECTOR_COUNT;
  65. ringfs_init(&fs2, &ringfs_flash2, LOG_ENTRY_VERSION, sizeof(log_entry_t));
  66. if (format || ringfs_scan(&fs2) != 0){
  67. DBG printf("FAT2 false\r\n");
  68. ringfs_format(&fs2);
  69. }
  70. DBG printf("FAT2 true\r\n");
  71. //fLogInit = true;
  72. //log_mutex = xSemaphoreCreateMutex();
  73. //xTaskCreate(log_task, ( char * ) "log_task", configMINIMAL_STACK_SIZE * 2, NULL, tskIDLE_PRIORITY, NULL);
  74. }
  75. #if 0
  76. char logFileBuf[FILE_BUF_MAX_LEN];
  77. char name_login[50];
  78. extern const char* logsStrShortRu[];
  79. bool flUpdateLog = false;
  80. static bool fLogInit = false; // Флаг инициализации журнала
  81. #define LOG_TIME 1000*60*10
  82. static int op_sector_erase(struct ringfs_flash_partition *flash, int address) {
  83. (void)flash;
  84. int ret;
  85. ret = spi_flash_erase_sector(address, 0);
  86. return ret;
  87. }
  88. static ssize_t op_program(struct ringfs_flash_partition *flash, int address, const void *data, size_t size) {
  89. (void)flash;
  90. int ret;
  91. ret = spi_flash_write(address, data, size, 0);
  92. return ret;
  93. }
  94. static ssize_t op_read(struct ringfs_flash_partition *flash, int address, void *data, size_t size) {
  95. (void)flash;
  96. int ret;
  97. ret = spi_flash_read(address, data, size, 0);
  98. return ret;
  99. }
  100. static struct ringfs_flash_partition ringfs_flash = {
  101. .sector_offset = LOG_FLASH_SECTOR_OFFSET,
  102. .sector_erase = op_sector_erase,
  103. .program = op_program,
  104. .read = op_read,
  105. };
  106. static struct ringfs fs;
  107. static struct ringfs_flash_partition ringfs_flash2 = {
  108. .sector_offset = ALARM_LOG_FLASH_SECTOR_OFFSET,
  109. .sector_erase = op_sector_erase,
  110. .program = op_program,
  111. .read = op_read,
  112. };
  113. static struct ringfs fs2;
  114. static SemaphoreHandle_t log_mutex;
  115. /**
  116. * @brief Отключает журнал для безопасной перезагрузки
  117. */
  118. bool LOG_Disable(void)
  119. {
  120. if (fLogInit) {
  121. /* Ожидаем завершения работы с журнал */
  122. if ( xSemaphoreTake(log_mutex, 10000) == pdTRUE ) {
  123. //fLogInit = false;
  124. //xSemaphoreGive(logMutex);
  125. return true;
  126. }
  127. else {
  128. return false;
  129. }
  130. }
  131. else {
  132. return true;
  133. }
  134. }
  135. void log_task(void* params)
  136. {
  137. for(;;){
  138. flUpdateLog = true;
  139. vTaskDelay(LOG_TIME);
  140. /*vTaskDelay(50);
  141. log_event_data(LOG_SYSTEM_BOOT, "Администратор");
  142. log_add(")215.7;215.7;220.5;000;50.1;2.30;25.0;00000001;");*/
  143. }
  144. }
  145. void log_init(bool format) {
  146. DBG printf(">>> Event log\n");
  147. if (!spi_flash_desc.present)
  148. return;
  149. ringfs_flash.sector_size = spi_flash_desc.sector_size;
  150. ringfs_flash.sector_count = SECTOR_COUNT;
  151. ringfs_init(&fs, &ringfs_flash, LOG_ENTRY_VERSION, sizeof(log_entry_t));
  152. if (format || ringfs_scan(&fs) != 0){
  153. DBG printf("FAT1 false\r\n");
  154. ringfs_format(&fs);
  155. }
  156. DBG printf("FAT1 true\r\n");
  157. ringfs_flash2.sector_size = spi_flash_desc.sector_size;
  158. ringfs_flash2.sector_count = SECTOR_COUNT;
  159. ringfs_init(&fs2, &ringfs_flash2, LOG_ENTRY_VERSION, sizeof(log_entry_t));
  160. if (format || ringfs_scan(&fs2) != 0){
  161. DBG printf("FAT2 false\r\n");
  162. ringfs_format(&fs2);
  163. }
  164. DBG printf("FAT2 true\r\n");
  165. fLogInit = true;
  166. log_mutex = xSemaphoreCreateMutex();
  167. xTaskCreate(log_task, ( char * ) "log_task", configMINIMAL_STACK_SIZE * 2, NULL, tskIDLE_PRIORITY, NULL);
  168. }
  169. int capacity_flash = 0;
  170. int count_flash = 0;
  171. int log_test(void) {
  172. int ret;
  173. log_entry_t entry;
  174. log_init(false);
  175. capacity_flash = ringfs_capacity(&fs);
  176. count_flash = ringfs_count_exact(&fs);
  177. DBG printf("\tCapacity: %d\n", capacity_flash);
  178. DBG printf("\tCount: %d\n", count_flash);
  179. DBG printf("\tAppending ");
  180. // ret = log_event(LOG_SYSTEM_DEFCONFIG, 0, 0);
  181. DBG printf("%s\n", ret == 0 ? "ok" : "error");
  182. if (ret == 0)
  183. return -1;
  184. // ret = log_event(LOG_SYSTEM_DEFCONFIG, 0, 512);
  185. entry.timestamp = 0;
  186. entry.type = 0;
  187. DBG printf("\tFetching ");
  188. if (log_fetch(&entry, portMAX_DELAY) == 0){
  189. DBG printf("ok, time=%d, type=%d\n", entry.timestamp, entry.type);
  190. log_fetch(&entry, portMAX_DELAY);
  191. entry.timestamp = 0;
  192. entry.type = 0;
  193. log_fetch(&entry, portMAX_DELAY);
  194. entry.timestamp = 0;
  195. entry.type = 0;
  196. log_fetch(&entry, portMAX_DELAY);
  197. entry.timestamp = 0;
  198. entry.type = 0;
  199. log_fetch(&entry, portMAX_DELAY);
  200. return 0;
  201. }
  202. else {
  203. DBG printf("fail\n");
  204. return -1;
  205. }
  206. DBG printf("\tDiscarding ");
  207. if (log_discard(&entry,portMAX_DELAY) == 0)
  208. DBG printf("ok\n");
  209. else {
  210. DBG printf("fail\n");
  211. return -1;
  212. }
  213. return 0;
  214. }
  215. int log_append(log_entry_t *entry) {
  216. int ret;
  217. TM_RTC_t data;
  218. ret = xSemaphoreTake( log_mutex, portMAX_DELAY );
  219. if (ret == pdFALSE)
  220. return ret;
  221. if (!entry->timestamp){
  222. TM_RTC_GetDateTime(&data, TM_RTC_Format_BIN);
  223. entry->timestamp = data.unix;
  224. }
  225. if(entry->type == LOG_VALUE)
  226. ringfs_append(&fs, entry);
  227. else
  228. ringfs_append(&fs2, entry);
  229. xSemaphoreGive(log_mutex);
  230. return ret;
  231. }
  232. int log_fetch(log_entry_t *entry, uint32_t timeout) {
  233. int ret;
  234. ret = xSemaphoreTake( log_mutex, (TickType_t)timeout );
  235. if (ret == pdFALSE)
  236. return ret;
  237. if(entry->type == LOG_VALUE)
  238. ret = ringfs_fetch(&fs, entry);
  239. else
  240. ret = ringfs_fetch(&fs2, entry);
  241. xSemaphoreGive(log_mutex);
  242. return ret;
  243. }
  244. int log_rewind(log_entry_t *entry, uint32_t timeout) {
  245. int ret;
  246. ret = xSemaphoreTake( log_mutex, (TickType_t)timeout );
  247. if (ret == pdFALSE)
  248. return ret;
  249. if(entry->type == LOG_VALUE)
  250. ret = ringfs_rewind(&fs);
  251. else
  252. ret = ringfs_rewind(&fs2);
  253. xSemaphoreGive(log_mutex);
  254. return ret;
  255. }
  256. int log_discard(log_entry_t *entry, uint32_t timeout) {
  257. int ret;
  258. ret = xSemaphoreTake( log_mutex, (TickType_t)timeout );
  259. if (ret == pdFALSE)
  260. return ret;
  261. if(entry->type == LOG_VALUE)
  262. ret = ringfs_discard(&fs);
  263. else
  264. ret = ringfs_discard(&fs2);
  265. xSemaphoreGive(log_mutex);
  266. return ret;
  267. }
  268. void log_event_data(log_type_t type, char *data)
  269. {
  270. log_entry_t entry_data;
  271. entry_data.timestamp = 0;
  272. entry_data.type = type;
  273. strncpy(entry_data.data, data, 49);
  274. if (fLogInit)
  275. log_append(&entry_data);
  276. }
  277. void log_add(char *log_data)
  278. {
  279. char buf_value[50];
  280. uint8_t i, len;
  281. memset(buf_value, 0, 50);
  282. len = strlen(log_data);
  283. if (len != UPS_DATA_STRING_SIZE) {
  284. //len = UPS_DATA_STRING_SIZE;
  285. return;
  286. }
  287. strncpy(buf_value, log_data, len);
  288. DBG printf("UPS log data: %s\r\n", log_data);
  289. buf_value[0] = '\"';
  290. for(i = 0; i < len; i++)
  291. {
  292. if(buf_value[i] == ' ')
  293. buf_value[i] = ';';
  294. }
  295. buf_value[len - 1] = ';';
  296. if(fLogInit){
  297. if(fs.write.slot>67)
  298. {
  299. log_entry_t entry_data;
  300. entry_data.timestamp = 0;
  301. log_event_data(LOG_VALUE, buf_value);
  302. }
  303. else
  304. log_event_data(LOG_VALUE, buf_value);
  305. }
  306. }
  307. /**
  308. * @brief Возвращает true если журнал проинициализирован
  309. */
  310. bool LOG_IsInit()
  311. {
  312. return fLogInit;
  313. }
  314. /**
  315. * @brief Возвращает общее количество страниц
  316. */
  317. uint32_t LOG_GetPageCount(void)
  318. {
  319. return (((ringfs_count_estimate(&fs)) / 10) + 1);
  320. }
  321. uint32_t LOG_GetTotalSTRCount(void)
  322. {
  323. return ringfs_count_estimate(&fs);
  324. }
  325. void LOG_GetPage_tabs(char *str, uint32_t page)
  326. {
  327. TM_RTC_t rtc_data;
  328. log_entry_t entry;
  329. char buf[20];
  330. uint8_t i;
  331. int start =LOG_GetTotalSTRCount();//(fs.write.sector*fs.slots_per_sector + fs.write.slot);
  332. memset(buf, 0, 20);
  333. for(i=0; i < 10; i++){
  334. fs.cursor_position = start - 10*(page-1) - 1 - i;
  335. if(fs.cursor_position < 0)
  336. break;
  337. else{
  338. fs.cursor.sector = (fs.read.sector + fs.cursor_position/fs.slots_per_sector)%fs.flash->sector_count;
  339. fs.cursor.slot = fs.cursor_position%fs.slots_per_sector;
  340. }
  341. entry.type = LOG_VALUE;
  342. log_fetch(&entry, portMAX_DELAY);
  343. entry.data[49] = 0;
  344. strncat(str, entry.data, strlen(entry.data));
  345. TM_RTC_GetDateTimeFromUnix(&rtc_data, entry.timestamp);
  346. sprintf(buf, "%02i.%02i.%02i %02i:%02i:%02i", rtc_data.date, rtc_data.month,
  347. rtc_data.year, rtc_data.hours, rtc_data.minutes, rtc_data.seconds);
  348. strcat(str, buf);
  349. strcat(str, "\",");
  350. strcat(str, "\r\n");
  351. }
  352. }
  353. void LOG_GetPage(char *str, uint32_t page)
  354. {
  355. TM_RTC_t rtc_data;
  356. log_entry_t entry;
  357. char buf[20];
  358. uint8_t i;
  359. int start =LOG_GetTotalSTRCount();//(fs.write.sector*fs.slots_per_sector + fs.write.slot);
  360. memset(buf, 0, 20);
  361. for(i=0; i < 10; i++){
  362. fs.cursor_position = start - 10*(page-1) - 1 - i;
  363. if(fs.cursor_position < 0)
  364. break;
  365. else{
  366. fs.cursor.sector = (fs.read.sector + fs.cursor_position/fs.slots_per_sector)%fs.flash->sector_count;
  367. fs.cursor.slot = fs.cursor_position%fs.slots_per_sector;
  368. }
  369. entry.type = LOG_VALUE;
  370. log_fetch(&entry, portMAX_DELAY);
  371. entry.data[49] = 0;
  372. strncat(str, entry.data, strlen(entry.data));
  373. TM_RTC_GetDateTimeFromUnix(&rtc_data, entry.timestamp);
  374. sprintf(buf, "%02i.%02i.%02i %02i:%02i:%02i", rtc_data.date, rtc_data.month,
  375. rtc_data.year, rtc_data.hours, rtc_data.minutes, rtc_data.seconds);
  376. strcat(str, buf);
  377. strcat(str, "\",");
  378. }
  379. }
  380. uint32_t LOG_GetData(int ptr, char *str, uint32_t size, bool start)
  381. {
  382. TM_RTC_t rtc_data;
  383. log_entry_t entry;
  384. char buf[20];
  385. uint8_t i;
  386. entry.type = LOG_VALUE;
  387. if(start)
  388. log_rewind(&entry, portMAX_DELAY);
  389. fs.cursor_position = ptr/STRING_SIZE;
  390. fs.cursor.sector = (fs.read.sector + fs.cursor_position/fs.slots_per_sector)%fs.flash->sector_count;
  391. fs.cursor.slot = fs.cursor_position%fs.slots_per_sector;
  392. for(i = 0; i < size/STRING_SIZE; i++)
  393. {
  394. entry.type = LOG_VALUE;
  395. log_fetch(&entry, portMAX_DELAY);
  396. entry.data[49] = 0;
  397. strncat(str, &entry.data[1], (strlen(entry.data) - 1));
  398. TM_RTC_GetDateTimeFromUnix(&rtc_data, entry.timestamp);
  399. sprintf(buf, "%02i.%02i.%02i %02i:%02i:%02i", rtc_data.date, rtc_data.month,
  400. rtc_data.year, rtc_data.hours, rtc_data.minutes, rtc_data.seconds);
  401. strcat(str, buf);
  402. strcat(str, "\n");
  403. }
  404. return strlen(str);
  405. }
  406. #endif