[FL-977] Internal Storage (#455)
* Add littlefs submodule * Furi: add mutex in logging, fix issues with corrupted printf * ApiHal: disable debug traces in ble glue * App-loader: more logs * Passport: fix invalid DolphinState usage * ApiHal, linker script: flash API is now aware of free space, complete abstraction layer for storage * Internal Storage: littlefs based storage services with key value API. Migrate dolphin state to new storage API.
This commit is contained in:
		@@ -1,6 +1,59 @@
 | 
			
		||||
#include <api-hal-flash.h>
 | 
			
		||||
#include <api-hal-bt.h>
 | 
			
		||||
#include <stm32wbxx.h>
 | 
			
		||||
#include <furi.h>
 | 
			
		||||
 | 
			
		||||
/* Free flash space borders, exported by linker */
 | 
			
		||||
extern const void __free_flash_start__;
 | 
			
		||||
extern const void __free_flash_end__;
 | 
			
		||||
 | 
			
		||||
#define API_HAL_FLASH_READ_BLOCK 8
 | 
			
		||||
#define API_HAL_FLASH_WRITE_BLOCK 8
 | 
			
		||||
#define API_HAL_FLASH_PAGE_SIZE 4096
 | 
			
		||||
#define API_HAL_FLASH_CYCLES_COUNT 10000
 | 
			
		||||
 | 
			
		||||
size_t api_hal_flash_get_base() {
 | 
			
		||||
    return FLASH_BASE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t api_hal_flash_get_read_block_size() {
 | 
			
		||||
    return API_HAL_FLASH_READ_BLOCK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t api_hal_flash_get_write_block_size() {
 | 
			
		||||
    return API_HAL_FLASH_WRITE_BLOCK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t api_hal_flash_get_page_size() {
 | 
			
		||||
    return API_HAL_FLASH_PAGE_SIZE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t api_hal_flash_get_cycles_count() {
 | 
			
		||||
    return API_HAL_FLASH_CYCLES_COUNT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void* api_hal_flash_get_free_start_address() {
 | 
			
		||||
    return &__free_flash_start__;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void* api_hal_flash_get_free_end_address() {
 | 
			
		||||
    return &__free_flash_end__;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t api_hal_flash_get_free_page_start_address() {
 | 
			
		||||
    size_t start = (size_t)api_hal_flash_get_free_start_address();
 | 
			
		||||
    size_t page_start = start - start % API_HAL_FLASH_PAGE_SIZE;
 | 
			
		||||
    if (page_start != start) {
 | 
			
		||||
        page_start += API_HAL_FLASH_PAGE_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
    return page_start;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t api_hal_flash_get_free_page_count() {
 | 
			
		||||
    size_t end = (size_t)api_hal_flash_get_free_end_address();
 | 
			
		||||
    size_t page_start = (size_t)api_hal_flash_get_free_page_start_address();
 | 
			
		||||
    return (end-page_start) / API_HAL_FLASH_PAGE_SIZE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool api_hal_flash_erase(uint8_t page, uint8_t count) {
 | 
			
		||||
    if (!api_hal_bt_lock_flash()) {
 | 
			
		||||
@@ -25,7 +78,7 @@ bool api_hal_flash_write_dword(size_t address, uint64_t data) {
 | 
			
		||||
    return status == HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool api_hal_flash_write_row(size_t address, size_t source_address) {
 | 
			
		||||
bool api_hal_flash_write_dword_from(size_t address, size_t source_address) {
 | 
			
		||||
    if (!api_hal_bt_lock_flash()) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,51 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
/** Get flash base address
 | 
			
		||||
 * @return pointer to flash base
 | 
			
		||||
 */
 | 
			
		||||
size_t api_hal_flash_get_base();
 | 
			
		||||
 | 
			
		||||
/** Get flash read block size
 | 
			
		||||
 * @return size in bytes
 | 
			
		||||
 */
 | 
			
		||||
size_t api_hal_flash_get_read_block_size();
 | 
			
		||||
 | 
			
		||||
/** Get flash write block size
 | 
			
		||||
 * @return size in bytes
 | 
			
		||||
 */
 | 
			
		||||
size_t api_hal_flash_get_write_block_size();
 | 
			
		||||
 | 
			
		||||
/** Get flash page size
 | 
			
		||||
 * @return size in bytes
 | 
			
		||||
 */
 | 
			
		||||
size_t api_hal_flash_get_page_size();
 | 
			
		||||
 | 
			
		||||
/** Get expected flash cycles count
 | 
			
		||||
 * @return count of erase-write operations 
 | 
			
		||||
 */
 | 
			
		||||
size_t api_hal_flash_get_cycles_count();
 | 
			
		||||
 | 
			
		||||
/** Get free flash start address
 | 
			
		||||
 * @return pointer to free region start
 | 
			
		||||
 */
 | 
			
		||||
const void* api_hal_flash_get_free_start_address();
 | 
			
		||||
 | 
			
		||||
/** Get free flash end address
 | 
			
		||||
 * @return pointer to free region end
 | 
			
		||||
 */
 | 
			
		||||
const void* api_hal_flash_get_free_end_address();
 | 
			
		||||
 | 
			
		||||
/** Get first free page start address
 | 
			
		||||
 * @return first free page memory address
 | 
			
		||||
 */
 | 
			
		||||
size_t api_hal_flash_get_free_page_start_address();
 | 
			
		||||
 | 
			
		||||
/** Get free page count
 | 
			
		||||
 * @return free page count
 | 
			
		||||
 */
 | 
			
		||||
size_t api_hal_flash_get_free_page_count();
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Erase Flash
 | 
			
		||||
 * Locking operation, uses HSEM to manage shared access.
 | 
			
		||||
@@ -21,9 +66,9 @@ bool api_hal_flash_erase(uint8_t page, uint8_t count);
 | 
			
		||||
bool api_hal_flash_write_dword(size_t address, uint64_t data);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Write page (4096 bytes or 64 rows of double words).
 | 
			
		||||
 * Write double word (64 bits) from address
 | 
			
		||||
 * Locking operation, uses HSEM to manage shared access.
 | 
			
		||||
 * @param address - destination address, must be page aligned
 | 
			
		||||
 * @param address - destination address, must be block aligned
 | 
			
		||||
 * @param source_address - source address
 | 
			
		||||
 */
 | 
			
		||||
bool api_hal_flash_write_page(size_t address, size_t source_address);
 | 
			
		||||
bool api_hal_flash_write_dword_from(size_t address, size_t source_address);
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@ extern UART_HandleTypeDef DEBUG_UART;
 | 
			
		||||
#define TL_HCI_EVT_DBG_EN       0   /* Reports BLE Asynchronous Events received from CPU2 */
 | 
			
		||||
#define TL_HCI_EVT_DBG_RAW_EN   0   /* Reports raw data BLE Asynchronous Events received from CPU2 */
 | 
			
		||||
 | 
			
		||||
#define TL_MM_DBG_EN            1   /* Reports the informations of the buffer released to CPU2 */
 | 
			
		||||
#define TL_MM_DBG_EN            0   /* Reports the informations of the buffer released to CPU2 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Macro definition
 | 
			
		||||
 
 | 
			
		||||
@@ -168,7 +168,13 @@ SECTIONS
 | 
			
		||||
    . = ALIGN(8);
 | 
			
		||||
  } >RAM1
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  /* Free Flash space, that can be used for internal storage */
 | 
			
		||||
  .free_flash(NOLOAD):
 | 
			
		||||
  {
 | 
			
		||||
    __free_flash_start__ = .;
 | 
			
		||||
    . = ORIGIN(FLASH) + LENGTH(FLASH);
 | 
			
		||||
    __free_flash_end__ = .;
 | 
			
		||||
  } >FLASH
 | 
			
		||||
 | 
			
		||||
  /* Remove information from the standard libraries */
 | 
			
		||||
  /DISCARD/ :
 | 
			
		||||
 
 | 
			
		||||
@@ -49,8 +49,8 @@ ENTRY(Reset_Handler)
 | 
			
		||||
/* Highest address of the user mode stack */
 | 
			
		||||
_estack = 0x20030000;    /* end of RAM */
 | 
			
		||||
/* Generate a link error if heap and stack don't fit into RAM */
 | 
			
		||||
_Min_Heap_Size = 0x200;      /* required amount of heap  */
 | 
			
		||||
_Min_Stack_Size = 0x400; /* required amount of stack */
 | 
			
		||||
_Min_Heap_Size = 0x400;      /* required amount of heap  */
 | 
			
		||||
_Min_Stack_Size = 0x1000; /* required amount of stack */
 | 
			
		||||
 | 
			
		||||
/* Specify the memory areas */
 | 
			
		||||
MEMORY
 | 
			
		||||
@@ -168,7 +168,13 @@ SECTIONS
 | 
			
		||||
    . = ALIGN(8);
 | 
			
		||||
  } >RAM1
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  /* Free Flash space, that can be used for internal storage */
 | 
			
		||||
  .free_flash(NOLOAD):
 | 
			
		||||
  {
 | 
			
		||||
    __free_flash_start__ = .;
 | 
			
		||||
    . = ORIGIN(FLASH) + LENGTH(FLASH);
 | 
			
		||||
    __free_flash_end__ = .;
 | 
			
		||||
  } >FLASH
 | 
			
		||||
 | 
			
		||||
  /* Remove information from the standard libraries */
 | 
			
		||||
  /DISCARD/ :
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user