/*---------------------------------------------------------------------------*/ static int coffee_test_gc(void) { int i; cfs_remove("alpha"); cfs_remove("beta"); for (i = 0; i < 100; i++) { if (i & 1) { if(cfs_coffee_reserve("alpha", random_rand() & 0xffff) < 0) { return i; } cfs_remove("beta"); } else { if(cfs_coffee_reserve("beta", 93171) < 0) { return i; } cfs_remove("alpha"); } } return 0; }
static void serial_interrupt_checkpoint() { int fd = 0; PAUSE_TIME(); if(SPI_IS_ENABLED()) { /* SPI is busy, abort */ PRINTF_COMMAND("CP:SPIBUSY\n"); RESUME_TIME(); return; } /* Open file */ cfs_remove("cp"); cfs_coffee_reserve("cp", checkpoint_arch_size()); fd = cfs_open("cp", CFS_WRITE); if(fd < 0) { printf("ERROR: No file access (cp)\n"); RESUME_TIME(); return; } /* Checkpoint */ preset_cmd = COMMAND_CHECKPOINT; preset_fd = fd; mt_exec(&checkpoint_thread); /* Close file */ cfs_close(fd); RESUME_TIME(); }
void manage_acq_setup() { for (u8 prn=0; prn<32; prn++) { acq_prn_param[prn].state = ACQ_PRN_UNTRIED; acq_prn_param[prn].score = 0; } int fd = cfs_open("almanac", CFS_READ); if (fd != -1) { cfs_read(fd, almanac, 32*sizeof(almanac_t)); log_info("Loaded almanac from flash\n"); cfs_close(fd); } else { log_info("No almanac file present in flash, create an empty one\n"); cfs_coffee_reserve("almanac", 32*sizeof(almanac_t)); cfs_coffee_configure_log("almanac", 256, sizeof(almanac_t)); for (u8 prn=0; prn<32; prn++) { almanac[prn].valid = 0; } } sbp_register_cbk( MSG_ALMANAC, &almanac_callback, &almanac_callback_node ); chThdCreateStatic( wa_manage_acq_thread, sizeof(wa_manage_acq_thread), MANAGE_ACQ_THREAD_PRIORITY, manage_acq_thread, NULL ); }
void manage_acq_setup() { for (u8 prn=0; prn<32; prn++) { acq_prn_param[prn].state = ACQ_PRN_ACQUIRING; for (enum acq_hint hint = 0; hint < ACQ_HINT_NUM; hint++) acq_prn_param[prn].score[hint] = 0; acq_prn_param[prn].dopp_hint_low = ACQ_FULL_CF_MIN; acq_prn_param[prn].dopp_hint_high = ACQ_FULL_CF_MAX; } int fd = cfs_open("almanac", CFS_READ); if (fd != -1) { cfs_read(fd, almanac, 32*sizeof(almanac_t)); log_info("Loaded almanac from flash"); cfs_close(fd); } else { log_info("No almanac file present in flash, create an empty one"); cfs_coffee_reserve("almanac", 32*sizeof(almanac_t)); cfs_coffee_configure_log("almanac", 256, sizeof(almanac_t)); for (u8 prn=0; prn<32; prn++) { almanac[prn].valid = 0; } } sbp_register_cbk( SBP_MSG_ALMANAC, &almanac_callback, &almanac_callback_node ); sbp_register_cbk( SBP_MSG_MASK_SATELLITE, &mask_sat_callback, &mask_sat_callback_node ); chThdCreateStatic( wa_manage_acq_thread, sizeof(wa_manage_acq_thread), MANAGE_ACQ_THREAD_PRIORITY, manage_acq_thread, NULL ); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_checkpoint_process, ev, data) { int fd = 0; PROCESS_BEGIN(); /* Make sure file does not already exist */ cfs_remove(data); cfs_coffee_reserve(data, checkpoint_arch_size()); fd = cfs_open(data, CFS_WRITE); if(fd < 0) { shell_output_str(&checkpoint_command, "checkpoint: could not open file for writing: ", data); } else { shell_output_str(&rollback_command, "checkpoint to: ", data); checkpoint_checkpoint(fd); cfs_close(fd); } PROCESS_END(); }
char * storage_generate_file(char *prefix, unsigned long size) { static char filename[ATTRIBUTE_NAME_LENGTH + sizeof(".ffff")]; #if !DB_FEATURE_COFFEE int fd; #endif snprintf(filename, sizeof(filename), "%s.%x", prefix, (unsigned)(random_rand() & 0xffff)); #if DB_FEATURE_COFFEE PRINTF("DB: Reserving %lu bytes in %s\n", size, filename); if(cfs_coffee_reserve(filename, size) < 0) { PRINTF("DB: Failed to reserve\n"); return NULL; } return filename; #else fd = cfs_open(filename, CFS_WRITE); cfs_close(fd); return fd < 0 ? NULL : filename; #endif /* DB_FEATURE_COFFEE */ }
PROCESS_THREAD(checkpoint_serial_process, ev, data) { static int set_fd = -1; static int set_count = -1; PROCESS_BEGIN(); /* Note: 'cp', 'rb', and 'mt' commands are intercepted */ PROCESS_PAUSE(); uart1_set_input(serial_input_byte_intercept); /* Format Coffee? */ PRINTF("Formatting Coffee\n"); cfs_coffee_format(); PRINTF("Formatting Coffee... done!\n"); while(1) { PROCESS_WAIT_EVENT_UNTIL(ev == serial_line_event_message && data != NULL); if(strcmp("set", data) == 0) { /* TODO Handle set command */ /* Open file */ cfs_remove("cp"); cfs_coffee_reserve("cp", checkpoint_arch_size()); set_fd = cfs_open("cp", CFS_WRITE); set_count = 0; if(set_fd < 0) { printf("SET:FSBUSY\n"); } else { printf("SET:LINE\n"); } } else if(set_fd >= 0 && strcmp("set:done", data) == 0) { cfs_close(set_fd); set_fd = -1; if(set_count == 9862) { printf("SET:DONE\n"); } else { printf("SET:WRONGSIZE\n"); } } else if(set_fd >= 0) { /* We are ready for another line */ printf("SET:LINE\n"); /* Set command: parse hex data */ int len = strlen((char*)data); if(len > 16 || (len%2)!=0) { printf("WARN: bad set data: %s\n", (char*)data); } else { int i; for (i=0; i < len; i+=2) { uint8_t b = (hex_decode_char(((char*)data)[i]) << 4) + (hex_decode_char(((char*)data)[i+1])); PRINTF("Parsing set command: writing to CFS: %02x\n", b); write_byte(set_fd, b); /* TODO Check return value */ set_count++; } } } else if(strcmp("", data) == 0 || strcmp("cp", data) == 0 || strcmp("rb", data) == 0 || strcmp("mt", data) == 0) { /* ignore commands: handled by interrupt */ } else if(strcmp("ping", data) == 0) { nr_pongs++; printf("pong %u\n", nr_pongs); } else if(strcmp("get", data) == 0) { handle_get_command(); } else { printf("WARN: Unknown command: '%s'\n", (char*)data); } } PROCESS_END(); }
int coffee_file_test(void) { int error; int wfd, rfd, afd; unsigned char buf[256], buf2[11]; int r, i, j, total_read; unsigned offset; cfs_remove("T1"); cfs_remove("T2"); cfs_remove("T3"); cfs_remove("T4"); cfs_remove("T5"); wfd = rfd = afd = -1; for(r = 0; r < sizeof(buf); r++) { buf[r] = r; } PRINTF("TEST 1\n"); /* Test 1: Open for writing. */ wfd = cfs_open("T1", CFS_WRITE); if(wfd < 0) { FAIL(-1); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("2\n"); /* Test 2: Write buffer. */ r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { FAIL(-2); } else if(r < sizeof(buf)) { FAIL(-3); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("3\n"); /* Test 3: Deny reading. */ r = cfs_read(wfd, buf, sizeof(buf)); if(r >= 0) { FAIL(-4); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("4\n"); /* Test 4: Open for reading. */ rfd = cfs_open("T1", CFS_READ); if(rfd < 0) { FAIL(-5); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("5\n"); /* Test 5: Write to read-only file. */ r = cfs_write(rfd, buf, sizeof(buf)); if(r >= 0) { FAIL(-6); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("7\n"); /* Test 7: Read the buffer written in Test 2. */ memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { FAIL(-8); } else if(r < sizeof(buf)) { PRINTF_CFS("r=%d\n", r); FAIL(-9); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("8\n"); /* Test 8: Verify that the buffer is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != r) { PRINTF_CFS("r=%d. buf[r]=%d\n", r, buf[r]); FAIL(-10); } } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("9\n"); /* Test 9: Seek to beginning. */ if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { FAIL(-11); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("10\n"); /* Test 10: Write to the log. */ r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { FAIL(-12); } else if(r < sizeof(buf)) { FAIL(-13); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("11\n"); /* Test 11: Read the data from the log. */ cfs_seek(rfd, 0, CFS_SEEK_SET); memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { FAIL(-14); } else if(r < sizeof(buf)) { FAIL(-15); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("12\n"); /* Test 12: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != r) { FAIL(-16); } } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("13\n"); /* Test 13: Write a reversed buffer to the file. */ for(r = 0; r < sizeof(buf); r++) { buf[r] = sizeof(buf) - r - 1; } if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { FAIL(-17); } r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { FAIL(-18); } else if(r < sizeof(buf)) { FAIL(-19); } if(cfs_seek(rfd, 0, CFS_SEEK_SET) != 0) { FAIL(-20); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("14\n"); /* Test 14: Read the reversed buffer. */ cfs_seek(rfd, 0, CFS_SEEK_SET); memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { FAIL(-21); } else if(r < sizeof(buf)) { PRINTF_CFS("r = %d\n", r); FAIL(-22); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("15\n"); /* Test 15: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != sizeof(buf) - r - 1) { FAIL(-23); } } cfs_close(rfd); cfs_close(wfd); if(cfs_coffee_reserve("T2", FILE_SIZE) < 0) { FAIL(-24); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("16\n"); /* Test 16: Test multiple writes at random offset. */ for(r = 0; r < 100; r++) { wfd = cfs_open("T2", CFS_WRITE | CFS_READ); if(wfd < 0) { FAIL(-25); } offset = random_rand() % FILE_SIZE; for(r = 0; r < sizeof(buf); r++) { buf[r] = r; } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { FAIL(-26); } if(cfs_write(wfd, buf, sizeof(buf)) != sizeof(buf)) { FAIL(-27); } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { FAIL(-28); } memset(buf, 0, sizeof(buf)); if(cfs_read(wfd, buf, sizeof(buf)) != sizeof(buf)) { FAIL(-29); } for(i = 0; i < sizeof(buf); i++) { if(buf[i] != i) { PRINTF_CFS("buf[%d] != %d\n", i, buf[i]); FAIL(-30); } } } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("17\n"); /* Test 17: Append data to the same file many times. */ #define APPEND_BYTES 3000 #define BULK_SIZE 10 for (i = 0; i < APPEND_BYTES; i += BULK_SIZE) { afd = cfs_open("T3", CFS_WRITE | CFS_APPEND); if (afd < 0) { FAIL(-31); } for (j = 0; j < BULK_SIZE; j++) { buf[j] = 1 + ((i + j) & 0x7f); } if ((r = cfs_write(afd, buf, BULK_SIZE)) != BULK_SIZE) { PRINTF_CFS("Count:%d, r=%d\n", i, r); FAIL(-32); } cfs_close(afd); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("18\n"); /* Test 18: Read back the data written in Test 17 and verify that it is correct. */ afd = cfs_open("T3", CFS_READ); if(afd < 0) { FAIL(-33); } total_read = 0; while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { for(j = 0; j < r; j++) { if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { FAIL(-34); } } total_read += r; } if(r < 0) { PRINTF_CFS("FAIL:-35 r=%d\n",r); FAIL(-35); } if(total_read != APPEND_BYTES) { PRINTF_CFS("FAIL:-35 total_read=%d\n",total_read); FAIL(-35); } cfs_close(afd); PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("19\n"); /***************T4********************/ /* file T4 and T5 writing forces to use garbage collector in greedy mode * this test is designed for 10kb of file system * */ #define APPEND_BYTES_1 2000 #define BULK_SIZE_1 10 for (i = 0; i < APPEND_BYTES_1; i += BULK_SIZE_1) { afd = cfs_open("T4", CFS_WRITE | CFS_APPEND); if (afd < 0) { FAIL(-36); } for (j = 0; j < BULK_SIZE_1; j++) { buf[j] = 1 + ((i + j) & 0x7f); } if ((r = cfs_write(afd, buf, BULK_SIZE_1)) != BULK_SIZE_1) { PRINTF_CFS("Count:%d, r=%d\n", i, r); FAIL(-37); } cfs_close(afd); } afd = cfs_open("T4", CFS_READ); if(afd < 0) { FAIL(-38); } total_read = 0; while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { for(j = 0; j < r; j++) { if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { PRINTF_CFS("FAIL:-39, total_read=%d r=%d\n",total_read,r); FAIL(-39); } } total_read += r; } if(r < 0) { PRINTF_CFS("FAIL:-40 r=%d\n",r); FAIL(-40); } if(total_read != APPEND_BYTES_1) { PRINTF_CFS("FAIL:-41 total_read=%d\n",total_read); FAIL(-41); } cfs_close(afd); /***************T5********************/ PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("20\n"); #define APPEND_BYTES_2 1000 #define BULK_SIZE_2 10 for (i = 0; i < APPEND_BYTES_2; i += BULK_SIZE_2) { afd = cfs_open("T5", CFS_WRITE | CFS_APPEND); if (afd < 0) { FAIL(-42); } for (j = 0; j < BULK_SIZE_2; j++) { buf[j] = 1 + ((i + j) & 0x7f); } if ((r = cfs_write(afd, buf, BULK_SIZE_2)) != BULK_SIZE_2) { PRINTF_CFS("Count:%d, r=%d\n", i, r); FAIL(-43); } cfs_close(afd); } afd = cfs_open("T5", CFS_READ); if(afd < 0) { FAIL(-44); } total_read = 0; while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { for(j = 0; j < r; j++) { if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { PRINTF_CFS("FAIL:-45, total_read=%d r=%d\n",total_read,r); FAIL(-45); } } total_read += r; } if(r < 0) { PRINTF_CFS("FAIL:-46 r=%d\n",r); FAIL(-46); } if(total_read != APPEND_BYTES_2) { PRINTF_CFS("FAIL:-47 total_read=%d\n",total_read); FAIL(-47); } cfs_close(afd); PRINTF("PASSED\n"); error = 0; end: cfs_close(wfd); cfs_close(rfd); cfs_close(afd); return error; }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(coffee_test_process, ev, data) { int fd_write, n, i; static int cnt = 0; uint8_t buffer[FILE_SIZE]; clock_time_t now; unsigned short now_fine; static uint32_t time_start, time_stop; printf("###########################################################\n"); PROCESS_BEGIN(); printf("process running\n"); // wait for 5 sec etimer_set(&et, CLOCK_SECOND * 5); PROCESS_YIELD_UNTIL(etimer_expired(&et)); #if (COFFEE_DEVICE == 6) int initialized = 0, i; SDCARD_POWER_ON(); //--- Detecting devices and partitions TEST_EQUALS(diskio_detect_devices(), DISKIO_SUCCESS); info = diskio_devices(); for (i = 0; i < DISKIO_MAX_DEVICES; i++) { if ((info + i)->type == (DISKIO_DEVICE_TYPE_SD_CARD | DISKIO_DEVICE_TYPE_PARTITION)) { info += i; initialized = 1; break; } } TEST_EQUALS(initialized, 1); diskio_set_default_device(info); #endif printf("fomartting...\n"); TEST_EQUALS(cfs_coffee_format(), 0); //printf("test starting\n"); do { now_fine = clock_time(); now = clock_seconds(); } while (now_fine != clock_time()); time_start = ((unsigned long)now)*CLOCK_SECOND + now_fine%CLOCK_SECOND; while(1) { // Shortest possible pause PROCESS_PAUSE(); // Determine the filename char b_file[8]; sprintf(b_file,"%u.b", cnt); // Set the file size printf("Reserving '%s'...\n", b_file); TEST_EQUALS(cfs_coffee_reserve(b_file, FILE_SIZE), 0); // And open it printf("Opening '%s'...\n", b_file); fd_write = cfs_open(b_file, CFS_WRITE); TEST_NEQ(fd_write, -1); // fill buffer for(i=0; i<FILE_SIZE; i++) { buffer[i] = cnt % 0xFF; } // Open was successful, write has to be successful too since the size has been reserved printf("Writing'%s'...\n", b_file); n = cfs_write(fd_write, buffer, FILE_SIZE); cfs_close(fd_write); TEST_EQUALS(n, FILE_SIZE); printf("%s written\n", b_file); if( cnt >= FILES_IN_STORAGE ) { int fd_read; // Figure out the filename char r_file[8]; sprintf(r_file,"%u.b", cnt - FILES_IN_STORAGE); // Open the bundle file printf("Reopening '%s'...\n", r_file); fd_read = cfs_open(r_file, CFS_READ); if(fd_read == -1) { // Could not open file printf("############# STORAGE: could not open file %s\n", r_file); fail(); } memset(buffer, 0, FILE_SIZE); // And now read the bundle back from flash printf("Reading '%s'...\n", b_file); if (cfs_read(fd_read, buffer, FILE_SIZE) == -1){ printf("############# STORAGE: cfs_read error\n"); cfs_close(fd_read); fail(); } cfs_close(fd_read); for(i=0; i<FILE_SIZE; i++) { if( buffer[i] != (cnt - FILES_IN_STORAGE) % 0xFF ) { printf("############# STORAGE: verify error\n"); fail(); } } if( cfs_remove(r_file) == -1 ) { printf("############# STORAGE: unable to remove %s\n", r_file); fail(); } printf("%s deleted\n", r_file); } cnt ++; if( cnt >= 10 ) { do { now_fine = clock_time(); now = clock_seconds(); } while (now_fine != clock_time()); time_stop = ((unsigned long)now)*CLOCK_SECOND + now_fine%CLOCK_SECOND; TEST_REPORT("data written", FILE_SIZE*cnt*CLOCK_SECOND, time_stop-time_start, "bytes/s"); TEST_PASS(); watchdog_stop(); while(1); } } PROCESS_END(); }
db_result_t storage_put_relation(relation_t *rel) { int fd; int r; char *str; unsigned char *last_byte; PRINTF("DB: put_relation(%s)\n", rel->name); cfs_remove(rel->name); #if DB_FEATURE_COFFEE cfs_coffee_reserve(rel->name, DB_COFFEE_CATALOG_SIZE); #endif fd = cfs_open(rel->name, CFS_WRITE | CFS_READ); if(fd < 0) { return DB_STORAGE_ERROR; } r = cfs_write(fd, rel->name, sizeof(rel->name)); if(r != sizeof(rel->name)) { cfs_close(fd); cfs_remove(rel->name); return DB_STORAGE_ERROR; } if(rel->tuple_filename[0] == '\0') { str = storage_generate_file("tuple", DB_COFFEE_RESERVE_SIZE); if(str == NULL) { cfs_close(fd); cfs_remove(rel->name); return DB_STORAGE_ERROR; } strncpy(rel->tuple_filename, str, sizeof(rel->tuple_filename) - 1); rel->tuple_filename[sizeof(rel->tuple_filename) - 1] = '\0'; } /* * Encode the last byte to ensure that the filename is not * null-terminated. This will make the Coffee FS determine * the correct length when re-opening the file. */ last_byte = (unsigned char *)&rel->tuple_filename[sizeof(rel->tuple_filename) - 1]; *last_byte ^= ROW_XOR; r = cfs_write(fd, rel->tuple_filename, sizeof(rel->tuple_filename)); *last_byte ^= ROW_XOR; if(r != sizeof(rel->tuple_filename)) { cfs_close(fd); cfs_remove(rel->tuple_filename); return DB_STORAGE_ERROR; } PRINTF("DB: Saved relation %s\n", rel->name); cfs_close(fd); return DB_OK; }
/*---------------------------------------------------------------------------*/ static int coffee_test_modify(void) { int error; int wfd; unsigned char buf[256]; int r, i; unsigned offset; cfs_remove("T3"); wfd = -1; if(cfs_coffee_reserve("T3", FILE_SIZE) < 0) { FAIL(1); } if(cfs_coffee_configure_log("T3", FILE_SIZE / 2, 11) < 0) { FAIL(2); } /* Test 16: Test multiple writes at random offset. */ for(r = 0; r < 100; r++) { wfd = cfs_open("T2", CFS_WRITE | CFS_READ); if(wfd < 0) { FAIL(3); } offset = random_rand() % FILE_SIZE; for(r = 0; r < sizeof(buf); r++) { buf[r] = r; } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { FAIL(4); } if(cfs_write(wfd, buf, sizeof(buf)) != sizeof(buf)) { FAIL(5); } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { FAIL(6); } memset(buf, 0, sizeof(buf)); if(cfs_read(wfd, buf, sizeof(buf)) != sizeof(buf)) { FAIL(7); } for(i = 0; i < sizeof(buf); i++) { if(buf[i] != i) { printf("buf[%d] != %d\n", i, buf[i]); FAIL(8); } } } error = 0; end: cfs_close(wfd); return error; }