void initSubsystems(int argc, const char *argv[]) { initFilesystem(argc, argv); initScripting(); init_c_interface(); initConfiguration(argc, argv); initGame(); initVideo(); initAudio(); initInput(); }
int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "Missing argument for sdcard image filename\n"); return EXIT_FAILURE; } if (!sdcard_sim_init(argv[1])) { fprintf(stderr, "sdcard_sim_init() failed\n"); return EXIT_FAILURE; } initFilesystem(); bool keepGoing = true; while (keepGoing) { afatfs_poll(); switch (afatfs_getFilesystemState()) { case AFATFS_FILESYSTEM_STATE_READY: if (!continueTesting()) { keepGoing = false; break; } break; case AFATFS_FILESYSTEM_STATE_FATAL: fprintf(stderr, "[Fail] Fatal filesystem error\n"); exit(-1); default: ; } } while (!afatfs_destroy(false)) { } sdcard_sim_destroy(); return EXIT_SUCCESS; }
/** * Continue testing for data retention over powerloss. * * start - For the first call of the test, set start to true * * Returns true if the test is still continuing, or false if the test was completed successfully. */ bool continueFilesizeTest(bool start, const char *filename, const char *fileMode, uint32_t logEntriesToWrite) { static uint32_t logEntryIndex = 0; uint32_t bytesToWrite = logEntriesToWrite * TEST_LOG_ENTRY_SIZE; uint32_t logFileSize; uint32_t position; if (start) { powerlossStage = POWERLOSS_TEST_STAGE_OPEN; } switch (powerlossStage) { case POWERLOSS_TEST_STAGE_OPEN: powerlossStage = POWERLOSS_TEST_STAGE_IDLE; logEntryIndex = 0; afatfs_fopen(filename, fileMode, powerlossTestFileCreatedForAppend); break; case POWERLOSS_TEST_STAGE_APPEND: // Write just more than one sector of log entries if (writeLogTestEntries(powerlossFile, &logEntryIndex, logEntriesToWrite)) { testAssert(afatfs_feof(powerlossFile), "feof() should be true after extending file with write"); testAssert(afatfs_ftell(powerlossFile, &logFileSize), "ftell() expected to work when no file operation queued"); testAssert(logFileSize == bytesToWrite, "Log file correct after writes within a cluster"); testAssert(afatfs_fseek(powerlossFile, 0, AFATFS_SEEK_END) == AFATFS_OPERATION_SUCCESS, "Seeks to end of file when we're already at end should be immediate"); testAssert(afatfs_ftell(powerlossFile, &logFileSize), "ftell() should work after immediate seek"); testAssert(logFileSize == bytesToWrite, "fseek() seeked to the wrong position for AFATFS_SEEK_END"); powerlossStage = POWERLOSS_TEST_STAGE_FLUSH; } break; case POWERLOSS_TEST_STAGE_FLUSH: // Wait for all the flushable data (i.e. completed sectors) to make it to the disk if (afatfs_flush() && sdcard_sim_isReady()) { // Simulate a power interruption by restarting the filesystem afatfs_destroy(true); powerlossFile = NULL; initFilesystem(); powerlossStage = POWERLOSS_TEST_STAGE_READ_OPEN; } break; case POWERLOSS_TEST_STAGE_READ_OPEN: powerlossStage = POWERLOSS_TEST_STAGE_IDLE; logEntryIndex = 0; afatfs_fopen(filename, "r", powerlossTestFileOpenedForRead); break; case POWERLOSS_TEST_STAGE_READ_SEEK_TO_END: testAssert(afatfs_fseek(powerlossFile, 0, AFATFS_SEEK_END) != AFATFS_OPERATION_FAILURE, "Seek to end should work"); powerlossStage = POWERLOSS_TEST_STAGE_READ_MEASURE_FILE_LENGTH; break; case POWERLOSS_TEST_STAGE_READ_MEASURE_FILE_LENGTH: // We must wait for the the seek to complete before ftell() will succeed if (afatfs_ftell(powerlossFile, &position) == AFATFS_OPERATION_SUCCESS) { // We expect all of the sectors we completely wrote to have made it to the card testAssert(position >= (bytesToWrite / SDCARD_SECTOR_SIZE) * SDCARD_SECTOR_SIZE, "Filesize after power interruption was smaller than expected"); testAssert(afatfs_fseek(powerlossFile, 0, AFATFS_SEEK_SET) == AFATFS_OPERATION_SUCCESS, "Should be able to seek to begininng of file instantly"); powerlossStage = POWERLOSS_TEST_STAGE_READ_VALIDATE; } break; case POWERLOSS_TEST_STAGE_READ_VALIDATE: // The sectors we completely filled should be readable if (validateLogTestEntries(powerlossFile, &logEntryIndex, (bytesToWrite / SDCARD_SECTOR_SIZE) * TEST_LOG_ENTRIES_PER_SECTOR)) { powerlossStage = POWERLOSS_TEST_STAGE_READ_CLOSE; } break; case POWERLOSS_TEST_STAGE_READ_CLOSE: if (afatfs_fclose(powerlossFile, NULL)) { return false; // Test is over now! } break; case POWERLOSS_TEST_STAGE_IDLE: // Waiting for callbacks break; } return true; // Still continuing test }