17#ifdef HAVE_APP_STORAGE
25#define APP_STORAGE_ERASE_BLOCK_SIZE 256
27CONST app_storage_t app_storage_real
__attribute__((section(
".storage_section")));
28#define app_storage (*(volatile app_storage_t *) PIC(&app_storage_real))
33STATIC int32_t app_storage_is_initalized(
void)
44 uint32_t crc = cx_crc32((
void *) &app_storage.header,
45 sizeof(app_storage.header) + app_storage.header.size);
46 if (crc != app_storage.crc) {
58static inline void update_crc(
void)
60 uint32_t crc = cx_crc32((
void *) &app_storage.header,
61 sizeof(app_storage.header) + app_storage.header.size);
62 nvm_write((
void *) &app_storage.crc, &crc,
sizeof(app_storage.crc));
68static inline void system_header_reset(
void)
79 header.
properties = ((HAVE_APP_STORAGE_PROP_SETTINGS << 0) | (HAVE_APP_STORAGE_PROP_DATA << 1));
80 nvm_write((
void *) &app_storage.header, &header,
sizeof(header));
97int32_t app_storage_init(
void)
99 int32_t status = app_storage_is_initalized();
103 system_header_reset();
107 system_header_reset();
123 system_header_reset();
125 uint8_t erase_buf[APP_STORAGE_ERASE_BLOCK_SIZE] = {0};
127 bool need_update =
false;
129 if (APP_STORAGE_SIZE > APP_STORAGE_ERASE_BLOCK_SIZE) {
130 for (; offset < APP_STORAGE_SIZE - APP_STORAGE_ERASE_BLOCK_SIZE;
131 offset += APP_STORAGE_ERASE_BLOCK_SIZE) {
132 nvm_write((
void *) &app_storage.data[offset],
134 APP_STORAGE_ERASE_BLOCK_SIZE);
138 if (APP_STORAGE_SIZE > offset) {
140 (
void *) &app_storage.data[offset], (
void *) erase_buf, APP_STORAGE_SIZE - offset);
153 return app_storage.header.size;
161 return app_storage.header.data_version;
169 return app_storage.header.properties;
177 uint32_t data_version = app_storage.header.data_version;
179 if (data_version == 0) {
187 (
void *) &app_storage.header.data_version, (
void *) &data_version,
sizeof(data_version));
197 (
void *) &app_storage.header.data_version, (
void *) &data_version,
sizeof(data_version));
213 uint32_t max_offset = 0;
214 if (__builtin_add_overflow(offset, nbyte, &max_offset)) {
219 if (max_offset > APP_STORAGE_SIZE) {
224 nvm_write((
void *) &app_storage.data[offset], (
void *) buf, nbyte);
227 if (app_storage.header.size < max_offset) {
228 nvm_write((
void *) &app_storage.header.size, (
void *) &max_offset,
sizeof(max_offset));
247 uint32_t max_offset = 0;
248 if (__builtin_add_overflow(offset, nbyte, &max_offset)) {
253 if (max_offset > app_storage.header.size) {
258 memcpy((
void *) buf, (
void *) &app_storage.data[offset], nbyte);
void app_storage_reset(void)
uint32_t app_storage_get_size(void)
#define APP_STORAGE_ERR_INVALID_ARGUMENT
Invalid argument.
#define APP_STORAGE_ERR_OVERFLOW
Value too large to be stored.
#define APP_STORAGE_INITIAL_APP_DATA_VERSION
Initial app data storage version.
#define APP_STORAGE_SUCCESS
No error.
int32_t app_storage_read(void *buf, uint32_t nbyte, uint32_t offset)
void app_storage_set_data_version(uint32_t data_version)
#define APP_STORAGE_ERR_INVALID_HEADER
Invalid storage header.
#define APP_STORAGE_ERR_CORRUPTED
App storage is corrupted.
void app_storage_increment_data_version(void)
#define APP_STORAGE_ERR_NO_DATA_AVAILABLE
Address not available for reading.
#define APP_STORAGE_TAG
Header structure version.
int32_t app_storage_write(const void *buf, uint32_t nbyte, uint32_t offset)
#define APP_STORAGE_TAG_LEN
Tag value.
uint16_t app_storage_get_properties(void)
uint32_t app_storage_get_data_version(void)
#define APP_STORAGE_HEADER_STRUCT_VERSION
Error codes.
const size_t absolution_globals_size __attribute__((weak))
CRC (Cyclic Redundancy Check).