diff --git a/inc/fdb_low_lvl.h b/inc/fdb_low_lvl.h index c252dca..4de0750 100644 --- a/inc/fdb_low_lvl.h +++ b/inc/fdb_low_lvl.h @@ -66,4 +66,6 @@ fdb_err_t _fdb_flash_read(fdb_db_t db, uint32_t addr, void *buf, size_t size); fdb_err_t _fdb_flash_erase(fdb_db_t db, uint32_t addr, size_t size); fdb_err_t _fdb_flash_write(fdb_db_t db, uint32_t addr, const void *buf, size_t size, bool sync); +fdb_err_t align_write(fdb_db_t db, uint32_t addr, const uint32_t *buf, size_t size); + #endif /* _FDB_LOW_LVL_H_ */ diff --git a/src/fdb_kvdb.c b/src/fdb_kvdb.c index 10c29d4..8c101dd 100644 --- a/src/fdb_kvdb.c +++ b/src/fdb_kvdb.c @@ -434,7 +434,7 @@ static fdb_err_t read_sector_info(fdb_kvdb_t db, uint32_t addr, kv_sec_info_t se sector->addr = addr; sector->magic = sec_hdr.magic; /* check magic word and combined value */ - if (sector->magic != SECTOR_MAGIC_WORD || + if (sector->magic != SECTOR_MAGIC_WORD || (sec_hdr.combined != SECTOR_NOT_COMBINED && sec_hdr.combined != SECTOR_COMBINED)) { sector->check_ok = false; sector->combined = SECTOR_NOT_COMBINED; @@ -1177,34 +1177,6 @@ static void gc_collect(fdb_kvdb_t db) gc_collect_by_free_size(db, db_max_size(db)); } -static fdb_err_t align_write(fdb_kvdb_t db, uint32_t addr, const uint32_t *buf, size_t size) -{ - fdb_err_t result = FDB_NO_ERR; - size_t align_remain; - -#if (FDB_WRITE_GRAN / 8 > 0) - uint8_t align_data[FDB_WRITE_GRAN / 8]; - size_t align_data_size = sizeof(align_data); -#else - /* For compatibility with C89 */ - uint8_t align_data_u8, *align_data = &align_data_u8; - size_t align_data_size = 1; -#endif - - memset(align_data, FDB_BYTE_ERASED, align_data_size); - if(FDB_WG_ALIGN_DOWN(size) > 0) { - result = _fdb_flash_write((fdb_db_t) db, addr, buf, FDB_WG_ALIGN_DOWN(size), false); - } - - align_remain = size - FDB_WG_ALIGN_DOWN(size); - if (result == FDB_NO_ERR && align_remain) { - memcpy(align_data, (uint8_t *) buf + FDB_WG_ALIGN_DOWN(size), align_remain); - result = _fdb_flash_write((fdb_db_t) db, addr + FDB_WG_ALIGN_DOWN(size), (uint32_t *) align_data, - align_data_size, false); - } - - return result; -} static fdb_err_t create_kv_blob(fdb_kvdb_t db, kv_sec_info_t sector, const char *key, const void *value, size_t len) { @@ -1818,9 +1790,9 @@ fdb_err_t fdb_kvdb_init(fdb_kvdb_t db, const char *name, const char *path, struc FDB_DEBUG("KVDB size is %" PRIu32 " bytes.\n", db_max_size(db)); db_unlock(db); - + result = _fdb_kv_load(db); - + db_lock(db); #ifdef FDB_KV_AUTO_UPDATE if (result == FDB_NO_ERR) { diff --git a/src/fdb_tsdb.c b/src/fdb_tsdb.c index bc53375..5ef596f 100644 --- a/src/fdb_tsdb.c +++ b/src/fdb_tsdb.c @@ -25,14 +25,17 @@ #if defined(FDB_USING_TSDB) -#if (FDB_WRITE_GRAN == 64) || (FDB_WRITE_GRAN == 128) -#error "Flash 64 or 128 bits write granularity is not supported in TSDB yet!" -#endif - /* magic word(`T`, `S`, `L`, `0`) */ #define SECTOR_MAGIC_WORD 0x304C5354 #define TSL_STATUS_TABLE_SIZE FDB_STATUS_TABLE_SIZE(FDB_TSL_STATUS_NUM) +#define TSL_UINT32_ALIGN_SIZE (FDB_WG_ALIGN(sizeof(uint32_t))) + +#ifdef FDB_USING_TIMESTAMP_64BIT + #define TSL_TIME_ALIGN_SIZE FDB_WG_ALIGN(sizeof(int64_t)) +#else + #define TSL_TIME_ALIGN_SIZE FDB_WG_ALIGN(sizeof(int32_t)) +#endif #define SECTOR_HDR_DATA_SIZE (FDB_WG_ALIGN(sizeof(struct sector_hdr_data))) #define LOG_IDX_DATA_SIZE (FDB_WG_ALIGN(sizeof(struct log_idx_data))) @@ -79,14 +82,17 @@ struct sector_hdr_data { uint8_t status[FDB_STORE_STATUS_TABLE_SIZE]; /**< sector store status @see fdb_sector_store_status_t */ - uint32_t magic; /**< magic word(`T`, `S`, `L`, `0`) */ - fdb_time_t start_time; /**< the first start node's timestamp */ + uint8_t magic[TSL_UINT32_ALIGN_SIZE]; /**< magic word(`T`, `S`, `L`, `0`) */ + uint8_t start_time[TSL_TIME_ALIGN_SIZE]; /**< the first start node's timestamp */ struct { - fdb_time_t time; /**< the last end node's timestamp */ - uint32_t index; /**< the last end node's index */ + uint8_t time[TSL_TIME_ALIGN_SIZE]; /**< the last end node's timestamp */ + uint8_t index[TSL_UINT32_ALIGN_SIZE]; /**< the last end node's index */ uint8_t status[TSL_STATUS_TABLE_SIZE]; /**< end node status, @see fdb_tsl_status_t */ } end_info[2]; uint32_t reserved; + + // Autofill to the FDB WRITE GRAN alignment + uint8_t padding[FDB_WG_ALIGN(sizeof(uint32_t))- sizeof(uint32_t)]; }; typedef struct sector_hdr_data *sector_hdr_data_t; @@ -98,6 +104,23 @@ struct log_idx_data { uint32_t log_len; /**< node total length (header + name + value), must align by FDB_WRITE_GRAN */ uint32_t log_addr; /**< node address */ #endif + // Autofill to the FDB WRITE GRAN alignment + uint8_t padding[ + FDB_WG_ALIGN( + sizeof(uint8_t) * TSL_STATUS_TABLE_SIZE + + sizeof(fdb_time_t) +#ifndef FDB_TSDB_FIXED_BLOB_SIZE + + sizeof(uint32_t) * 2 +#endif + ) - + ( + sizeof(uint8_t) * TSL_STATUS_TABLE_SIZE + + sizeof(fdb_time_t) +#ifndef FDB_TSDB_FIXED_BLOB_SIZE + + sizeof(uint32_t) * 2 +#endif + ) + ]; }; typedef struct log_idx_data *log_idx_data_t; @@ -219,7 +242,7 @@ static fdb_err_t read_sector_info(fdb_tsdb_t db, uint32_t addr, tsdb_sec_info_t _fdb_flash_read((fdb_db_t)db, addr, (uint32_t *)&sec_hdr, sizeof(struct sector_hdr_data)); sector->addr = addr; - sector->magic = sec_hdr.magic; + memcpy(§or->magic, sec_hdr.magic, sizeof(uint32_t)); /* check magic word */ if (sector->magic != SECTOR_MAGIC_WORD) { @@ -228,15 +251,15 @@ static fdb_err_t read_sector_info(fdb_tsdb_t db, uint32_t addr, tsdb_sec_info_t } sector->check_ok = true; sector->status = (fdb_sector_store_status_t) _fdb_get_status(sec_hdr.status, FDB_SECTOR_STORE_STATUS_NUM); - sector->start_time = sec_hdr.start_time; + memcpy(§or->start_time, sec_hdr.start_time, sizeof(fdb_time_t)); sector->end_info_stat[0] = (fdb_tsl_status_t) _fdb_get_status(sec_hdr.end_info[0].status, FDB_TSL_STATUS_NUM); sector->end_info_stat[1] = (fdb_tsl_status_t) _fdb_get_status(sec_hdr.end_info[1].status, FDB_TSL_STATUS_NUM); if (sector->end_info_stat[0] == FDB_TSL_WRITE) { - sector->end_time = sec_hdr.end_info[0].time; - sector->end_idx = sec_hdr.end_info[0].index; + memcpy(§or->end_time, sec_hdr.end_info[0].time, sizeof(fdb_time_t)); + memcpy(§or->end_idx, sec_hdr.end_info[0].index, sizeof(uint32_t)); } else if (sector->end_info_stat[1] == FDB_TSL_WRITE) { - sector->end_time = sec_hdr.end_info[1].time; - sector->end_idx = sec_hdr.end_info[1].index; + memcpy(§or->end_time, sec_hdr.end_info[1].time, sizeof(fdb_time_t)); + memcpy(§or->end_idx, sec_hdr.end_info[1].index, sizeof(uint32_t)); } else if (sector->end_info_stat[0] == FDB_TSL_PRE_WRITE && sector->end_info_stat[1] == FDB_TSL_PRE_WRITE) { //TODO There is no valid end node info on this sector, need impl fast query this sector by fdb_tsl_iter_by_time FDB_ASSERT(0); @@ -279,6 +302,7 @@ static fdb_err_t format_sector(fdb_tsdb_t db, uint32_t addr) { fdb_err_t result = FDB_NO_ERR; struct sector_hdr_data sec_hdr; + uint32_t magic = SECTOR_MAGIC_WORD; FDB_ASSERT(addr % db_sec_size(db) == 0); @@ -286,8 +310,9 @@ static fdb_err_t format_sector(fdb_tsdb_t db, uint32_t addr) if (result == FDB_NO_ERR) { _FDB_WRITE_STATUS(db, addr, sec_hdr.status, FDB_SECTOR_STORE_STATUS_NUM, FDB_SECTOR_STORE_EMPTY, true); /* set the magic */ - sec_hdr.magic = SECTOR_MAGIC_WORD; - FLASH_WRITE(db, addr + SECTOR_MAGIC_OFFSET, &sec_hdr.magic, sizeof(sec_hdr.magic), true); + memset(sec_hdr.magic, FDB_BYTE_ERASED, TSL_UINT32_ALIGN_SIZE); + memcpy(sec_hdr.magic, &magic, sizeof(uint32_t)); + FLASH_WRITE(db, addr + SECTOR_MAGIC_OFFSET, &sec_hdr.magic, TSL_UINT32_ALIGN_SIZE, true); } return result; @@ -333,7 +358,10 @@ static fdb_err_t write_tsl(fdb_tsdb_t db, fdb_blob_t blob, fdb_time_t time) /* write other index info */ FLASH_WRITE(db, idx_addr + LOG_IDX_TS_OFFSET, &idx.time, sizeof(struct log_idx_data) - LOG_IDX_TS_OFFSET, false); /* write blob data */ - FLASH_WRITE(db, log_addr, blob->buf, blob->size, false); + result = align_write(db, log_addr, blob->buf, blob->size); + if (result != FDB_NO_ERR){ + return result; + } /* write the status will by write granularity */ _FDB_WRITE_STATUS(db, idx_addr, idx.status_table, FDB_TSL_STATUS_NUM, FDB_TSL_WRITE, true); @@ -344,20 +372,29 @@ static fdb_err_t update_sec_status(fdb_tsdb_t db, tsdb_sec_info_t sector, fdb_bl { fdb_err_t result = FDB_NO_ERR; uint8_t status[FDB_STORE_STATUS_TABLE_SIZE]; + uint8_t time[TSL_TIME_ALIGN_SIZE]; + uint8_t index[TSL_UINT32_ALIGN_SIZE]; if (sector->status == FDB_SECTOR_STORE_USING && sector->remain < LOG_IDX_DATA_SIZE + FDB_WG_ALIGN(blob->size)) { uint8_t end_status[TSL_STATUS_TABLE_SIZE]; - uint32_t end_index = sector->empty_idx - LOG_IDX_DATA_SIZE, new_sec_addr, cur_sec_addr = sector->addr; + uint32_t end_index_temp = sector->empty_idx - LOG_IDX_DATA_SIZE, new_sec_addr, cur_sec_addr = sector->addr; + + memset(index, FDB_BYTE_ERASED, TSL_UINT32_ALIGN_SIZE); + memcpy(index, &end_index_temp, sizeof(uint32_t)); + + memset(time, FDB_BYTE_ERASED, TSL_TIME_ALIGN_SIZE); + memcpy(time, &db->last_time, sizeof(fdb_time_t)); + /* save the end node index and timestamp */ if (sector->end_info_stat[0] == FDB_TSL_UNUSED) { _FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END0_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_PRE_WRITE, false); - FLASH_WRITE(db, cur_sec_addr + SECTOR_END0_TIME_OFFSET, (uint32_t * )&db->last_time, sizeof(fdb_time_t), false); - FLASH_WRITE(db, cur_sec_addr + SECTOR_END0_IDX_OFFSET, &end_index, sizeof(end_index), false); + FLASH_WRITE(db, cur_sec_addr + SECTOR_END0_TIME_OFFSET, time, TSL_TIME_ALIGN_SIZE, false); + FLASH_WRITE(db, cur_sec_addr + SECTOR_END0_IDX_OFFSET, index, TSL_UINT32_ALIGN_SIZE, false); _FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END0_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_WRITE, true); } else if (sector->end_info_stat[1] == FDB_TSL_UNUSED) { _FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END1_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_PRE_WRITE, false); - FLASH_WRITE(db, cur_sec_addr + SECTOR_END1_TIME_OFFSET, (uint32_t * )&db->last_time, sizeof(fdb_time_t), false); - FLASH_WRITE(db, cur_sec_addr + SECTOR_END1_IDX_OFFSET, &end_index, sizeof(end_index), false); + FLASH_WRITE(db, cur_sec_addr + SECTOR_END1_TIME_OFFSET, time, TSL_TIME_ALIGN_SIZE, false); + FLASH_WRITE(db, cur_sec_addr + SECTOR_END1_IDX_OFFSET, index, TSL_UINT32_ALIGN_SIZE, false); _FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END1_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_WRITE, true); } /* change current sector to full */ @@ -395,7 +432,9 @@ static fdb_err_t update_sec_status(fdb_tsdb_t db, tsdb_sec_info_t sector, fdb_bl sector->start_time = cur_time; _FDB_WRITE_STATUS(db, sector->addr, status, FDB_SECTOR_STORE_STATUS_NUM, FDB_SECTOR_STORE_USING, true); /* save the start timestamp */ - FLASH_WRITE(db, sector->addr + SECTOR_START_TIME_OFFSET, (uint32_t *)&cur_time, sizeof(fdb_time_t), true); + memset(time, FDB_BYTE_ERASED, TSL_TIME_ALIGN_SIZE); + memcpy(time, &cur_time, sizeof(fdb_time_t)); + FLASH_WRITE(db, sector->addr + SECTOR_START_TIME_OFFSET, time, TSL_TIME_ALIGN_SIZE, true); } return result; @@ -415,7 +454,7 @@ static fdb_err_t tsl_append(fdb_tsdb_t db, fdb_blob_t blob, fdb_time_t *timestam /* check the append length, MUST less than the db->max_len */ if(blob->size > db->max_len) { - FDB_INFO("Warning: append length (%" PRIdMAX ") is more than the db->max_len (%" PRIdMAX "). This tsl will be dropped.\n", + FDB_INFO("Warning: append length (%" PRIdMAX ") is more than the db->max_len (%" PRIdMAX "). This tsl will be dropped.\n", (intmax_t)blob->size, (intmax_t)(db->max_len)); return FDB_WRITE_ERR; } @@ -1046,4 +1085,4 @@ fdb_err_t fdb_tsdb_deinit(fdb_tsdb_t db) return FDB_NO_ERR; } -#endif /* defined(FDB_USING_TSDB) */ +#endif /* defined(FDB_USING_TSDB) */ \ No newline at end of file diff --git a/src/fdb_utils.c b/src/fdb_utils.c index 0776f13..9c7df25 100644 --- a/src/fdb_utils.c +++ b/src/fdb_utils.c @@ -318,3 +318,32 @@ fdb_err_t _fdb_flash_write(fdb_db_t db, uint32_t addr, const void *buf, size_t s return result; } + +fdb_err_t align_write(fdb_db_t db, uint32_t addr, const uint32_t *buf, size_t size) +{ + fdb_err_t result = FDB_NO_ERR; + size_t align_remain; + +#if (FDB_WRITE_GRAN / 8 > 0) + uint8_t align_data[FDB_WRITE_GRAN / 8]; + size_t align_data_size = sizeof(align_data); +#else + /* For compatibility with C89 */ + uint8_t align_data_u8, *align_data = &align_data_u8; + size_t align_data_size = 1; +#endif + + memset(align_data, FDB_BYTE_ERASED, align_data_size); + if(FDB_WG_ALIGN_DOWN(size) > 0) { + result = _fdb_flash_write(db, addr, buf, FDB_WG_ALIGN_DOWN(size), false); + } + + align_remain = size - FDB_WG_ALIGN_DOWN(size); + if (result == FDB_NO_ERR && align_remain) { + memcpy(align_data, (uint8_t *) buf + FDB_WG_ALIGN_DOWN(size), align_remain); + result = _fdb_flash_write(db, addr + FDB_WG_ALIGN_DOWN(size), (uint32_t *) align_data, + align_data_size, false); + } + + return result; +} \ No newline at end of file