| 1 | #include "log_and_debug.h"
 | 
|---|
| 2 | #include "usbd_cdc_if.h"
 | 
|---|
| 3 | #include "cmsis_os.h"
 | 
|---|
| 4 | #include "ff.h"
 | 
|---|
| 5 | #include <stdarg.h>
 | 
|---|
| 6 | #include <string.h>
 | 
|---|
| 7 | #include <stdio.h>
 | 
|---|
| 8 | #include "Time.h"
 | 
|---|
| 9 | #include "lwip.h"
 | 
|---|
| 10 | 
 | 
|---|
| 11 | #define debug_transmit(b, l)    CDC_Transmit_FS(b, l);
 | 
|---|
| 12 | 
 | 
|---|
| 13 | TaskHandle_t xTaskDebugAndLog;
 | 
|---|
| 14 | xSemaphoreHandle xMutexAccessUSB;
 | 
|---|
| 15 | xQueueHandle QueueReceiveUSB;
 | 
|---|
| 16 | extern network_settings table_network[MAX_IP];
 | 
|---|
| 17 | extern RealTimeClock_typeDef RealTimeClock;
 | 
|---|
| 18 | extern USBD_HandleTypeDef hUsbDeviceFS;
 | 
|---|
| 19 | extern ETH_HandleTypeDef heth;
 | 
|---|
| 20 | 
 | 
|---|
| 21 | uint32_t state_level = 0x0001;
 | 
|---|
| 22 | char debug_buffer[2048];
 | 
|---|
| 23 | 
 | 
|---|
| 24 | static void vDebugTask(void *arg);
 | 
|---|
| 25 | int str2int(char *par);
 | 
|---|
| 26 | 
 | 
|---|
| 27 | void dcmd_help(uint32_t param);
 | 
|---|
| 28 | void dcmd_debug(uint32_t param);
 | 
|---|
| 29 | void dcmd_reboot(uint32_t param);
 | 
|---|
| 30 | void dcmd_date(uint32_t param);
 | 
|---|
| 31 | void dcmd_ifconfig(uint32_t param);
 | 
|---|
| 32 | 
 | 
|---|
| 33 | 
 | 
|---|
| 34 | void dcmd_log_read(uint32_t param);
 | 
|---|
| 35 | void dcmd_filesystem(uint32_t param);
 | 
|---|
| 36 | 
 | 
|---|
| 37 | void dcmd_t(uint32_t param);
 | 
|---|
| 38 | 
 | 
|---|
| 39 | CMD_STRUCT cmds[] = {
 | 
|---|
| 40 |         {"help", dcmd_help, PARAM_INT},
 | 
|---|
| 41 |         {"debug", dcmd_debug, PARAM_INT},
 | 
|---|
| 42 |         {"reboot", dcmd_reboot, PARAM_INT},
 | 
|---|
| 43 |         {"date", dcmd_date, PARAM_INT},
 | 
|---|
| 44 |         {"ifconfig", dcmd_ifconfig, PARAM_INT},
 | 
|---|
| 45 |         
 | 
|---|
| 46 |         
 | 
|---|
| 47 |         {"logread", dcmd_log_read, PARAM_INT},
 | 
|---|
| 48 |         {"filesystem", dcmd_filesystem, PARAM_INT},
 | 
|---|
| 49 |         {"t", dcmd_t, PARAM_INT},
 | 
|---|
| 50 |         {NULL, NULL, NULL}
 | 
|---|
| 51 | };
 | 
|---|
| 52 | 
 | 
|---|
| 53 | void __debug_init(void)
 | 
|---|
| 54 | {
 | 
|---|
| 55 |         xMutexAccessUSB = xSemaphoreCreateMutex();
 | 
|---|
| 56 |         QueueReceiveUSB = xQueueCreate(256, sizeof(uint8_t));
 | 
|---|
| 57 |         xTaskCreate(vDebugTask, "debug streams", 512, NULL, 0, &xTaskDebugAndLog); 
 | 
|---|
| 58 | }
 | 
|---|
| 59 | 
 | 
|---|
| 60 | uint8_t debug_wait_transmit(void)
 | 
|---|
| 61 | {
 | 
|---|
| 62 |         uint32_t count = 0;
 | 
|---|
| 63 |         USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
 | 
|---|
| 64 |         if(hcdc == NULL) return 0;
 | 
|---|
| 65 |         while(hcdc->TxState != 0){
 | 
|---|
| 66 |                 osDelay(1);
 | 
|---|
| 67 |                 if(count++ == 500)return 0;
 | 
|---|
| 68 |         }
 | 
|---|
| 69 |         return 1;
 | 
|---|
| 70 | }
 | 
|---|
| 71 | 
 | 
|---|
| 72 | uint8_t __debug(uint32_t level, const char *format, ...)
 | 
|---|
| 73 | {
 | 
|---|
| 74 |         uint32_t msg_len;
 | 
|---|
| 75 |         if(xTaskDebugAndLog == NULL) return 0;
 | 
|---|
| 76 |         
 | 
|---|
| 77 |         if(state_level & level){
 | 
|---|
| 78 |                 xSemaphoreTake(xMutexAccessUSB, portMAX_DELAY);
 | 
|---|
| 79 |                 va_list args;
 | 
|---|
| 80 |                 va_start (args, format);
 | 
|---|
| 81 |                 vsprintf (debug_buffer, format, args);
 | 
|---|
| 82 |                 va_end (args);
 | 
|---|
| 83 |                 msg_len = strlen(debug_buffer);
 | 
|---|
| 84 |                 if(msg_len <= 0) {
 | 
|---|
| 85 |                         xSemaphoreGive(xMutexAccessUSB);
 | 
|---|
| 86 |                         return 0;
 | 
|---|
| 87 |                 }
 | 
|---|
| 88 |                 if(debug_wait_transmit()) debug_transmit((uint8_t*)debug_buffer, msg_len); 
 | 
|---|
| 89 |                 xSemaphoreGive(xMutexAccessUSB);
 | 
|---|
| 90 |         }
 | 
|---|
| 91 |         return 1;
 | 
|---|
| 92 | }
 | 
|---|
| 93 | 
 | 
|---|
| 94 | /* ------------------- Receive ---------------------*/
 | 
|---|
| 95 | void debug_receive(uint8_t *Buf, uint32_t *Len)
 | 
|---|
| 96 | {
 | 
|---|
| 97 |         portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
 | 
|---|
| 98 |         for(uint32_t i = 0; i < *Len; i++) xQueueSendFromISR(QueueReceiveUSB, &Buf[i], &xHigherPriorityTaskWoken);
 | 
|---|
| 99 | }
 | 
|---|
| 100 | 
 | 
|---|
| 101 | static void vDebugTask(void *arg)
 | 
|---|
| 102 | {
 | 
|---|
| 103 |         CMD_STRUCT *desc;
 | 
|---|
| 104 |         uint32_t i, spacepos, cmd_len = 0, lenparam = 0, paramn;
 | 
|---|
| 105 |         char receive_symbol;
 | 
|---|
| 106 |         char cmd[CMDLEN], param[CMDLEN]; 
 | 
|---|
| 107 | 
 | 
|---|
| 108 |         for(;;){
 | 
|---|
| 109 |                 if(xQueueReceive(QueueReceiveUSB, &receive_symbol, portMAX_DELAY) == pdTRUE) {
 | 
|---|
| 110 |                         if (cmd_len >= CMDLEN) cmd_len = CMDLEN-1;
 | 
|---|
| 111 |                         if ((receive_symbol != 0x0D) && (receive_symbol != 0x0A && (receive_symbol != 0x08))){
 | 
|---|
| 112 |                                 cmd[cmd_len] = receive_symbol;
 | 
|---|
| 113 |                                 cmd_len++;
 | 
|---|
| 114 |                                 if (cmd_len >= CMDLEN) cmd_len--;
 | 
|---|
| 115 |                                 else debug_transmit((uint8_t*)&receive_symbol, 1);
 | 
|---|
| 116 |                         }
 | 
|---|
| 117 | 
 | 
|---|
| 118 |                         if (receive_symbol == 0x08) {
 | 
|---|
| 119 |                                 if (cmd_len > 0) cmd_len-- ;
 | 
|---|
| 120 |                                 debug_transmit((uint8_t*)"\b \b", 3);
 | 
|---|
| 121 |                         }
 | 
|---|
| 122 |                         if ((receive_symbol == 0x0A)||(receive_symbol == 0x0D)) { 
 | 
|---|
| 123 |                                 cmd[cmd_len] = 0; 
 | 
|---|
| 124 |                                 debug_transmit((uint8_t*)"\r\n", 2);
 | 
|---|
| 125 |                                 spacepos = 0;
 | 
|---|
| 126 |                                 for (i = 0; i <= cmd_len; i++){
 | 
|---|
| 127 |                                         if (cmd[i] == ' '){
 | 
|---|
| 128 |                                                 spacepos = i;   
 | 
|---|
| 129 |                                                 break;
 | 
|---|
| 130 |                                         }
 | 
|---|
| 131 |                                 }
 | 
|---|
| 132 |                                                 
 | 
|---|
| 133 |                                 if (spacepos>0) {
 | 
|---|
| 134 |                                         for (i = spacepos + 1; i <= cmd_len; i++){
 | 
|---|
| 135 |                                                 param[i-spacepos-1] = cmd[i];                           
 | 
|---|
| 136 |                                         }
 | 
|---|
| 137 |                                         cmd[spacepos]=0;
 | 
|---|
| 138 |                                         lenparam =  cmd_len - (spacepos - 1);
 | 
|---|
| 139 |                                 }
 | 
|---|
| 140 |                                 else param[0] = 0;
 | 
|---|
| 141 |                                 paramn = str2int(param);
 | 
|---|
| 142 |                                 cmd_len = 0;
 | 
|---|
| 143 | 
 | 
|---|
| 144 |                                 
 | 
|---|
| 145 |                                 for(desc = cmds; desc->cmd; desc++){
 | 
|---|
| 146 |                                         if ((strcmp((char*)cmd, desc->cmd)) == 0){
 | 
|---|
| 147 |                                                 if(desc->typepar == PARAM_INT) desc->pfunc(paramn);
 | 
|---|
| 148 |                                                 if(desc->typepar == PARAM_STR) desc->pfunc(param, lenparam);
 | 
|---|
| 149 |                                                 break;
 | 
|---|
| 150 |                                         }
 | 
|---|
| 151 |                                 }               
 | 
|---|
| 152 |                                 if(desc->cmd == NULL)__debug(DEBUG_SERVSE, "Unknown cmd: %s\r\n",cmd);
 | 
|---|
| 153 |                                 __debug(DEBUG_SERVSE, "cmd >");
 | 
|---|
| 154 |                         }
 | 
|---|
| 155 |                 }
 | 
|---|
| 156 |         }
 | 
|---|
| 157 | }
 | 
|---|
| 158 | 
 | 
|---|
| 159 | int str2int(char *par){
 | 
|---|
| 160 |   int i, j, r = 0, len, dig;
 | 
|---|
| 161 |   len=strlen(par);
 | 
|---|
| 162 |   for (j = 0; j < len; j++) {
 | 
|---|
| 163 |     dig = ((int)(par[j]) - 0x30);
 | 
|---|
| 164 |                 for (i = 0; i < (len - j - 1); i++) dig = dig * 10;;
 | 
|---|
| 165 |                 r = r + dig;
 | 
|---|
| 166 |   }
 | 
|---|
| 167 |   return r;
 | 
|---|
| 168 | }
 | 
|---|
| 169 | 
 | 
|---|
| 170 | /* ----------------------------------------------------------------------------------------- */
 | 
|---|
| 171 | /* ######################################################################################### */
 | 
|---|
| 172 | void dcmd_help(uint32_t param){
 | 
|---|
| 173 |         CMD_STRUCT *desc;
 | 
|---|
| 174 |   param = param;
 | 
|---|
| 175 |   __debug(DEBUG_SERVSE, "______________________\n\rCompiled: %s %s\n\r___commands:___\n\r", __DATE__, __TIME__);
 | 
|---|
| 176 |         
 | 
|---|
| 177 |         for(desc = cmds; desc->cmd; desc++)__debug(DEBUG_SERVSE, "%s\n\r", desc->cmd);
 | 
|---|
| 178 | }
 | 
|---|
| 179 | 
 | 
|---|
| 180 | void dcmd_debug(uint32_t param)
 | 
|---|
| 181 | {
 | 
|---|
| 182 |         if(param == NUM_LEVEL_DEBUG)param = 0;
 | 
|---|
| 183 |         
 | 
|---|
| 184 |         if(param != 0){
 | 
|---|
| 185 |                 state_level ^= (1 << param);
 | 
|---|
| 186 |                 param = 0;
 | 
|---|
| 187 |         }
 | 
|---|
| 188 |   if(param == 0){       
 | 
|---|
| 189 |         __debug(DEBUG_SERVSE, "CMD:debug\r\n\
 | 
|---|
| 190 |         1 - ETH %s\r\n\
 | 
|---|
| 191 |         2 - PLC CROSS %s\r\n\
 | 
|---|
| 192 |         3 - PLC TRANSIT %s\r\n\
 | 
|---|
| 193 |         4 - WEB SERVER %s\r\n\
 | 
|---|
| 194 |         5 - TEMP %s\r\n", 
 | 
|---|
| 195 |                         (state_level & DEBUG_ETH) ? "on" : "off",
 | 
|---|
| 196 |                         (state_level & DEBUG_PLC_CROSS) ? "on" : "off",
 | 
|---|
| 197 |                         (state_level & DEBUG_PLC_TRANSIT) ? "on" : "off",
 | 
|---|
| 198 |                         (state_level & DEBUG_WEB_SERVER) ? "on" : "off",
 | 
|---|
| 199 |                         (state_level & DEBUG_TEMP) ? "on" : "off");
 | 
|---|
| 200 |     return;
 | 
|---|
| 201 |   }
 | 
|---|
| 202 | }
 | 
|---|
| 203 | 
 | 
|---|
| 204 | void dcmd_reboot(uint32_t param)
 | 
|---|
| 205 | {
 | 
|---|
| 206 |         switch(param){
 | 
|---|
| 207 |                 case 1:
 | 
|---|
| 208 |                         __debug(DEBUG_SERVSE, "Reboot S-Port\r\n");
 | 
|---|
| 209 |                         vTaskDelay(500);
 | 
|---|
| 210 |                         NVIC_SystemReset();
 | 
|---|
| 211 |                         break;
 | 
|---|
| 212 |                 case 2:
 | 
|---|
| 213 |                         __debug(DEBUG_SERVSE, "Reboot PHY\r\n");
 | 
|---|
| 214 |                         HAL_GPIO_WritePin(PHY_nRST_GPIO_Port, PHY_nRST_Pin, GPIO_PIN_RESET);
 | 
|---|
| 215 |                         osDelay(50);
 | 
|---|
| 216 |                         HAL_GPIO_WritePin(PHY_nRST_GPIO_Port, PHY_nRST_Pin, GPIO_PIN_SET);
 | 
|---|
| 217 |                         HAL_ETH_WritePHYRegister(&heth, 0x1B, 0x500); // link interrupt enable
 | 
|---|
| 218 |                         break;
 | 
|---|
| 219 |                 default: __debug(DEBUG_SERVSE, "CMD:Reboot\r\n\
 | 
|---|
| 220 |                                         1 - Reboot S-Port\r\n\
 | 
|---|
| 221 |                                         2 - Reboot PHY\r\n");
 | 
|---|
| 222 |         }
 | 
|---|
| 223 | }
 | 
|---|
| 224 | 
 | 
|---|
| 225 | void dcmd_filesystem(uint32_t param)
 | 
|---|
| 226 | {
 | 
|---|
| 227 |         PWR->CR |= PWR_CR_DBP; 
 | 
|---|
| 228 |         RTC->BKP0R |= 0x01;
 | 
|---|
| 229 |         PWR->CR &= ~PWR_CR_DBP;
 | 
|---|
| 230 |         dcmd_reboot(1);
 | 
|---|
| 231 | }
 | 
|---|
| 232 | 
 | 
|---|
| 233 | void dcmd_ifconfig(uint32_t param)
 | 
|---|
| 234 | {
 | 
|---|
| 235 |         uint32_t RX_frames = 0, RX_error = 0, TX_frames = 0;
 | 
|---|
| 236 |         uint32_t cnt = 0;
 | 
|---|
| 237 |         char Sbuffer[512] = {0};
 | 
|---|
| 238 |         
 | 
|---|
| 239 |         cnt += sprintf(&Sbuffer[cnt], "\r\n# ifconfig eth0 inet %s netmask %s\r\n", table_network[0].ipv4_addr, table_network[0].ipv4_nm);
 | 
|---|
| 240 |         cnt += sprintf(&Sbuffer[cnt], "# ifconfig eth0 %s\r\n# ifconfig\r\n", (table_network[0].netif.flags & NETIF_FLAG_UP) ? "up" : "down");
 | 
|---|
| 241 |         cnt += sprintf(&Sbuffer[cnt], "eth0\tLink encap:Ethernet  HWaddr 02:AD:C8:%02X:%02X:%02X \r\n", table_network[0].netif.hwaddr[3], table_network[0].netif.hwaddr[4], table_network[0].netif.hwaddr[5]);
 | 
|---|
| 242 |         cnt += sprintf(&Sbuffer[cnt], "\tinet addr:%s  Bcast:192.168.0.255  Mask:%s \r\n", table_network[0].ipv4_addr, table_network[0].ipv4_nm);
 | 
|---|
| 243 |         cnt += sprintf(&Sbuffer[cnt], "\t%s BROADCAST RUNNING MULTICAST  MTU:%d  Metric:1 \r\n", (table_network[0].netif.flags & NETIF_FLAG_UP) ? "UP" : "DOWN", table_network[0].netif.mtu);
 | 
|---|
| 244 |         
 | 
|---|
| 245 |         RX_frames = ETH->MMCRGUFCR;
 | 
|---|
| 246 |         RX_error = ETH->MMCRFCECR;
 | 
|---|
| 247 |         cnt += sprintf(&Sbuffer[cnt], "\tRX packets:%d errors CRC:%d\r\n", RX_frames, RX_error);
 | 
|---|
| 248 |         TX_frames = ETH->MMCTGFCR;
 | 
|---|
| 249 |         cnt += sprintf(&Sbuffer[cnt], "\tTX packets:%d\r\n#\r\n", TX_frames);
 | 
|---|
| 250 |         
 | 
|---|
| 251 |         __debug(DEBUG_SERVSE, "%s", Sbuffer);
 | 
|---|
| 252 | }
 | 
|---|
| 253 | 
 | 
|---|
| 254 | void dcmd_log_read(uint32_t param)
 | 
|---|
| 255 | {
 | 
|---|
| 256 | //      FIL FlashFile;
 | 
|---|
| 257 | //      uint32_t ByteRead = 0, ByteWritten = 0;
 | 
|---|
| 258 | //      uint8_t buff[256] = {0};
 | 
|---|
| 259 | //      
 | 
|---|
| 260 | //      if((f_open(&FlashFile, "log.txt", FA_READ)) == FR_OK){
 | 
|---|
| 261 | //              while(f_eof(&FlashFile) == 0){
 | 
|---|
| 262 | //                      f_lseek(&FlashFile, ByteRead);
 | 
|---|
| 263 | //                      f_read(&FlashFile, buff, 256, (UINT*)&ByteWritten);
 | 
|---|
| 264 | //                      ByteRead += 256;
 | 
|---|
| 265 | //                      __debug(DEBUG_SERVSE, (char*)buff);
 | 
|---|
| 266 | //              }
 | 
|---|
| 267 | //              f_close(&FlashFile);
 | 
|---|
| 268 | //      }
 | 
|---|
| 269 | }
 | 
|---|
| 270 | 
 | 
|---|
| 271 | void dcmd_date(uint32_t param)
 | 
|---|
| 272 | {
 | 
|---|
| 273 |         __debug(DEBUG_SERVSE, "RTC: Data: %02d.%02d.%04d, Time: %02d:%02d:%02d\r\nRTC: Current flags: WDT -> %s; BAT_LOW -> %s; TMR -> %s; OSC_FAIL -> %s\r\n", 
 | 
|---|
| 274 |         RealTimeClock.Data.Day, RealTimeClock.Data.Month, RealTimeClock.Data.Year, RealTimeClock.Time.Hour, RealTimeClock.Time.Min, RealTimeClock.Time.Sec,
 | 
|---|
| 275 |         (RealTimeClock.Flags.WDT) ? "true" : "false", (RealTimeClock.Flags.BAT_LOW) ? "true" : "false", (RealTimeClock.Flags.TMR) ? "true" : "false", (RealTimeClock.Flags.OSC_FAIL) ? "true" : "false");
 | 
|---|
| 276 | }
 | 
|---|
| 277 | 
 | 
|---|
| 278 | FIL FlashFile;
 | 
|---|
| 279 | 
 | 
|---|
| 280 | void dcmd_t(uint32_t param)
 | 
|---|
| 281 | {
 | 
|---|
| 282 |         FATFS *fs; 
 | 
|---|
| 283 |         uint32_t clust = 0;
 | 
|---|
| 284 |         f_getfree("/", (DWORD*)&clust, &fs);    
 | 
|---|
| 285 |         
 | 
|---|
| 286 |         __debug(DEBUG_SERVSE, "fre_clust: %lu \r\n", clust);
 | 
|---|
| 287 |         __debug(DEBUG_SERVSE, "n_fatent: %lu \r\n", fs->n_fatent);
 | 
|---|
| 288 |         __debug(DEBUG_SERVSE, "fs_csize: %lu \r\n", fs->csize);
 | 
|---|
| 289 |         
 | 
|---|
| 290 |         uint32_t tot_sect = (fs->n_fatent - 2) * fs->csize;
 | 
|---|
| 291 |         __debug(DEBUG_SERVSE, "tot_sect: %lu \r\n", tot_sect);
 | 
|---|
| 292 | 
 | 
|---|
| 293 |         uint32_t fre_sect = clust * fs->csize;
 | 
|---|
| 294 |         __debug(DEBUG_SERVSE, "fre_sect: %lu \r\n", fre_sect);
 | 
|---|
| 295 | 
 | 
|---|
| 296 |         __debug(DEBUG_SERVSE, "%lu KB total drive space. \r\n%lu KB available.\r\n", fre_sect/2, tot_sect/2);
 | 
|---|
| 297 | }
 | 
|---|
| 298 | 
 | 
|---|
| 299 | /* ----------------------------------------------------------------------------------------- */
 | 
|---|
| 300 | /* ######################################################################################### */
 | 
|---|
| 301 | /* ÇÀÏÈÑÜ ËÎÃÀ ÍÀ ÔËÅØ --------------------------------------------------------------------- */
 | 
|---|
| 302 | extern xSemaphoreHandle MutexAccessFlash;
 | 
|---|
| 303 | char log_buffer[2048];
 | 
|---|
| 304 | 
 | 
|---|
| 305 | void __logWrite(const char *format, ...) // çàïèñü â ëîã
 | 
|---|
| 306 | {
 | 
|---|
| 307 |                 uint32_t size = 0; 
 | 
|---|
| 308 |     xSemaphoreTake(MutexAccessFlash, portMAX_DELAY);// ïûòàåìñÿ âçÿòü ìüþòåêñ äëÿ çàïèñè ëîãà
 | 
|---|
| 309 |                 va_list args;
 | 
|---|
| 310 |                 va_start (args, format);
 | 
|---|
| 311 |                 vsprintf (log_buffer, format, args);
 | 
|---|
| 312 |                 va_end (args);
 | 
|---|
| 313 |         
 | 
|---|
| 314 |                 if((f_open(&FlashFile, "log.txt", FA_OPEN_ALWAYS | FA_WRITE)) == FR_OK){
 | 
|---|
| 315 |                         size = f_size(&FlashFile);
 | 
|---|
| 316 |                         if(size >= 524288){ // áîëüøå èëè ðàâíî 512 ÊÁ
 | 
|---|
| 317 |                                 f_close(&FlashFile);
 | 
|---|
| 318 |                                 f_unlink("old_log.txt");
 | 
|---|
| 319 |                                 f_rename("log.txt", "old_log.txt");
 | 
|---|
| 320 |                                 if((f_open(&FlashFile, "log.txt", FA_OPEN_ALWAYS | FA_WRITE)) != FR_OK){
 | 
|---|
| 321 |                                         xSemaphoreGive(MutexAccessFlash); // Îòäàåì ìüþòåêñ
 | 
|---|
| 322 |                                         return;
 | 
|---|
| 323 |                                 }
 | 
|---|
| 324 |                                 else size = f_size(&FlashFile);
 | 
|---|
| 325 |                         }
 | 
|---|
| 326 |                         f_lseek(&FlashFile, size);
 | 
|---|
| 327 |                         f_printf(&FlashFile, "%02d.%02d.%02d/%02d:%02d:%02d %s",RealTimeClock.Data.Day, RealTimeClock.Data.Month, 
 | 
|---|
| 328 |                                                                                                                 RealTimeClock.Data.Year, RealTimeClock.Time.Hour, RealTimeClock.Time.Min, RealTimeClock.Time.Sec, log_buffer);
 | 
|---|
| 329 |                         f_close(&FlashFile);
 | 
|---|
| 330 |                 }
 | 
|---|
| 331 |                 xSemaphoreGive(MutexAccessFlash); // Îòäàåì ìüþòåêñ
 | 
|---|
| 332 | }
 | 
|---|