165 lines
4.5 KiB
C++
165 lines
4.5 KiB
C++
#include "pch.h"
|
|
|
|
#if EFI_PROD_CODE && EFI_FILE_LOGGING
|
|
|
|
#include "ff.h"
|
|
#include "mmc_card_util.h"
|
|
#include "backup_ram.h"
|
|
#include "mmc_card.h"
|
|
|
|
#define LOG_INDEX_FILENAME "index.txt"
|
|
#define HARD_FAULT_PREFIX "hard_"
|
|
|
|
// 10 because we want at least 4 character name (is that about TS protocol which we do not use any more?)
|
|
#define MIN_FILE_INDEX 10
|
|
int logFileIndex = MIN_FILE_INDEX;
|
|
|
|
static FIL FDLogFile NO_CACHE;
|
|
|
|
void incLogFileName() {
|
|
memset(&FDLogFile, 0, sizeof(FIL)); // clear the memory
|
|
FRESULT ret = f_open(&FDLogFile, LOG_INDEX_FILENAME, FA_READ); // This file has the index for next log file name
|
|
|
|
char data[_MAX_FILLER];
|
|
memset(data, 0, sizeof(data));
|
|
|
|
if (ret == FR_OK) {
|
|
UINT readed = 0;
|
|
// leave one byte for terminating 0
|
|
ret = f_read(&FDLogFile, (void*)data, sizeof(data) - 1, &readed);
|
|
|
|
if (ret != FR_OK) {
|
|
printError("log index file read", ret);
|
|
logFileIndex = MIN_FILE_INDEX;
|
|
} else {
|
|
efiPrintf("Got content [%s] size %d", data, readed);
|
|
logFileIndex = maxI(MIN_FILE_INDEX, atoi(data));
|
|
if (absI(logFileIndex) == ATOI_ERROR_CODE) {
|
|
logFileIndex = MIN_FILE_INDEX;
|
|
} else {
|
|
logFileIndex++; // next file would use next file name
|
|
}
|
|
}
|
|
f_close(&FDLogFile);
|
|
} else if (ret == FR_NO_FILE) {
|
|
// no index file - this is not an error, just an empty SD
|
|
logFileIndex = MIN_FILE_INDEX;
|
|
} else {
|
|
printError("log index file open", ret);
|
|
efiPrintf("%s: not found or error: %d", LOG_INDEX_FILENAME, ret);
|
|
logFileIndex = MIN_FILE_INDEX;
|
|
}
|
|
|
|
// truncate or create new
|
|
ret = f_open(&FDLogFile, LOG_INDEX_FILENAME, FA_CREATE_ALWAYS | FA_WRITE);
|
|
if (ret == FR_OK) {
|
|
UINT writen = 0;
|
|
size_t len = itoa10(data, logFileIndex) - data;
|
|
ret = f_write(&FDLogFile, (void*)data, len, &writen);
|
|
if ((ret != FR_OK) || (len != writen)) {
|
|
printError("log index write", ret);
|
|
}
|
|
f_close(&FDLogFile);
|
|
} else {
|
|
printError("log index file write", ret);
|
|
}
|
|
|
|
efiPrintf("New log file index %d", logFileIndex);
|
|
}
|
|
|
|
bool needsToWriteReportFile() {
|
|
#if EFI_BACKUP_SRAM
|
|
extern ErrorCookie errorCookieOnStart;
|
|
return errorCookieOnStart == ErrorCookie::HardFault;
|
|
#else
|
|
return false;
|
|
#endif // EFI_BACKUP_SRAM
|
|
}
|
|
|
|
PUBLIC_API_WEAK void onBoardWriteErrorFile(FIL *file) {
|
|
UNUSED(file);
|
|
}
|
|
|
|
#if EFI_BACKUP_SRAM
|
|
// todo: unit test? or better file stdlib method to do same?
|
|
static int mystrncasecmp(const char *s1, const char *s2, size_t n) {
|
|
if (n != 0) {
|
|
const char *us1 = (const char *)s1;
|
|
const char *us2 = (const char *)s2;
|
|
|
|
do {
|
|
if (mytolower(*us1) != mytolower(*us2))
|
|
return (mytolower(*us1) - mytolower(*us2));
|
|
if (*us1++ == '\0')
|
|
break;
|
|
us2++;
|
|
} while (--n != 0);
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
static bool findFile(const char *path, const char *prefix) {
|
|
if (!isSdCardAlive()) {
|
|
efiPrintf("Error: No File system is mounted");
|
|
return false;
|
|
}
|
|
|
|
DIR dir;
|
|
FRESULT res = f_opendir(&dir, path);
|
|
|
|
if (res != FR_OK) {
|
|
efiPrintf("Error opening directory %s", path);
|
|
return false;
|
|
}
|
|
|
|
// todo: do we need paranoia loop limit?
|
|
while (true) {
|
|
FILINFO fno;
|
|
|
|
res = f_readdir(&dir, &fno);
|
|
if (res != FR_OK || fno.fname[0] == 0) {
|
|
// done!
|
|
break;
|
|
}
|
|
if (fno.fname[0] == '.') {
|
|
continue;
|
|
}
|
|
if ((fno.fattrib & AM_DIR) || mystrncasecmp(prefix, fno.fname, strlen(prefix) - 1)) {
|
|
// skipping folders and files with wrong names
|
|
continue;
|
|
}
|
|
efiPrintf("file found %lu:%s", (uint32_t)fno.fsize, fno.fname);
|
|
return true;
|
|
|
|
// efiPrintf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %-12s", (fno.fattrib & AM_DIR) ? 'D' : '-',
|
|
// (fno.fattrib & AM_RDO) ? 'R' : '-', (fno.fattrib & AM_HID) ? 'H' : '-',
|
|
// (fno.fattrib & AM_SYS) ? 'S' : '-', (fno.fattrib & AM_ARC) ? 'A' : '-', (fno.fdate >> 9) + 1980,
|
|
// (fno.fdate >> 5) & 15, fno.fdate & 31, (fno.ftime >> 11), (fno.ftime >> 5) & 63, fno.fsize,
|
|
// fno.fname);
|
|
}
|
|
return false;
|
|
}
|
|
#endif // EFI_BACKUP_SRAM
|
|
|
|
void writeErrorReportFile() {
|
|
#if EFI_BACKUP_SRAM
|
|
extern ErrorCookie errorCookieOnStart;
|
|
static char fileName[_MAX_FILLER + 20];
|
|
auto sramState = getBackupSram();
|
|
if (errorCookieOnStart == ErrorCookie::HardFault) {
|
|
memset(&FDLogFile, 0, sizeof(FIL)); // clear the memory
|
|
sprintf(fileName, "%s%d.txt", HARD_FAULT_PREFIX, logFileIndex);
|
|
FRESULT ret = f_open(&FDLogFile, fileName, FA_CREATE_ALWAYS | FA_WRITE);
|
|
if (ret == FR_OK) {
|
|
onBoardWriteErrorFile(&FDLogFile);
|
|
f_printf(&FDLogFile, "type=%d\n", sramState->Err.FaultType);
|
|
// todo: figure out what else would be useful
|
|
f_close(&FDLogFile);
|
|
}
|
|
}
|
|
findFile(".", HARD_FAULT_PREFIX);
|
|
#endif // EFI_BACKUP_SRAM
|
|
}
|
|
|
|
#endif // EFI_PROD_CODE && EFI_FILE_LOGGING
|