Lines Matching full:fs

12 #include <fs/nvs.h>
20 /* nvs_al_size returns size aligned to fs->write_block_size */
21 static inline size_t nvs_al_size(struct nvs_fs *fs, size_t len) in nvs_al_size() argument
23 uint8_t write_block_size = fs->flash_parameters->write_block_size; in nvs_al_size()
34 static int nvs_flash_al_wrt(struct nvs_fs *fs, uint32_t addr, const void *data, in nvs_flash_al_wrt() argument
48 offset = fs->offset; in nvs_flash_al_wrt()
49 offset += fs->sector_size * (addr >> ADDR_SECT_SHIFT); in nvs_flash_al_wrt()
52 blen = len & ~(fs->flash_parameters->write_block_size - 1U); in nvs_flash_al_wrt()
54 rc = flash_write(fs->flash_device, offset, data8, blen); in nvs_flash_al_wrt()
65 (void)memset(buf + len, fs->flash_parameters->erase_value, in nvs_flash_al_wrt()
66 fs->flash_parameters->write_block_size - len); in nvs_flash_al_wrt()
68 rc = flash_write(fs->flash_device, offset, buf, in nvs_flash_al_wrt()
69 fs->flash_parameters->write_block_size); in nvs_flash_al_wrt()
77 static int nvs_flash_rd(struct nvs_fs *fs, uint32_t addr, void *data, in nvs_flash_rd() argument
83 offset = fs->offset; in nvs_flash_rd()
84 offset += fs->sector_size * (addr >> ADDR_SECT_SHIFT); in nvs_flash_rd()
87 rc = flash_read(fs->flash_device, offset, data, len); in nvs_flash_rd()
93 static int nvs_flash_ate_wrt(struct nvs_fs *fs, const struct nvs_ate *entry) in nvs_flash_ate_wrt() argument
97 rc = nvs_flash_al_wrt(fs, fs->ate_wra, entry, in nvs_flash_ate_wrt()
99 fs->ate_wra -= nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_flash_ate_wrt()
105 static int nvs_flash_data_wrt(struct nvs_fs *fs, const void *data, size_t len) in nvs_flash_data_wrt() argument
109 rc = nvs_flash_al_wrt(fs, fs->data_wra, data, len); in nvs_flash_data_wrt()
110 fs->data_wra += nvs_al_size(fs, len); in nvs_flash_data_wrt()
116 static int nvs_flash_ate_rd(struct nvs_fs *fs, uint32_t addr, in nvs_flash_ate_rd() argument
119 return nvs_flash_rd(fs, addr, entry, sizeof(struct nvs_ate)); in nvs_flash_ate_rd()
127 * in blocks of size NVS_BLOCK_SIZE aligned to fs->write_block_size
130 static int nvs_flash_block_cmp(struct nvs_fs *fs, uint32_t addr, const void *data, in nvs_flash_block_cmp() argument
139 NVS_BLOCK_SIZE & ~(fs->flash_parameters->write_block_size - 1U); in nvs_flash_block_cmp()
143 rc = nvs_flash_rd(fs, addr, buf, bytes_to_cmp); in nvs_flash_block_cmp()
162 static int nvs_flash_cmp_const(struct nvs_fs *fs, uint32_t addr, uint8_t value, in nvs_flash_cmp_const() argument
170 NVS_BLOCK_SIZE & ~(fs->flash_parameters->write_block_size - 1U); in nvs_flash_cmp_const()
175 rc = nvs_flash_block_cmp(fs, addr, cmp, bytes_to_cmp); in nvs_flash_cmp_const()
188 static int nvs_flash_block_move(struct nvs_fs *fs, uint32_t addr, size_t len) in nvs_flash_block_move() argument
195 NVS_BLOCK_SIZE & ~(fs->flash_parameters->write_block_size - 1U); in nvs_flash_block_move()
199 rc = nvs_flash_rd(fs, addr, buf, bytes_to_copy); in nvs_flash_block_move()
203 rc = nvs_flash_data_wrt(fs, buf, bytes_to_copy); in nvs_flash_block_move()
216 static int nvs_flash_erase_sector(struct nvs_fs *fs, uint32_t addr) in nvs_flash_erase_sector() argument
223 offset = fs->offset; in nvs_flash_erase_sector()
224 offset += fs->sector_size * (addr >> ADDR_SECT_SHIFT); in nvs_flash_erase_sector()
227 fs->sector_size); in nvs_flash_erase_sector()
228 rc = flash_erase(fs->flash_device, offset, fs->sector_size); in nvs_flash_erase_sector()
234 if (nvs_flash_cmp_const(fs, addr, fs->flash_parameters->erase_value, in nvs_flash_erase_sector()
235 fs->sector_size)) { in nvs_flash_erase_sector()
287 static int nvs_ate_valid(struct nvs_fs *fs, const struct nvs_ate *entry) in nvs_ate_valid() argument
291 ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_ate_valid()
294 (entry->offset >= (fs->sector_size - ate_size))) { in nvs_ate_valid()
308 static int nvs_close_ate_valid(struct nvs_fs *fs, const struct nvs_ate *entry) in nvs_close_ate_valid() argument
312 if ((!nvs_ate_valid(fs, entry)) || (entry->len != 0U) || in nvs_close_ate_valid()
317 ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_close_ate_valid()
318 if ((fs->sector_size - entry->offset) % ate_size) { in nvs_close_ate_valid()
326 static int nvs_flash_wrt_entry(struct nvs_fs *fs, uint16_t id, const void *data, in nvs_flash_wrt_entry() argument
333 ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_flash_wrt_entry()
336 entry.offset = (uint16_t)(fs->data_wra & ADDR_OFFS_MASK); in nvs_flash_wrt_entry()
342 rc = nvs_flash_data_wrt(fs, data, len); in nvs_flash_wrt_entry()
346 rc = nvs_flash_ate_wrt(fs, &entry); in nvs_flash_wrt_entry()
362 static int nvs_recover_last_ate(struct nvs_fs *fs, uint32_t *addr) in nvs_recover_last_ate() argument
372 ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_recover_last_ate()
378 rc = nvs_flash_ate_rd(fs, ate_end_addr, &end_ate); in nvs_recover_last_ate()
382 if (nvs_ate_valid(fs, &end_ate)) { in nvs_recover_last_ate()
397 static int nvs_prev_ate(struct nvs_fs *fs, uint32_t *addr, struct nvs_ate *ate) in nvs_prev_ate() argument
403 ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_prev_ate()
405 rc = nvs_flash_ate_rd(fs, *addr, ate); in nvs_prev_ate()
411 if (((*addr) & ADDR_OFFS_MASK) != (fs->sector_size - ate_size)) { in nvs_prev_ate()
417 *addr += ((fs->sector_count - 1) << ADDR_SECT_SHIFT); in nvs_prev_ate()
422 rc = nvs_flash_ate_rd(fs, *addr, &close_ate); in nvs_prev_ate()
427 rc = nvs_ate_cmp_const(&close_ate, fs->flash_parameters->erase_value); in nvs_prev_ate()
430 *addr = fs->ate_wra; in nvs_prev_ate()
436 if (nvs_close_ate_valid(fs, &close_ate)) { in nvs_prev_ate()
449 return nvs_recover_last_ate(fs, addr); in nvs_prev_ate()
452 static void nvs_sector_advance(struct nvs_fs *fs, uint32_t *addr) in nvs_sector_advance() argument
455 if ((*addr >> ADDR_SECT_SHIFT) == fs->sector_count) { in nvs_sector_advance()
456 *addr -= (fs->sector_count << ADDR_SECT_SHIFT); in nvs_sector_advance()
463 static int nvs_sector_close(struct nvs_fs *fs) in nvs_sector_close() argument
469 ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_sector_close()
473 close_ate.offset = (uint16_t)((fs->ate_wra + ate_size) & ADDR_OFFS_MASK); in nvs_sector_close()
475 fs->ate_wra &= ADDR_SECT_MASK; in nvs_sector_close()
476 fs->ate_wra += (fs->sector_size - ate_size); in nvs_sector_close()
480 rc = nvs_flash_ate_wrt(fs, &close_ate); in nvs_sector_close()
482 nvs_sector_advance(fs, &fs->ate_wra); in nvs_sector_close()
484 fs->data_wra = fs->ate_wra & ADDR_SECT_MASK; in nvs_sector_close()
489 static int nvs_add_gc_done_ate(struct nvs_fs *fs) in nvs_add_gc_done_ate() argument
493 LOG_DBG("Adding gc done ate at %x", fs->ate_wra & ADDR_OFFS_MASK); in nvs_add_gc_done_ate()
496 gc_done_ate.offset = (uint16_t)(fs->data_wra & ADDR_OFFS_MASK); in nvs_add_gc_done_ate()
499 return nvs_flash_ate_wrt(fs, &gc_done_ate); in nvs_add_gc_done_ate()
505 static int nvs_gc(struct nvs_fs *fs) in nvs_gc() argument
513 ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_gc()
515 sec_addr = (fs->ate_wra & ADDR_SECT_MASK); in nvs_gc()
516 nvs_sector_advance(fs, &sec_addr); in nvs_gc()
517 gc_addr = sec_addr + fs->sector_size - ate_size; in nvs_gc()
520 rc = nvs_flash_ate_rd(fs, gc_addr, &close_ate); in nvs_gc()
526 rc = nvs_ate_cmp_const(&close_ate, fs->flash_parameters->erase_value); in nvs_gc()
533 if (nvs_close_ate_valid(fs, &close_ate)) { in nvs_gc()
537 rc = nvs_recover_last_ate(fs, &gc_addr); in nvs_gc()
545 rc = nvs_prev_ate(fs, &gc_addr, &gc_ate); in nvs_gc()
550 if (!nvs_ate_valid(fs, &gc_ate)) { in nvs_gc()
554 wlk_addr = fs->ate_wra; in nvs_gc()
557 rc = nvs_prev_ate(fs, &wlk_addr, &wlk_ate); in nvs_gc()
567 (nvs_ate_valid(fs, &wlk_ate))) { in nvs_gc()
570 } while (wlk_addr != fs->ate_wra); in nvs_gc()
582 gc_ate.offset = (uint16_t)(fs->data_wra & ADDR_OFFS_MASK); in nvs_gc()
585 rc = nvs_flash_block_move(fs, data_addr, gc_ate.len); in nvs_gc()
590 rc = nvs_flash_ate_wrt(fs, &gc_ate); in nvs_gc()
605 if (fs->ate_wra >= (fs->data_wra + ate_size)) { in nvs_gc()
606 rc = nvs_add_gc_done_ate(fs); in nvs_gc()
613 rc = nvs_flash_erase_sector(fs, sec_addr); in nvs_gc()
620 static int nvs_startup(struct nvs_fs *fs) in nvs_startup() argument
625 /* Initialize addr to 0 for the case fs->sector_count == 0. This in nvs_startup()
631 uint8_t erase_value = fs->flash_parameters->erase_value; in nvs_startup()
633 k_mutex_lock(&fs->nvs_lock, K_FOREVER); in nvs_startup()
635 ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_startup()
639 for (i = 0; i < fs->sector_count; i++) { in nvs_startup()
641 (uint16_t)(fs->sector_size - ate_size); in nvs_startup()
642 rc = nvs_flash_cmp_const(fs, addr, erase_value, in nvs_startup()
647 nvs_sector_advance(fs, &addr); in nvs_startup()
648 rc = nvs_flash_cmp_const(fs, addr, erase_value, in nvs_startup()
656 /* all sectors are closed, this is not a nvs fs */ in nvs_startup()
657 if (closed_sectors == fs->sector_count) { in nvs_startup()
662 if (i == fs->sector_count) { in nvs_startup()
668 rc = nvs_flash_cmp_const(fs, addr - ate_size, erase_value, in nvs_startup()
672 nvs_sector_advance(fs, &addr); in nvs_startup()
680 rc = nvs_recover_last_ate(fs, &addr); in nvs_startup()
688 * also update fs->data_wra. in nvs_startup()
690 fs->ate_wra = addr; in nvs_startup()
691 fs->data_wra = addr & ADDR_SECT_MASK; in nvs_startup()
693 while (fs->ate_wra >= fs->data_wra) { in nvs_startup()
694 rc = nvs_flash_ate_rd(fs, fs->ate_wra, &last_ate); in nvs_startup()
706 if (nvs_ate_valid(fs, &last_ate)) { in nvs_startup()
708 fs->data_wra = addr & ADDR_SECT_MASK; in nvs_startup()
715 fs->data_wra += nvs_al_size(fs, last_ate.offset + last_ate.len); in nvs_startup()
720 if (fs->ate_wra == fs->data_wra && last_ate.len) { in nvs_startup()
727 fs->ate_wra -= ate_size; in nvs_startup()
736 addr = fs->ate_wra & ADDR_SECT_MASK; in nvs_startup()
737 nvs_sector_advance(fs, &addr); in nvs_startup()
738 rc = nvs_flash_cmp_const(fs, addr, erase_value, fs->sector_size); in nvs_startup()
743 /* the sector after fs->ate_wrt is not empty, look for a marker in nvs_startup()
749 addr = fs->ate_wra + ate_size; in nvs_startup()
750 while ((addr & ADDR_OFFS_MASK) < (fs->sector_size - ate_size)) { in nvs_startup()
751 rc = nvs_flash_ate_rd(fs, addr, &gc_done_ate); in nvs_startup()
755 if (nvs_ate_valid(fs, &gc_done_ate) && in nvs_startup()
767 addr = fs->ate_wra & ADDR_SECT_MASK; in nvs_startup()
768 nvs_sector_advance(fs, &addr); in nvs_startup()
769 rc = nvs_flash_erase_sector(fs, addr); in nvs_startup()
773 rc = nvs_flash_erase_sector(fs, fs->ate_wra); in nvs_startup()
777 fs->ate_wra &= ADDR_SECT_MASK; in nvs_startup()
778 fs->ate_wra += (fs->sector_size - 2 * ate_size); in nvs_startup()
779 fs->data_wra = (fs->ate_wra & ADDR_SECT_MASK); in nvs_startup()
780 rc = nvs_gc(fs); in nvs_startup()
785 while (fs->ate_wra > fs->data_wra) { in nvs_startup()
786 empty_len = fs->ate_wra - fs->data_wra; in nvs_startup()
788 rc = nvs_flash_cmp_const(fs, fs->data_wra, erase_value, in nvs_startup()
797 fs->data_wra += fs->flash_parameters->write_block_size; in nvs_startup()
804 if (((fs->ate_wra + 2 * ate_size) == fs->sector_size) && in nvs_startup()
805 (fs->data_wra != (fs->ate_wra & ADDR_SECT_MASK))) { in nvs_startup()
806 rc = nvs_flash_erase_sector(fs, fs->ate_wra); in nvs_startup()
810 fs->data_wra = fs->ate_wra & ADDR_SECT_MASK; in nvs_startup()
817 if ((!rc) && ((fs->ate_wra & ADDR_OFFS_MASK) == in nvs_startup()
818 (fs->sector_size - 2 * ate_size))) { in nvs_startup()
820 rc = nvs_add_gc_done_ate(fs); in nvs_startup()
822 k_mutex_unlock(&fs->nvs_lock); in nvs_startup()
826 int nvs_clear(struct nvs_fs *fs) in nvs_clear() argument
831 if (!fs->ready) { in nvs_clear()
836 for (uint16_t i = 0; i < fs->sector_count; i++) { in nvs_clear()
838 rc = nvs_flash_erase_sector(fs, addr); in nvs_clear()
845 fs->ready = false; in nvs_clear()
850 int nvs_init(struct nvs_fs *fs, const char *dev_name) in nvs_init() argument
857 k_mutex_init(&fs->nvs_lock); in nvs_init()
859 fs->flash_device = device_get_binding(dev_name); in nvs_init()
860 if (!fs->flash_device) { in nvs_init()
865 fs->flash_parameters = flash_get_parameters(fs->flash_device); in nvs_init()
866 if (fs->flash_parameters == NULL) { in nvs_init()
871 write_block_size = flash_get_write_block_size(fs->flash_device); in nvs_init()
880 rc = flash_get_page_info_by_offs(fs->flash_device, fs->offset, &info); in nvs_init()
885 if (!fs->sector_size || fs->sector_size % info.size) { in nvs_init()
891 if (fs->sector_count < 2) { in nvs_init()
896 rc = nvs_startup(fs); in nvs_init()
902 fs->ready = true; in nvs_init()
904 LOG_INF("%d Sectors of %d bytes", fs->sector_count, fs->sector_size); in nvs_init()
906 (fs->ate_wra >> ADDR_SECT_SHIFT), in nvs_init()
907 (fs->ate_wra & ADDR_OFFS_MASK)); in nvs_init()
909 (fs->data_wra >> ADDR_SECT_SHIFT), in nvs_init()
910 (fs->data_wra & ADDR_OFFS_MASK)); in nvs_init()
915 ssize_t nvs_write(struct nvs_fs *fs, uint16_t id, const void *data, size_t len) in nvs_write() argument
924 if (!fs->ready) { in nvs_write()
929 ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_write()
930 data_size = nvs_al_size(fs, len); in nvs_write()
936 if ((len > (fs->sector_size - 4 * ate_size)) || in nvs_write()
942 wlk_addr = fs->ate_wra; in nvs_write()
947 rc = nvs_prev_ate(fs, &wlk_addr, &wlk_ate); in nvs_write()
951 if ((wlk_ate.id == id) && (nvs_ate_valid(fs, &wlk_ate))) { in nvs_write()
955 if (wlk_addr == fs->ate_wra) { in nvs_write()
976 rc = nvs_flash_block_cmp(fs, rd_addr, data, len); in nvs_write()
994 k_mutex_lock(&fs->nvs_lock, K_FOREVER); in nvs_write()
998 if (gc_count == fs->sector_count) { in nvs_write()
1006 if (fs->ate_wra >= (fs->data_wra + required_space)) { in nvs_write()
1008 rc = nvs_flash_wrt_entry(fs, id, data, len); in nvs_write()
1016 rc = nvs_sector_close(fs); in nvs_write()
1021 rc = nvs_gc(fs); in nvs_write()
1029 k_mutex_unlock(&fs->nvs_lock); in nvs_write()
1033 int nvs_delete(struct nvs_fs *fs, uint16_t id) in nvs_delete() argument
1035 return nvs_write(fs, id, NULL, 0); in nvs_delete()
1038 ssize_t nvs_read_hist(struct nvs_fs *fs, uint16_t id, void *data, size_t len, in nvs_read_hist() argument
1047 if (!fs->ready) { in nvs_read_hist()
1052 ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_read_hist()
1054 if (len > (fs->sector_size - 2 * ate_size)) { in nvs_read_hist()
1060 wlk_addr = fs->ate_wra; in nvs_read_hist()
1065 rc = nvs_prev_ate(fs, &wlk_addr, &wlk_ate); in nvs_read_hist()
1069 if ((wlk_ate.id == id) && (nvs_ate_valid(fs, &wlk_ate))) { in nvs_read_hist()
1072 if (wlk_addr == fs->ate_wra) { in nvs_read_hist()
1077 if (((wlk_addr == fs->ate_wra) && (wlk_ate.id != id)) || in nvs_read_hist()
1084 rc = nvs_flash_rd(fs, rd_addr, data, MIN(len, wlk_ate.len)); in nvs_read_hist()
1095 ssize_t nvs_read(struct nvs_fs *fs, uint16_t id, void *data, size_t len) in nvs_read() argument
1099 rc = nvs_read_hist(fs, id, data, len, 0); in nvs_read()
1103 ssize_t nvs_calc_free_space(struct nvs_fs *fs) in nvs_calc_free_space() argument
1111 if (!fs->ready) { in nvs_calc_free_space()
1116 ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); in nvs_calc_free_space()
1119 for (uint16_t i = 1; i < fs->sector_count; i++) { in nvs_calc_free_space()
1120 free_space += (fs->sector_size - ate_size); in nvs_calc_free_space()
1123 step_addr = fs->ate_wra; in nvs_calc_free_space()
1126 rc = nvs_prev_ate(fs, &step_addr, &step_ate); in nvs_calc_free_space()
1131 wlk_addr = fs->ate_wra; in nvs_calc_free_space()
1134 rc = nvs_prev_ate(fs, &wlk_addr, &wlk_ate); in nvs_calc_free_space()
1139 (wlk_addr == fs->ate_wra)) { in nvs_calc_free_space()
1145 (nvs_ate_valid(fs, &step_ate))) { in nvs_calc_free_space()
1147 free_space -= nvs_al_size(fs, step_ate.len); in nvs_calc_free_space()
1151 if (step_addr == fs->ate_wra) { in nvs_calc_free_space()