| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- #include "internal-storage-i.h"
- int internal_storage_device_read(
- const struct lfs_config* c,
- lfs_block_t block,
- lfs_off_t off,
- void* buffer,
- lfs_size_t size) {
- InternalStorage* internal_storage = c->context;
- size_t address = internal_storage->start_address + block * c->block_size + off;
- FURI_LOG_D(
- "internal-storage",
- "Device read: block %d, off %d, buffer: %p, size %d, translated address: %p",
- block,
- off,
- buffer,
- size,
- address);
- memcpy(buffer, (void*)address, size);
- return 0;
- }
- int internal_storage_device_prog(
- const struct lfs_config* c,
- lfs_block_t block,
- lfs_off_t off,
- const void* buffer,
- lfs_size_t size) {
- InternalStorage* internal_storage = c->context;
- size_t address = internal_storage->start_address + block * c->block_size + off;
- FURI_LOG_D(
- "internal-storage",
- "Device prog: block %d, off %d, buffer: %p, size %d, translated address: %p",
- block,
- off,
- buffer,
- size,
- address);
- int ret = 0;
- while(size > 0) {
- if(!api_hal_flash_write_dword(address, *(uint64_t*)buffer)) {
- ret = -1;
- break;
- }
- address += c->prog_size;
- buffer += c->prog_size;
- size -= c->prog_size;
- }
- return ret;
- }
- int internal_storage_device_erase(const struct lfs_config* c, lfs_block_t block) {
- InternalStorage* internal_storage = c->context;
- size_t page = internal_storage->start_page + block;
- FURI_LOG_D("internal-storage", "Device erase: page %d, translated page: %d", block, page);
- if(api_hal_flash_erase(page, 1)) {
- return 0;
- } else {
- return -1;
- }
- }
- int internal_storage_device_sync(const struct lfs_config* c) {
- FURI_LOG_D("internal-storage", "Device sync: skipping, cause ");
- return 0;
- }
- InternalStorage* internal_storage_alloc() {
- InternalStorage* internal_storage = furi_alloc(sizeof(InternalStorage));
- internal_storage->queue = osMessageQueueNew(8, sizeof(InternalStorageCommand), NULL);
- // Internal storage start address
- internal_storage->state = InternalStorageStateInitializing;
- // Internal storage start address
- *(size_t*)(&internal_storage->start_address) = api_hal_flash_get_free_page_start_address();
- *(size_t*)(&internal_storage->start_page) =
- (internal_storage->start_address - api_hal_flash_get_base()) /
- api_hal_flash_get_page_size();
- // LFS configuration
- // Glue and context
- internal_storage->config.context = internal_storage;
- internal_storage->config.read = internal_storage_device_read;
- internal_storage->config.prog = internal_storage_device_prog;
- internal_storage->config.erase = internal_storage_device_erase;
- internal_storage->config.sync = internal_storage_device_sync;
- // Block device description
- internal_storage->config.read_size = api_hal_flash_get_read_block_size();
- internal_storage->config.prog_size = api_hal_flash_get_write_block_size();
- internal_storage->config.block_size = api_hal_flash_get_page_size();
- internal_storage->config.block_count = api_hal_flash_get_free_page_count();
- internal_storage->config.block_cycles = api_hal_flash_get_cycles_count();
- internal_storage->config.cache_size = 16;
- internal_storage->config.lookahead_size = 16;
- return internal_storage;
- }
- void internal_storage_free(InternalStorage* internal_storage) {
- furi_assert(internal_storage);
- free(internal_storage);
- }
- int32_t internal_storage_task(void* p) {
- FURI_LOG_I("internal-storage", "Starting");
- InternalStorage* internal_storage = internal_storage_alloc();
- FURI_LOG_I(
- "internal-storage",
- "Config: start %p, read %d, write %d, page size: %d, page count: %d, cycles: %d",
- internal_storage->start_address,
- internal_storage->config.read_size,
- internal_storage->config.prog_size,
- internal_storage->config.block_size,
- internal_storage->config.block_count,
- internal_storage->config.block_cycles);
- int err;
- ApiHalBootFlag boot_flags = api_hal_boot_get_flags();
- if(boot_flags & ApiHalBootFlagFactoryReset) {
- // Factory reset
- err = lfs_format(&internal_storage->lfs, &internal_storage->config);
- if(err == 0) {
- FURI_LOG_I("internal-storage", "Factory reset: Format successful, trying to mount");
- api_hal_boot_set_flags(boot_flags & ~ApiHalBootFlagFactoryReset);
- err = lfs_mount(&internal_storage->lfs, &internal_storage->config);
- if(err == 0) {
- FURI_LOG_I("internal-storage", "Factory reset: Mounted");
- internal_storage->state = InternalStorageStateReady;
- } else {
- FURI_LOG_E("internal-storage", "Factory reset: Mount after format failed");
- internal_storage->state = InternalStorageStateBroken;
- }
- } else {
- FURI_LOG_E("internal-storage", "Factory reset: Format failed");
- internal_storage->state = InternalStorageStateBroken;
- }
- } else {
- // Normal
- err = lfs_mount(&internal_storage->lfs, &internal_storage->config);
- if(err == 0) {
- FURI_LOG_I("internal-storage", "Mounted");
- internal_storage->state = InternalStorageStateReady;
- } else {
- FURI_LOG_E("internal-storage", "Mount failed, formatting");
- err = lfs_format(&internal_storage->lfs, &internal_storage->config);
- if(err == 0) {
- FURI_LOG_I("internal-storage", "Format successful, trying to mount");
- err = lfs_mount(&internal_storage->lfs, &internal_storage->config);
- if(err == 0) {
- FURI_LOG_I("internal-storage", "Mounted");
- internal_storage->state = InternalStorageStateReady;
- } else {
- FURI_LOG_E("internal-storage", "Mount after format failed");
- internal_storage->state = InternalStorageStateBroken;
- }
- } else {
- FURI_LOG_E("internal-storage", "Format failed");
- internal_storage->state = InternalStorageStateBroken;
- }
- }
- }
- furi_record_create("internal-storage", internal_storage);
- InternalStorageCommand command;
- while(1) {
- furi_check(
- osMessageQueueGet(internal_storage->queue, &command, NULL, osWaitForever) == osOK);
- command.function(internal_storage, command.data);
- osThreadFlagsSet(command.thread, INTERNAL_STORAGE_THREAD_FLAG_CALL_COMPLETE);
- }
- lfs_unmount(&internal_storage->lfs);
- internal_storage_free(internal_storage);
- return 0;
- }
- void _internal_storage_read_key(InternalStorage* internal_storage, InternalStorageCommandKey* data) {
- lfs_file_t file;
- int ret = lfs_file_open(&internal_storage->lfs, &file, data->key, LFS_O_RDONLY);
- if(ret == 0) {
- ret = lfs_file_read(&internal_storage->lfs, &file, data->buffer, data->size);
- lfs_file_close(&internal_storage->lfs, &file);
- }
- data->ret = ret;
- }
- int internal_storage_read_key(
- InternalStorage* internal_storage,
- const char* key,
- uint8_t* buffer,
- size_t size) {
- osThreadId_t caller_thread = osThreadGetId();
- if(caller_thread == 0) {
- return -1;
- }
- InternalStorageCommandKey data = {.key = key, .buffer = buffer, .size = size, .ret = 0};
- InternalStorageCommand command = {
- .thread = caller_thread,
- .function = (InternalStorageCommandFunction)_internal_storage_read_key,
- .data = &data,
- };
- furi_check(osMessageQueuePut(internal_storage->queue, &command, 0, osWaitForever) == osOK);
- osThreadFlagsWait(INTERNAL_STORAGE_THREAD_FLAG_CALL_COMPLETE, osFlagsWaitAny, osWaitForever);
- return data.ret;
- }
- void _internal_storage_write_key(
- InternalStorage* internal_storage,
- InternalStorageCommandKey* data) {
- lfs_file_t file;
- int ret = lfs_file_open(
- &internal_storage->lfs, &file, data->key, LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC);
- if(ret == 0) {
- ret = lfs_file_write(&internal_storage->lfs, &file, data->buffer, data->size);
- lfs_file_close(&internal_storage->lfs, &file);
- }
- data->ret = ret;
- }
- int internal_storage_write_key(
- InternalStorage* internal_storage,
- const char* key,
- uint8_t* buffer,
- size_t size) {
- osThreadId_t caller_thread = osThreadGetId();
- if(caller_thread == 0) {
- return -1;
- }
- InternalStorageCommandKey data = {.key = key, .buffer = buffer, .size = size, .ret = 0};
- InternalStorageCommand command = {
- .thread = caller_thread,
- .function = (InternalStorageCommandFunction)_internal_storage_write_key,
- .data = &data,
- };
- furi_check(osMessageQueuePut(internal_storage->queue, &command, 0, osWaitForever) == osOK);
- osThreadFlagsWait(INTERNAL_STORAGE_THREAD_FLAG_CALL_COMPLETE, osFlagsWaitAny, osWaitForever);
- return data.ret;
- }
|