/* * Copyright © 2014 Kosma Moczek * This program is free software. It comes without any warranty, to the extent * permitted by applicable law. You can redistribute it and/or modify it under * the terms of the Do What The Fuck You Want To Public License, Version 2, as * published by Sam Hocevar. See the COPYING file for more details. */ #include #include "lib_ringfs.h" #include "lib_ringfs_func.h" #include "lib_ringfs_ram.h" #include "lib_ringfs_w25q.h" #include "func_spi_w25qxx.h" #include "obj_hal_w25qxx.h" #include "obj_soft_w25qxx.h" /* Flash implementation & ops. */ /* Data record format. */ struct log_entry { int level; char message[16]; }; #define LOG_ENTRY_VERSION 1 struct ringfs rfs_obj; int lib_ringfs_push(void *object, size_t size) { if(ringfs_append(&rfs_obj, object) == 0) { ringfs_end(&rfs_obj); return size; } return 0; } int lib_ringfs_pop(void *object, size_t size) { if(ringfs_del(&rfs_obj, (void *)object) == 0) { return size; } return 0; } uint32_t lib_ringfs_obj_cnt_estimate(void) { return (uint32_t)ringfs_count_estimate(&rfs_obj); } uint32_t lib_ringfs_obj_cnt_exact(void) { return (uint32_t)ringfs_count_exact(&rfs_obj); } /* Let's roll! */ int lib_ringfs_init(int object_size) { /* Initialize your Flash driver before using the filesystem. */ #if USE_LIB_RINGFS_RAM==1 init_flash_driver_ram(); /* Always call ringfs_init first. */ ringfs_init(&rfs_obj, &rfs_disk_ram, LOG_ENTRY_VERSION, object_size); #elif USE_LIB_RINGFS_W25Q==1 init_flash_driver_w25q(); /* Always call ringfs_init first. */ ringfs_init(&rfs_obj, &rfs_disk_w25q, LOG_ENTRY_VERSION, object_size); #endif /* Scan and/or format before any data operations. */ printf("# scanning for filesystem...\n"); if (ringfs_scan(&rfs_obj) == 0) { printf("# found existing filesystem, usage: %d/%d\n", ringfs_count_estimate(&rfs_obj), ringfs_capacity(&rfs_obj)); } else { printf("# no valid filesystem found, formatting.\n"); ringfs_format(&rfs_obj); } //把光标位置移动到写入位置; ringfs_end(&rfs_obj); return 0; } int lib_ringfs_log_test(void) { static uint32_t obj_idx = 0; int obj_cnt = ringfs_count_exact(&rfs_obj); printf("\n\n\n# ringfs has %d objects\n", obj_cnt); /* Append data using ringfs_append. Oldest data is removed as needed. */ printf("# inserting some objects\n"); ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "foo" }); ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "bar" }); ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "baz" }); ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "xyzzy" }); ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "test" }); ringfs_append(&rfs_obj, &(struct log_entry) { obj_idx++, "hello" }); /* Objects are retrieved using ringfs_fetch. They are not physically removed * until you call ringfs_discard. This is useful, for example, when transmitting * queued objects over the network: you don't physically remove the objects * from the ring buffer until you receive an ACK. */ printf("# reading 2 objects\n"); for (int i=0; i<2; i++) { struct log_entry entry; RFS_ASSERT(ringfs_fetch(&rfs_obj, &entry) == 0); printf("## level=%d message=%.16s\n", entry.level, entry.message); } if(0) { printf("# discarding read objects\n"); ringfs_discard(&rfs_obj); } printf("# rewinding read head back\n"); ringfs_rewind(&rfs_obj); /* If you decide you can't remove the objects yet, just call ringfs_rewind() and * they will be available again for subsequent reads. */ printf("# reading 2 objects\n"); for (int i=0; i<2; i++) { struct log_entry entry; if(ringfs_fetch(&rfs_obj, &entry) == 0) { printf("## level=%d message=%.16s\n", entry.level, entry.message); } } printf("# popping 2 objects\n"); for (int i=0; i<2; i++) { struct log_entry entry; RFS_ASSERT(ringfs_pop(&rfs_obj, &entry) == 0); printf("## level=%d message=%.16s\n", entry.level, entry.message); } /* ...and here they are again. */ printf("# reading 2 objects\n"); for (int i=0; i<2; i++) { struct log_entry entry; if(ringfs_fetch(&rfs_obj, &entry) == 0) { printf("## level=%d message=%.16s\n", entry.level, entry.message); } } return 0; } void lib_ringfs_test(void const *argument) { //UNUSED(argument); lib_ringfs_init(sizeof(struct log_entry)); while(1) { lib_ringfs_log_test(); }; //return 0; } /* vim: set ts=4 sw=4 et: */