test/flash_tlv: add context argument to hal_flash_sector_t interface

This commit is contained in:
Matthias Ringwald 2017-06-04 16:37:09 +02:00
parent 16b4f22c82
commit 6705d5660b
4 changed files with 58 additions and 51 deletions

View File

@ -52,7 +52,9 @@ static const char * btstack_tlv_header_magic = "BTstack";
// globals // globals
static int btstack_tlv_current_bank; static int btstack_tlv_current_bank;
static int btstack_tlv_write_offset; static int btstack_tlv_write_offset;
static const hal_flash_sector_t * hal_flash_sector; static const hal_flash_sector_t * hal_flash_sector_impl;
static void * hal_flash_sector_context;
// TLV Iterator // TLV Iterator
typedef struct { typedef struct {
@ -64,7 +66,7 @@ typedef struct {
static void tlv_iterator_fetch_tag_len(tlv_iterator_t * it){ static void tlv_iterator_fetch_tag_len(tlv_iterator_t * it){
uint8_t entry[8]; uint8_t entry[8];
hal_flash_sector->read(it->bank, it->offset, entry, 8); hal_flash_sector_impl->read(hal_flash_sector_context, it->bank, it->offset, entry, 8);
it->tag = big_endian_read_32(entry, 0); it->tag = big_endian_read_32(entry, 0);
it->len = big_endian_read_32(entry, 4); it->len = big_endian_read_32(entry, 4);
} }
@ -78,7 +80,7 @@ static void tlv_iterator_init(tlv_iterator_t * it, int bank){
static int tlv_iterator_has_next(tlv_iterator_t * it){ static int tlv_iterator_has_next(tlv_iterator_t * it){
if (it->tag == 0xffffffff) return 0; if (it->tag == 0xffffffff) return 0;
return it->offset + 8 + it->len < hal_flash_sector->get_size(); return it->offset + 8 + it->len < hal_flash_sector_impl->get_size(hal_flash_sector_context);
} }
static void tlv_iterator_fetch_next(tlv_iterator_t * it){ static void tlv_iterator_fetch_next(tlv_iterator_t * it){
@ -91,8 +93,8 @@ static void tlv_iterator_fetch_next(tlv_iterator_t * it){
static int btstack_tlv_get_latest_bank(void){ static int btstack_tlv_get_latest_bank(void){
uint8_t header0[BTSTACK_TLV_HEADER_LEN]; uint8_t header0[BTSTACK_TLV_HEADER_LEN];
uint8_t header1[BTSTACK_TLV_HEADER_LEN]; uint8_t header1[BTSTACK_TLV_HEADER_LEN];
hal_flash_sector->read(0, 0, &header0[0], BTSTACK_TLV_HEADER_LEN); hal_flash_sector_impl->read(hal_flash_sector_context, 0, 0, &header0[0], BTSTACK_TLV_HEADER_LEN);
hal_flash_sector->read(1, 0, &header1[0], BTSTACK_TLV_HEADER_LEN); hal_flash_sector_impl->read(hal_flash_sector_context, 1, 0, &header1[0], BTSTACK_TLV_HEADER_LEN);
int valid0 = memcmp(header1, btstack_tlv_header_magic, BTSTACK_TLV_HEADER_LEN-1) == 0; int valid0 = memcmp(header1, btstack_tlv_header_magic, BTSTACK_TLV_HEADER_LEN-1) == 0;
int valid1 = memcmp(header1, btstack_tlv_header_magic, BTSTACK_TLV_HEADER_LEN-1) == 0; int valid1 = memcmp(header1, btstack_tlv_header_magic, BTSTACK_TLV_HEADER_LEN-1) == 0;
if (!valid0 && !valid1) return -1; if (!valid0 && !valid1) return -1;
@ -109,14 +111,14 @@ static void btstack_tlv_write_header(int bank, int epoch){
uint8_t header[BTSTACK_TLV_HEADER_LEN]; uint8_t header[BTSTACK_TLV_HEADER_LEN];
memcpy(&header[0], btstack_tlv_header_magic, BTSTACK_TLV_HEADER_LEN-1); memcpy(&header[0], btstack_tlv_header_magic, BTSTACK_TLV_HEADER_LEN-1);
header[BTSTACK_TLV_HEADER_LEN-1] = epoch; header[BTSTACK_TLV_HEADER_LEN-1] = epoch;
hal_flash_sector->write(bank, 0, header, BTSTACK_TLV_HEADER_LEN); hal_flash_sector_impl->write(hal_flash_sector_context, bank, 0, header, BTSTACK_TLV_HEADER_LEN);
} }
static void btstack_tlv_migrate(void){ static void btstack_tlv_migrate(void){
int next_bank = 1 - btstack_tlv_current_bank; int next_bank = 1 - btstack_tlv_current_bank;
// @TODO erase might not be needed - resp. already been performed // @TODO erase might not be needed - resp. already been performed
hal_flash_sector->erase(next_bank); hal_flash_sector_impl->erase(hal_flash_sector_context, next_bank);
int next_write_pos = 8; int next_write_pos = 8;
tlv_iterator_t it; tlv_iterator_t it;
@ -157,8 +159,8 @@ static void btstack_tlv_migrate(void){
uint8_t copy_buffer[32]; uint8_t copy_buffer[32];
while (bytes_to_copy){ while (bytes_to_copy){
int bytes_this_iteration = btstack_min(bytes_to_copy, sizeof(copy_buffer)); int bytes_this_iteration = btstack_min(bytes_to_copy, sizeof(copy_buffer));
hal_flash_sector->read(btstack_tlv_current_bank, tag_index, copy_buffer, bytes_this_iteration); hal_flash_sector_impl->read(hal_flash_sector_context, btstack_tlv_current_bank, tag_index, copy_buffer, bytes_this_iteration);
hal_flash_sector->write(next_bank, next_write_pos, copy_buffer, bytes_this_iteration); hal_flash_sector_impl->write(hal_flash_sector_context, next_bank, next_write_pos, copy_buffer, bytes_this_iteration);
tag_index += bytes_this_iteration; tag_index += bytes_this_iteration;
next_write_pos += bytes_this_iteration; next_write_pos += bytes_this_iteration;
bytes_to_copy -= bytes_this_iteration; bytes_to_copy -= bytes_this_iteration;
@ -169,7 +171,7 @@ static void btstack_tlv_migrate(void){
// prepare new one // prepare new one
uint8_t epoch_buffer; uint8_t epoch_buffer;
hal_flash_sector->read(btstack_tlv_current_bank, BTSTACK_TLV_HEADER_LEN-1, &epoch_buffer, 1); hal_flash_sector_impl->read(hal_flash_sector_context, btstack_tlv_current_bank, BTSTACK_TLV_HEADER_LEN-1, &epoch_buffer, 1);
btstack_tlv_write_header(next_bank, (epoch_buffer + 1) & 3); btstack_tlv_write_header(next_bank, (epoch_buffer + 1) & 3);
btstack_tlv_current_bank = next_bank; btstack_tlv_current_bank = next_bank;
btstack_tlv_write_offset = next_write_pos; btstack_tlv_write_offset = next_write_pos;
@ -178,9 +180,9 @@ static void btstack_tlv_migrate(void){
/** /**
* Init Tag Length Value Store * Init Tag Length Value Store
*/ */
void btstack_tlv_init(const hal_flash_sector_t * hal_flash_sector_impl){ void btstack_tlv_init(const hal_flash_sector_t * hal_flash_sector){
hal_flash_sector = hal_flash_sector_impl; hal_flash_sector_impl = hal_flash_sector;
// find current bank and erase both if none found // find current bank and erase both if none found
int current_bank = btstack_tlv_get_latest_bank(); int current_bank = btstack_tlv_get_latest_bank();
@ -188,8 +190,8 @@ void btstack_tlv_init(const hal_flash_sector_t * hal_flash_sector_impl){
if (current_bank < 0){ if (current_bank < 0){
log_info("erase both banks"); log_info("erase both banks");
// erase both to get into stable state // erase both to get into stable state
hal_flash_sector->erase(0); hal_flash_sector_impl->erase(hal_flash_sector_context, 0);
hal_flash_sector->erase(1); hal_flash_sector_impl->erase(hal_flash_sector_context, 1);
current_bank = 0; current_bank = 0;
btstack_tlv_write_header(current_bank, 0); // epoch = 0; btstack_tlv_write_header(current_bank, 0); // epoch = 0;
} }
@ -228,7 +230,7 @@ int btstack_tlv_get_tag(uint32_t tag, uint8_t * buffer, uint32_t buffer_size){
if (tag_index == 0) return 0; if (tag_index == 0) return 0;
if (!buffer) return tag_len; if (!buffer) return tag_len;
int copy_size = btstack_min(buffer_size, tag_len); int copy_size = btstack_min(buffer_size, tag_len);
hal_flash_sector->read(btstack_tlv_current_bank, tag_index + 8, buffer, copy_size); hal_flash_sector_impl->read(hal_flash_sector_context, btstack_tlv_current_bank, tag_index + 8, buffer, copy_size);
return copy_size; return copy_size;
} }
@ -239,7 +241,7 @@ int btstack_tlv_get_tag(uint32_t tag, uint8_t * buffer, uint32_t buffer_size){
* @param data_size * @param data_size
*/ */
void btstack_tlv_store_tag(uint32_t tag, const uint8_t * data, uint32_t data_size){ void btstack_tlv_store_tag(uint32_t tag, const uint8_t * data, uint32_t data_size){
if (btstack_tlv_write_offset + 8 + data_size > hal_flash_sector->get_size()){ if (btstack_tlv_write_offset + 8 + data_size > hal_flash_sector_impl->get_size(hal_flash_sector_context)){
btstack_tlv_migrate(); btstack_tlv_migrate();
} }
// prepare entry // prepare entry
@ -250,10 +252,10 @@ void btstack_tlv_store_tag(uint32_t tag, const uint8_t * data, uint32_t data_siz
log_info("write '%x', len %u at %u", tag, data_size, btstack_tlv_write_offset); log_info("write '%x', len %u at %u", tag, data_size, btstack_tlv_write_offset);
// write value first // write value first
hal_flash_sector->write(btstack_tlv_current_bank, btstack_tlv_write_offset + 8, data, data_size); hal_flash_sector_impl->write(hal_flash_sector_context, btstack_tlv_current_bank, btstack_tlv_write_offset + 8, data, data_size);
// then entry // then entry
hal_flash_sector->write(btstack_tlv_current_bank, btstack_tlv_write_offset, entry, sizeof(entry)); hal_flash_sector_impl->write(hal_flash_sector_context, btstack_tlv_current_bank, btstack_tlv_write_offset, entry, sizeof(entry));
btstack_tlv_write_offset += sizeof(entry) + data_size; btstack_tlv_write_offset += sizeof(entry) + data_size;
} }

View File

@ -53,31 +53,34 @@ typedef struct {
/** /**
* Get size of flash banks * Get size of flash banks
*/ */
uint32_t (*get_size)(void); uint32_t (*get_size)(void * context);
/** /**
* Erase a bank * Erase a bank
* @param context
* @param bank * @param bank
*/ */
void (*erase)(int bank); void (*erase)(void * context, int bank);
/** /**
* Read from flash into provided buffer * Read from flash into provided buffer
* @param context
* @param bank * @param bank
* @param offset into flash bank * @param offset into flash bank
* @param buffer to read data * @param buffer to read data
* @param size of data to read * @param size of data to read
*/ */
void (*read)(int bank, uint32_t offset, uint8_t * buffer, uint32_t size); void (*read)(void * context, int bank, uint32_t offset, uint8_t * buffer, uint32_t size);
/** /**
* Write data into flash. Each offset can only be written once after bank was erased * Write data into flash. Each offset can only be written once after bank was erased
* @param context
* @param bank * @param bank
* @param offset into flash bank * @param offset into flash bank
to read data to read data
* @param size of data to store * @param size of data to store
*/ */
void (*write)(int bank, uint32_t offset, const uint8_t * data, uint32_t size); void (*write)(void * context, int bank, uint32_t offset, const uint8_t * data, uint32_t size);
} hal_flash_sector_t; } hal_flash_sector_t;

View File

@ -53,16 +53,16 @@ static uint8_t hal_flash_storage_bank_1[HAL_FLASH_SECTOR_SIZE];
static uint8_t hal_flash_storage_bank_2[HAL_FLASH_SECTOR_SIZE]; static uint8_t hal_flash_storage_bank_2[HAL_FLASH_SECTOR_SIZE];
static uint8_t * hal_flash_storage_banks[] = {hal_flash_storage_bank_1, hal_flash_storage_bank_2}; static uint8_t * hal_flash_storage_banks[] = {hal_flash_storage_bank_1, hal_flash_storage_bank_2};
static uint32_t hal_flash_sector_memory_get_size(void){ static uint32_t hal_flash_sector_memory_get_size(void * context){
return HAL_FLASH_SECTOR_SIZE; return HAL_FLASH_SECTOR_SIZE;
} }
static void hal_flash_sector_memory_erase(int bank){ static void hal_flash_sector_memory_erase(void * context, int bank){
if (bank > 1) return; if (bank > 1) return;
memset(hal_flash_storage_banks[bank], 0xff, HAL_FLASH_SECTOR_SIZE); memset(hal_flash_storage_banks[bank], 0xff, HAL_FLASH_SECTOR_SIZE);
} }
static void hal_flash_sector_memory_read(int bank, uint32_t offset, uint8_t * buffer, uint32_t size){ static void hal_flash_sector_memory_read(void * context, int bank, uint32_t offset, uint8_t * buffer, uint32_t size){
// log_info("read offset %u, len %u", offset, size); // log_info("read offset %u, len %u", offset, size);
@ -73,7 +73,7 @@ static void hal_flash_sector_memory_read(int bank, uint32_t offset, uint8_t * bu
memcpy(buffer, &hal_flash_storage_banks[bank][offset], size); memcpy(buffer, &hal_flash_storage_banks[bank][offset], size);
} }
static void hal_flash_sector_memory_write(int bank, uint32_t offset, const uint8_t * data, uint32_t size){ static void hal_flash_sector_memory_write(void * context, int bank, uint32_t offset, const uint8_t * data, uint32_t size){
// log_info("write offset %u, len %u", offset, size); // log_info("write offset %u, len %u", offset, size);

View File

@ -8,11 +8,12 @@
#include "hci_dump.h" #include "hci_dump.h"
TEST_GROUP(HAL_FLASH_SECTOR){ TEST_GROUP(HAL_FLASH_SECTOR){
const hal_flash_sector_t * hal_flash_sector; const hal_flash_sector_t * hal_flash_sector_impl;
void * hal_flash_sector_context;
void setup(void){ void setup(void){
hal_flash_sector = hal_flash_sector_memory_get_instance(); hal_flash_sector_impl = hal_flash_sector_memory_get_instance();
hal_flash_sector->erase(0); hal_flash_sector_impl->erase(hal_flash_sector_context, 0);
hal_flash_sector->erase(1); hal_flash_sector_impl->erase(hal_flash_sector_context, 1);
} }
}; };
@ -23,7 +24,7 @@ TEST(HAL_FLASH_SECTOR, TestErased){
for (i=0;i<sizeof(offsets)/sizeof(int);i++){ for (i=0;i<sizeof(offsets)/sizeof(int);i++){
int bank; int bank;
for (bank=0;bank<2;bank++){ for (bank=0;bank<2;bank++){
hal_flash_sector->read(bank, offsets[i], &buffer, 1); hal_flash_sector_impl->read(hal_flash_sector_context, bank, offsets[i], &buffer, 1);
CHECK_EQUAL(buffer, 0xff); CHECK_EQUAL(buffer, 0xff);
} }
} }
@ -37,13 +38,13 @@ TEST(HAL_FLASH_SECTOR, TestWrite){
int bank; int bank;
for (bank=0;bank<2;bank++){ for (bank=0;bank<2;bank++){
buffer = i; buffer = i;
hal_flash_sector->write(bank, offsets[i], &buffer, 1); hal_flash_sector_impl->write(hal_flash_sector_context, bank, offsets[i], &buffer, 1);
} }
} }
for (i=0;i<sizeof(offsets)/sizeof(int);i++){ for (i=0;i<sizeof(offsets)/sizeof(int);i++){
int bank; int bank;
for (bank=0;bank<2;bank++){ for (bank=0;bank<2;bank++){
hal_flash_sector->read(bank, offsets[i], &buffer, 1); hal_flash_sector_impl->read(hal_flash_sector_context, bank, offsets[i], &buffer, 1);
CHECK_EQUAL(buffer, i); CHECK_EQUAL(buffer, i);
} }
} }
@ -53,8 +54,8 @@ TEST(HAL_FLASH_SECTOR, TestWrite){
// prints error and exits tests. maybe all functions need to return ok // prints error and exits tests. maybe all functions need to return ok
TEST(HAL_FLASH_SECTOR, TestWriteTwice){ TEST(HAL_FLASH_SECTOR, TestWriteTwice){
uint8_t buffer = 5; uint8_t buffer = 5;
hal_flash_sector->write(0, 5, &buffer, 1); hal_flash_sector_impl->write(hal_flash_sector_context, 0, 5, &buffer, 1);
hal_flash_sector->write(0, 5, &buffer, 1); hal_flash_sector_impl->write(hal_flash_sector_context, 0, 5, &buffer, 1);
} }
#endif #endif
@ -62,32 +63,33 @@ TEST(HAL_FLASH_SECTOR, TestWriteErase){
uint32_t offset = 7; uint32_t offset = 7;
uint8_t value = 9; uint8_t value = 9;
uint8_t buffer = value; uint8_t buffer = value;
hal_flash_sector->write(0, offset, &buffer, 1); hal_flash_sector_impl->write(hal_flash_sector_context, 0, offset, &buffer, 1);
hal_flash_sector->read(0, offset, &buffer, 1); hal_flash_sector_impl->read(hal_flash_sector_context, 0, offset, &buffer, 1);
CHECK_EQUAL(buffer, value); CHECK_EQUAL(buffer, value);
hal_flash_sector->erase(0); hal_flash_sector_impl->erase(hal_flash_sector_context, 0);
hal_flash_sector->read(0, offset, &buffer, 1); hal_flash_sector_impl->read(hal_flash_sector_context, 0, offset, &buffer, 1);
CHECK_EQUAL(buffer, 0xff); CHECK_EQUAL(buffer, 0xff);
} }
TEST_GROUP(BSTACK_TLV){ TEST_GROUP(BSTACK_TLV){
const hal_flash_sector_t * hal_flash_sector; const hal_flash_sector_t * hal_flash_sector_impl;
void * hal_flash_sector_context;
void setup(void){ void setup(void){
hal_flash_sector = hal_flash_sector_memory_get_instance(); hal_flash_sector_impl = hal_flash_sector_memory_get_instance();
hal_flash_sector->erase(0); hal_flash_sector_impl->erase(hal_flash_sector_context, 0);
hal_flash_sector->erase(1); hal_flash_sector_impl->erase(hal_flash_sector_context, 1);
} }
}; };
TEST(BSTACK_TLV, TestMissingTag){ TEST(BSTACK_TLV, TestMissingTag){
btstack_tlv_init(hal_flash_sector); btstack_tlv_init(hal_flash_sector_impl);
uint32_t tag = 'abcd'; uint32_t tag = 'abcd';
int size = btstack_tlv_get_tag(tag, NULL, 0); int size = btstack_tlv_get_tag(tag, NULL, 0);
CHECK_EQUAL(size, 0); CHECK_EQUAL(size, 0);
} }
TEST(BSTACK_TLV, TestWriteRead){ TEST(BSTACK_TLV, TestWriteRead){
btstack_tlv_init(hal_flash_sector); btstack_tlv_init(hal_flash_sector_impl);
uint32_t tag = 'abcd'; uint32_t tag = 'abcd';
uint8_t data = 7; uint8_t data = 7;
uint8_t buffer = data; uint8_t buffer = data;
@ -99,7 +101,7 @@ TEST(BSTACK_TLV, TestWriteRead){
} }
TEST(BSTACK_TLV, TestWriteWriteRead){ TEST(BSTACK_TLV, TestWriteWriteRead){
btstack_tlv_init(hal_flash_sector); btstack_tlv_init(hal_flash_sector_impl);
uint32_t tag = 'abcd'; uint32_t tag = 'abcd';
uint8_t data = 7; uint8_t data = 7;
uint8_t buffer = data; uint8_t buffer = data;
@ -114,7 +116,7 @@ TEST(BSTACK_TLV, TestWriteWriteRead){
} }
TEST(BSTACK_TLV, TestWriteDeleteRead){ TEST(BSTACK_TLV, TestWriteDeleteRead){
btstack_tlv_init(hal_flash_sector); btstack_tlv_init(hal_flash_sector_impl);
uint32_t tag = 'abcd'; uint32_t tag = 'abcd';
uint8_t data = 7; uint8_t data = 7;
uint8_t buffer = data; uint8_t buffer = data;
@ -129,7 +131,7 @@ TEST(BSTACK_TLV, TestWriteDeleteRead){
TEST(BSTACK_TLV, TestMigrate){ TEST(BSTACK_TLV, TestMigrate){
btstack_tlv_init(hal_flash_sector); btstack_tlv_init(hal_flash_sector_impl);
uint32_t tag = 'abcd'; uint32_t tag = 'abcd';
uint8_t data[8]; uint8_t data[8];
@ -142,7 +144,7 @@ TEST(BSTACK_TLV, TestMigrate){
btstack_tlv_store_tag(tag, &data[0], 8); btstack_tlv_store_tag(tag, &data[0], 8);
} }
btstack_tlv_init(hal_flash_sector); btstack_tlv_init(hal_flash_sector_impl);
uint8_t buffer[8]; uint8_t buffer[8];
btstack_tlv_get_tag(tag, &buffer[0], 1); btstack_tlv_get_tag(tag, &buffer[0], 1);
@ -151,7 +153,7 @@ TEST(BSTACK_TLV, TestMigrate){
TEST(BSTACK_TLV, TestMigrate2){ TEST(BSTACK_TLV, TestMigrate2){
btstack_tlv_init(hal_flash_sector); btstack_tlv_init(hal_flash_sector_impl);
uint32_t tag1 = 0x11223344; uint32_t tag1 = 0x11223344;
uint32_t tag2 = 0x44556677; uint32_t tag2 = 0x44556677;
@ -169,7 +171,7 @@ TEST(BSTACK_TLV, TestMigrate2){
btstack_tlv_store_tag(tag2, data2, 8); btstack_tlv_store_tag(tag2, data2, 8);
} }
btstack_tlv_init(hal_flash_sector); btstack_tlv_init(hal_flash_sector_impl);
uint8_t buffer[8]; uint8_t buffer[8];
btstack_tlv_get_tag(tag1, &buffer[0], 1); btstack_tlv_get_tag(tag1, &buffer[0], 1);