#include "FileSysTask.h" #include "WatchDogTask.h" #include "UpcCommTask.h" #include "EepromTaskConf.h" #include "McuBspEeprom.h" #include "TimerTask.h" #include "ff.h" #include "RtcDrv.h" #include "FileSys.h" #include #include #include #include static int gFileTaskMutex = 0; // 操作日志文件的互斥量 static char gLogFilePathW[32] = {0}; // 日志文件的写 static char gDataFilePathW[64] = {0}; // 数据文件的写 static char gLogFilePathR[32] = {0}; // 日志文件的读 static char gDataFilePathR[64] = {0}; // 数据文件的读 static char gTimeBuf[20] = {0}; // 时间字符串缓存 static unsigned char gTaskFileData[559] = {0}; // 一帧文件的数据 static int gTaskFileTimerId = -1; // 文件任务的定时器 static int gTaskFileReplaceEnable = 0; static unsigned int gTaskFileSaveSector = 0; // 当前文件存储区域标志位 static unsigned int gTaskFileSaveCardKind = 0; // 用来进行文件判断的 /* 上位机读取文件时需要的参数 */ static unsigned short gFileTaskAskedYear = 0; // 年 static unsigned char gFileTaskAskedMon = 0; // 月 static unsigned char gFileTaskAskedDay = 0; // 日 static int gFileTaskAskedType = -1; // 文件类型获取 static unsigned char gFileTaskUpTransmiting = 0; // 是否有文件正在传输的标志位 /* 文件任务的看门狗 */ static int gTaskFileWatchdogId = -1; // 网络通信任务的看门狗ID /* 下位机发送数据需要的参数 */ static uint32_t gTaskFileSize = 0; static uint32_t gTaskFileDate = 0; static uint32_t gTaskFileDataAll = 0; static uint32_t gTaskFileDataLocal = 1; static uint16_t gTaskFileSendSerial = 0; static uint32_t gTaskFileSendCount = 0; static void TaskFileEnableCheckSector(void); static int TaskFileCreateUsr0(void); static int TaskFileCreateUsr1(void); /* 初始化文件任务 */ int TaskFileInit(void) { unsigned int AllSpace = 0; unsigned int RemainingSpace = 0; if (0 > TaskFileCreateUsr0()) { return -1; } if (0 > TaskFileCreateUsr1()) { return -1; } /* 获取文件存储区域 */ McuBspEepromReadValue(FILE_SYS_SAVE_SECTOR_ADDR, &gTaskFileSaveSector, sizeof(gTaskFileSaveSector)); if (gTaskFileSaveSector > 1 || gTaskFileSaveSector < 1) { gTaskFileSaveSector = 0; } FileGetDiskSpace(&AllSpace, &RemainingSpace); if (RemainingSpace > (AllSpace - (AllSpace / 4 * 3 / 2))) { gTaskFileSaveCardKind = 0; gTaskFileSaveSector = 0; } else { gTaskFileSaveCardKind = 1; } gTaskFileTimerId = TaskTimerRegEventId(); TaskTimerStartEvent(&gTaskFileTimerId, 86400, 0xffffffff, TaskFileEnableCheckSector); return 0; } int TaskFileLogWrite(char *Wdata, unsigned int WdataLen, unsigned int *RealWLen) { FIL LogFile; FRESULT fres; DRV_RTC_TIME RtcTime; if (0 > FileGetFileInitFlag()) { return -1; } if (gFileTaskMutex == 0) { gFileTaskMutex = 1; } else { return -1; // 表示文件被占用中 } if (Wdata == NULL || WdataLen == 0 || RealWLen == NULL) { gFileTaskMutex = 0; return -1; } /* 获取RTC时钟 */ RtcGetTime(&RtcTime); if (gTaskFileSaveSector == 0) { sprintf(gLogFilePathW, "/Usr0/Log/%d-%d-%d_run.log", RtcTime.year, RtcTime.month, RtcTime.date); } else { sprintf(gLogFilePathW, "/Usr1/Log/%d-%d-%d_run.log", RtcTime.year, RtcTime.month, RtcTime.date); } fres = f_open(&LogFile, gLogFilePathW, FA_OPEN_APPEND | FA_WRITE); if (fres != FR_OK) { /* 文件打开失败 */ gFileTaskMutex = 0; return -1; } sprintf(gTimeBuf, "%02d:%02d:%02d\t", RtcTime.hour, RtcTime.minute, RtcTime.second); f_write(&LogFile, gTimeBuf, strlen(gTimeBuf), RealWLen); // 写入事件发生的时间 f_write(&LogFile, Wdata, WdataLen, RealWLen); f_close(&LogFile); gFileTaskMutex = 0; return 0; } /* 数据文件写入 */ int TaskFileDataWrite(const char *DataType, char *Wdata, unsigned int WdataLen, unsigned int *RealWLen) { FIL DataFile; FRESULT fres; DRV_RTC_TIME RtcTime; if (0 > FileGetFileInitFlag()) { return -1; } if (gFileTaskMutex == 0) { gFileTaskMutex = 1; } else { return -1; // 表示文件被占用中 } if (DataType == NULL || Wdata == NULL || WdataLen == 0 || RealWLen == NULL) { gFileTaskMutex = 0; return -1; } /* 获取RTC时钟 */ RtcGetTime(&RtcTime); if (gTaskFileSaveSector == 0) { sprintf(gDataFilePathW, "/Usr0/Data/%d-%d-%d_%s.csv", RtcTime.year, RtcTime.month, RtcTime.date, DataType); } else { sprintf(gDataFilePathW, "/Usr1/Data/%d-%d-%d_%s.csv", RtcTime.year, RtcTime.month, RtcTime.date, DataType); } fres = f_open(&DataFile, gDataFilePathW, FA_OPEN_APPEND | FA_WRITE); if (fres != FR_OK) { /* 文件打开失败 */ gFileTaskMutex = 0; return -1; } sprintf(gTimeBuf, "%02d:%02d:%02d,", RtcTime.hour, RtcTime.minute, RtcTime.second); f_write(&DataFile, gTimeBuf, strlen(gTimeBuf), RealWLen); // 写入事件发生的时间 f_write(&DataFile, Wdata, WdataLen, RealWLen); f_write(&DataFile, "\r\n", strlen("\r\n"), RealWLen); f_close(&DataFile); gFileTaskMutex = 0; return 0; } /* 文件任务 */ void TaskSysFile(void *arg) { int i = 0; unsigned int RealWbyte; int ret; FRESULT fres; FIL FileTmp; unsigned int Wcount = 0; char LogBuf[64] = {0}; gTaskFileWatchdogId = TaskWatchdogRegEvent("TaskFileSys"); /* 将接收缓存提取数据任务开启写入日志 */ TaskFileLogWrite("TaskFile: Join in!!\n", strlen("TaskFile: Join in!!\n"), &RealWbyte); while (1) { OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); if (gFileTaskUpTransmiting == 1) { if (gFileTaskAskedType == FILE_DATA_TYPE) { /* 等待其他调用文件的程序结束 */ while (gFileTaskMutex == 1) { OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); } gFileTaskMutex = 1; fres = f_open(&FileTmp, gDataFilePathR, FA_READ | FA_OPEN_EXISTING); if (fres != FR_OK) { gFileTaskUpTransmiting = 0; gFileTaskMutex = 0; OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); continue; } gTaskFileSize = FileTmp.obj.objsize; gTaskFileDate = gFileTaskAskedYear * 10000 + gFileTaskAskedMon * 100 + gFileTaskAskedDay; gTaskFileDataAll = (gTaskFileSize / 512) + 1; gTaskFileData[0] = FILE_DATA_TYPE; gTaskFileData[1] = (uint8_t)((gTaskFileDate & 0xff000000) >> 24); gTaskFileData[2] = (uint8_t)((gTaskFileDate & 0x00ff0000) >> 16); gTaskFileData[3] = (uint8_t)((gTaskFileDate & 0x0000ff00) >> 8); gTaskFileData[4] = (uint8_t)(gTaskFileDate & 0x000000ff); for (i = 0; i < (strlen(gDataFilePathR) - 6); i++) { gTaskFileData[5 + i] = gDataFilePathR[i + 11]; } } else if (gFileTaskAskedType == FILE_LOG_TYPE) { /* 等待其他调用文件的程序结束 */ while (gFileTaskMutex == 1) { OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); } gFileTaskMutex = 1; fres = f_open(&FileTmp, gLogFilePathR, FA_READ | FA_OPEN_EXISTING); if (fres != FR_OK) { gFileTaskUpTransmiting = 0; gFileTaskMutex = 0; OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); continue; } gTaskFileSize = FileTmp.obj.objsize; gTaskFileDate = gFileTaskAskedYear * 10000 + gFileTaskAskedMon * 100 + gFileTaskAskedDay; gTaskFileDataAll = (gTaskFileSize / 512) + 1; gTaskFileData[0] = FILE_LOG_TYPE; gTaskFileData[1] = (uint8_t)((gTaskFileDate & 0xff000000) >> 24); gTaskFileData[2] = (uint8_t)((gTaskFileDate & 0x00ff0000) >> 16); gTaskFileData[3] = (uint8_t)((gTaskFileDate & 0x0000ff00) >> 8); gTaskFileData[4] = (uint8_t)(gTaskFileDate & 0x000000ff); for (i = 0; i < (strlen(gLogFilePathR) - 10); i++) { gTaskFileData[5 + i] = gLogFilePathR[i + 10]; } } while (i < 30) { gTaskFileData[5 + i] = 0; i++; } gTaskFileData[35] = (uint8_t)((gTaskFileSize & 0xff000000) >> 24); gTaskFileData[36] = (uint8_t)((gTaskFileSize & 0x00ff0000) >> 16); gTaskFileData[37] = (uint8_t)((gTaskFileSize & 0x0000ff00) >> 8); gTaskFileData[38] = (uint8_t)(gTaskFileSize & 0x000000ff); gTaskFileData[39] = (uint8_t)((gTaskFileDataAll & 0xff000000) >> 24); gTaskFileData[40] = (uint8_t)((gTaskFileDataAll & 0x00ff0000) >> 16); gTaskFileData[41] = (uint8_t)((gTaskFileDataAll & 0x0000ff00) >> 8); gTaskFileData[42] = (uint8_t)(gTaskFileDataAll & 0x000000ff); gTaskFileSendCount = 0; while (1) { Wcount = 0; gTaskFileData[43] = (uint8_t)((gTaskFileDataLocal & 0xff000000) >> 24); gTaskFileData[44] = (uint8_t)((gTaskFileDataLocal & 0x00ff0000) >> 16); gTaskFileData[45] = (uint8_t)((gTaskFileDataLocal & 0x0000ff00) >> 8); gTaskFileData[46] = (uint8_t)(gTaskFileDataLocal & 0x000000ff); f_read(&FileTmp, &gTaskFileData[47], 512, &Wcount); if ((f_eof(&FileTmp)) && (Wcount == 0)) { break; } /* 发送数据 */ TaskUpcCommSendMessage(FILE_TRANSMIT_MESSAGE, &gTaskFileSendSerial, gTaskFileData, Wcount + 47); gTaskFileSendSerial++; gTaskFileDataLocal++; gTaskFileSendCount++; TaskWatchdogFreed(gTaskFileWatchdogId); OSTimeDly(50); } f_close(&FileTmp); gTaskFileDataLocal = 1; gFileTaskUpTransmiting = 0; if (gFileTaskMutex == 1) { gFileTaskMutex = 0; } if (gFileTaskMutex == 1) { gFileTaskMutex = 0; } sprintf(LogBuf, "FILE SEND %d packet!!!!\r\n", gTaskFileSendCount); TaskFileLogWrite(LogBuf, strlen(LogBuf), &RealWbyte); } if (gTaskFileReplaceEnable == 1) { unsigned int AllSpace = 0; unsigned int RemainingSpace = 0; while (gFileTaskMutex == 1) { OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); } gFileTaskMutex = 1; while (gFileTaskMutex == 1) { OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); } gFileTaskMutex = 1; FileGetDiskSpace(&AllSpace, &RemainingSpace); /* 更换空间 */ if (RemainingSpace < (AllSpace / 4)) { if (gTaskFileSaveSector == 0) { do { OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); fres = f_unlink("/Usr1"); } while (fres != FR_OK || fres == FR_NO_PATH); do { OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); ret = TaskFileCreateUsr1(); } while (ret < 0); gTaskFileSaveSector = 1; } else { do { OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); fres = f_unlink("/Usr0"); } while (fres != FR_OK || fres == FR_NO_PATH); do { OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); ret = TaskFileCreateUsr0(); } while (ret < 0); gTaskFileSaveSector = 0; } } else if (RemainingSpace < (AllSpace - (AllSpace / 4 * 3 / 2)) && gTaskFileSaveCardKind == 0) { do { OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); fres = f_unlink("/Usr1"); } while (fres != FR_OK || fres == FR_NO_PATH); do { OSTimeDly(10); TaskWatchdogFreed(gTaskFileWatchdogId); ret = TaskFileCreateUsr1(); } while (ret < 0); gTaskFileSaveSector = 1; } if (gFileTaskMutex == 1) { gFileTaskMutex = 0; } } } } /* 获取文件使能 */ int TaskFileEnableSend(unsigned char Type, unsigned short Year, unsigned char Mon, unsigned char Day, unsigned char Action, const char *DataType) { FIL File; FRESULT fres; if (gFileTaskUpTransmiting == 1 && Action == FILE_UPLOAD) { return -1; } gFileTaskAskedYear = Year; // 年 gFileTaskAskedMon = Mon; // 月 gFileTaskAskedDay = Day; // 日 gFileTaskAskedType = Type; if (Type == FILE_DATA_TYPE) { if (gFileTaskMutex == 1) { return -1; } gFileTaskMutex = 1; memset(gDataFilePathR, 0, sizeof(gDataFilePathR)); sprintf(gDataFilePathR, "/Usr0/Data/%d-%d-%d_%s.csv", Year, Mon, Day, DataType); /* 判断文件是否存在 */ fres = f_open(&File, gDataFilePathR, FA_READ); if (fres != FR_OK) { sprintf(gDataFilePathR, "/Usr1/Data/%d-%d-%d_%s.csv", Year, Mon, Day, DataType); fres = f_open(&File, gDataFilePathR, FA_READ); if (fres != FR_OK) { gFileTaskMutex = 0; return -1; } } f_close(&File); if (Action == FILE_DELETE) { f_unlink(gDataFilePathR); gFileTaskMutex = 0; return 0; } gFileTaskMutex = 0; } else if (Type == FILE_LOG_TYPE) { if (gFileTaskMutex == 1) { return -1; } gFileTaskMutex = 1; memset(gLogFilePathR, 0, sizeof(gLogFilePathR)); sprintf(gLogFilePathR, "/Usr0/Log/%d-%d-%d_run.log", Year, Mon, Day); fres = f_open(&File, gLogFilePathR, FA_READ); if (fres != FR_OK) { sprintf(gLogFilePathR, "/Usr1/Log/%d-%d-%d_run.log", Year, Mon, Day); fres = f_open(&File, gLogFilePathR, FA_READ); if (fres != FR_OK) { gFileTaskMutex = 0; return -1; } } f_close(&File); if (Action == FILE_DELETE) { f_unlink(gLogFilePathR); gFileTaskMutex = 0; return 0; } gFileTaskMutex = 0; } gFileTaskUpTransmiting = 1; return 0; } /* 获取状态 */ int TaskFileMutexState(void) { return gFileTaskMutex; } static void TaskFileEnableCheckSector(void) { gTaskFileReplaceEnable = 1; } static int TaskFileCreateUsr0(void) { FRESULT fres; DIR dp; fres = f_opendir(&dp, "/Usr0"); if (fres == FR_NO_PATH) { f_mkdir("/Usr0"); } else if (fres != FR_OK) { return -1; } fres = f_opendir(&dp, "/Usr0/log"); if (fres == FR_NO_PATH) { f_mkdir("/Usr0/log"); } else if (fres != FR_OK) { return -1; } fres = f_opendir(&dp, "/Usr0/Data"); if (fres == FR_NO_PATH) { f_mkdir("/Usr0/Data"); } else if (fres != FR_OK) { return -1; } return 0; } static int TaskFileCreateUsr1(void) { FRESULT fres; DIR dp; fres = f_opendir(&dp, "/Usr1"); if (fres == FR_NO_PATH) { f_mkdir("/Usr1"); } else if (fres != FR_OK) { return -1; } fres = f_opendir(&dp, "/Usr1/log"); if (fres == FR_NO_PATH) { f_mkdir("/Usr1/log"); } else if (fres != FR_OK) { return -1; } fres = f_opendir(&dp, "/Usr1/Data"); if (fres == FR_NO_PATH) { f_mkdir("/Usr1/Data"); } else if (fres != FR_OK) { return -1; } return 0; }