add fs entry replace/cache functions
This commit is contained in:
parent
7bb38a7f12
commit
c7b26fb270
|
@ -58,7 +58,7 @@ int flash_erase(uint8_t page, uint8_t page_count);
|
|||
* Copies `size` words from `src` to `dst`. Since this function is only called using constant values and previously checked values, the input parameters are not validated. The addresses must be aligned according
|
||||
* to the rules specified in the ST DM00083560 document.
|
||||
*/
|
||||
int flash_copy(uint32_t* src, __IO uint32_t* dst, uint32_t size);
|
||||
int flash_copy(const uint32_t* src, __IO uint32_t* dst, uint32_t size);
|
||||
|
||||
/**
|
||||
* Locks the flash again, preventing writing.
|
||||
|
|
12
Inc/fs.h
12
Inc/fs.h
|
@ -105,4 +105,16 @@ uint32_t* fs_swap_get_free();
|
|||
*/
|
||||
uint32_t* fs_cache_get_free(uint32_t cache_start, int page_count, int entry_size);
|
||||
|
||||
/**
|
||||
* Finds the first free entry and writes the new value. If all pages are full, they are all erased and the new value is written at the beginning
|
||||
* of the first page.
|
||||
*/
|
||||
int fs_replace_entry(uint32_t page_num, int page_count, int entry_size, const uint32_t *entry);
|
||||
|
||||
/**
|
||||
* Similar to fs_replace_entry but applicable to caches. In case the cache is full, only the oldest page is erased and the new entry is placed at
|
||||
* the beginning of the erased page.
|
||||
*/
|
||||
int fs_cache_entry(uint32_t cache_start, int page_count, int entry_size, const uint32_t *entry);
|
||||
|
||||
#endif /* FS_H_ */
|
||||
|
|
|
@ -73,7 +73,7 @@ int flash_erase(uint8_t page, uint8_t page_count) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int flash_copy(uint32_t *src, __IO uint32_t *dst, uint32_t size) {
|
||||
int flash_copy(const uint32_t *src, __IO uint32_t *dst, uint32_t size) {
|
||||
_flash_wait();
|
||||
_flash_clear_errors();
|
||||
int ret = 0;
|
||||
|
|
65
Src/fs.c
65
Src/fs.c
|
@ -195,10 +195,10 @@ uint32_t* _fs_find_free_entry(uint32_t* page, int entry_size) {
|
|||
|
||||
uint32_t* fs_find_free_entry(uint32_t page_num, int page_count, int entry_size) {
|
||||
for (int i = 0; i < page_count; i++) {
|
||||
uint32_t* page = _fs_find_free_entry(FS_PAGE_IDX_ADDR(page_num, i), entry_size);
|
||||
uint32_t* free = _fs_find_free_entry(FS_PAGE_IDX_ADDR(page_num, i), entry_size);
|
||||
|
||||
if (page) {
|
||||
return page;
|
||||
if (free) {
|
||||
return free;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,11 +277,13 @@ uint32_t * _fs_cache_free_oldest(uint32_t cache_start, int page_count) {
|
|||
if (flash_erase(FS_ABS_IDX_PAGE(cache_start, page_idx), 1) || flash_copy(header, addr, 2)) {
|
||||
addr = NULL;
|
||||
goto ret;
|
||||
} else {
|
||||
addr = &addr[2];
|
||||
}
|
||||
|
||||
ret:
|
||||
flash_lock();
|
||||
return &addr[2];
|
||||
return addr;
|
||||
}
|
||||
|
||||
uint32_t* fs_cache_get_free(uint32_t cache_start, int page_count, int entry_size) {
|
||||
|
@ -293,3 +295,58 @@ uint32_t* fs_cache_get_free(uint32_t cache_start, int page_count, int entry_size
|
|||
|
||||
return free_addr;
|
||||
}
|
||||
|
||||
int _fs_write_entry(uint32_t* addr, const uint32_t* entry, int entry_size) {
|
||||
int res = 0;
|
||||
|
||||
if(flash_unlock() || flash_copy(entry, addr, entry_size)) res = -1;
|
||||
|
||||
flash_lock();
|
||||
return res;
|
||||
}
|
||||
|
||||
int _fs_rewrite_entry(uint32_t page_num, int page_count, int entry_size, const uint32_t *entry) {
|
||||
uint32_t *free = fs_swap_get_free();
|
||||
if (!free) return -1;
|
||||
|
||||
int res = -1;
|
||||
|
||||
if (flash_unlock()) goto ret;
|
||||
|
||||
uint32_t header[2];
|
||||
uint32_t* page = FS_PAGE_IDX_ADDR(page_num, 0);
|
||||
FS_HEADER(header, page[0], (page[1] + 1));
|
||||
|
||||
if (flash_copy(entry, &free[2], entry_size)) goto ret;
|
||||
if (flash_copy(header, free, 2)) goto ret;
|
||||
|
||||
for (int i = 1; i < page_count; i++) {
|
||||
free = fs_swap_get_free();
|
||||
if (!free) goto ret;
|
||||
page = FS_PAGE_IDX_ADDR(page_num, i);
|
||||
FS_HEADER(header, page[0], (page[1] + 1));
|
||||
if (flash_copy(header, free, 2)) goto ret;
|
||||
}
|
||||
|
||||
res = 0;
|
||||
|
||||
ret:
|
||||
flash_lock();
|
||||
return res;
|
||||
}
|
||||
|
||||
int fs_replace_entry(uint32_t page_num, int page_count, int entry_size, const uint32_t *entry) {
|
||||
uint32_t* free = fs_find_free_entry(page_num, page_count, entry_size);
|
||||
|
||||
if (free) {
|
||||
return _fs_write_entry(free, entry, entry_size);
|
||||
} else {
|
||||
return _fs_rewrite_entry(page_num, page_count, entry_size, entry) || fs_commit();
|
||||
}
|
||||
}
|
||||
|
||||
int fs_cache_entry(uint32_t cache_start, int page_count, int entry_size, const uint32_t *entry) {
|
||||
uint32_t* free = fs_cache_get_free(cache_start, page_count, entry_size);
|
||||
if (!free) return -1;
|
||||
return _fs_write_entry(free, entry, entry_size);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ int flash_erase(uint8_t page, uint8_t page_count) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int flash_copy(uint32_t* src, __IO uint32_t* dst, uint32_t size) {
|
||||
int flash_copy(const uint32_t* src, __IO uint32_t* dst, uint32_t size) {
|
||||
TEST_CHECK(!(flash_locked || (((uintptr_t) dst) % 4) || (size % 2)));
|
||||
|
||||
for(int i = 0; i < size; i += 2) {
|
||||
|
@ -250,6 +250,80 @@ void test_fs_cache_get_free(void) {
|
|||
TEST_CHECK(page[1] == (FS_KEY_CACHE_COUNT + 1));
|
||||
}
|
||||
|
||||
void test_fs_replace_entry(void) {
|
||||
TEST_CHECK(!fs_init());
|
||||
|
||||
uint32_t entry[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0X10 };
|
||||
uint32_t* page = FS_PAGE_IDX_ADDR(FS_COUNTERS_PAGE, 0);
|
||||
|
||||
TEST_CHECK(!fs_replace_entry(FS_COUNTERS_PAGE, FS_COUNTERS_PAGE, 4, entry));
|
||||
TEST_CHECK(!memcmp(entry, &page[2], 16));
|
||||
|
||||
for (int i = 0; i < FS_KEY_CACHE_COUNT; i++) {
|
||||
page = FS_PAGE_IDX_ADDR(FS_COUNTERS_PAGE, i);
|
||||
|
||||
for (int j = 2; j < FLASH_PAGE_SIZE/4; j++) {
|
||||
page[j] = 0xeeeeeeee;
|
||||
}
|
||||
}
|
||||
|
||||
page = FS_PAGE_IDX_ADDR(FS_COUNTERS_PAGE, 0);
|
||||
|
||||
TEST_CHECK(!fs_replace_entry(FS_COUNTERS_PAGE, FS_COUNTERS_PAGE, 4, entry));
|
||||
TEST_CHECK(!memcmp(entry, &page[2], 16));
|
||||
TEST_CHECK(page[0] == FS_V1_PAGE_ID(FS_COUNTERS_ID, 0));
|
||||
TEST_CHECK(page[1] == 1);
|
||||
|
||||
for (int j = 6; j < FLASH_PAGE_SIZE/4; j++) {
|
||||
TEST_CHECK(page[j] == 0xffffffff);
|
||||
}
|
||||
|
||||
for (int i = 1; i < FS_COUNTERS_PAGE; i++) {
|
||||
page = FS_PAGE_IDX_ADDR(FS_COUNTERS_PAGE, i);
|
||||
TEST_CHECK(page[0] == FS_V1_PAGE_ID(FS_COUNTERS_ID, i));
|
||||
TEST_CHECK(page[1] == 1);
|
||||
|
||||
for (int j = 2; j < FLASH_PAGE_SIZE/4; j++) {
|
||||
TEST_CHECK(page[j] == 0xffffffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_fs_cache_entry(void) {
|
||||
TEST_CHECK(!fs_init());
|
||||
|
||||
uint32_t entry[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0X10 };
|
||||
uint32_t* page = FS_PAGE_IDX_ADDR(FS_KEY_CACHE_PAGE, 0);
|
||||
|
||||
TEST_CHECK(!fs_cache_entry(FS_KEY_CACHE_PAGE, FS_KEY_CACHE_COUNT, 4, entry));
|
||||
TEST_CHECK(!memcmp(entry, &page[2], 16));
|
||||
|
||||
for (int i = 0; i < FS_KEY_CACHE_COUNT; i++) {
|
||||
page = FS_PAGE_IDX_ADDR(FS_KEY_CACHE_PAGE, i);
|
||||
|
||||
for (int j = 2; j < FLASH_PAGE_SIZE/4; j++) {
|
||||
page[j] = 0xeeeeeeee;
|
||||
}
|
||||
}
|
||||
|
||||
page = FS_PAGE_IDX_ADDR(FS_KEY_CACHE_PAGE, 0);
|
||||
|
||||
TEST_CHECK(!fs_cache_entry(FS_KEY_CACHE_PAGE, FS_KEY_CACHE_COUNT, 4, entry));
|
||||
TEST_CHECK(!memcmp(entry, &page[2], 16));
|
||||
|
||||
for (int j = 6; j < FLASH_PAGE_SIZE/4; j++) {
|
||||
TEST_CHECK(page[j] == 0xffffffff);
|
||||
}
|
||||
|
||||
for (int i = 1; i < FS_KEY_CACHE_COUNT; i++) {
|
||||
page = FS_PAGE_IDX_ADDR(FS_KEY_CACHE_PAGE, i);
|
||||
|
||||
for (int j = 2; j < FLASH_PAGE_SIZE/4; j++) {
|
||||
TEST_CHECK(page[j] == 0xeeeeeeee);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_LIST = {
|
||||
{ "fs_init", test_fs_init },
|
||||
{ "fs_commit", test_fs_commit },
|
||||
|
@ -257,5 +331,7 @@ TEST_LIST = {
|
|||
{ "fs_find_last_entry", test_fs_find_last_entry },
|
||||
{ "fs_swap_get_free", test_fs_swap_get_free },
|
||||
{ "fs_cache_get_free", test_fs_cache_get_free },
|
||||
{ "fs_replace_entry", test_fs_replace_entry },
|
||||
{ "fs_cache_entry", test_fs_cache_entry },
|
||||
{ 0 }
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue