From 8aecaa9f0f44957eac4e72b14cfe0c8dbb121ee3 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Wed, 16 Aug 2017 14:53:22 +0200 Subject: [PATCH] btstack_tlv_flash_sector: trigger migration if Flash is not erased after last found tag --- platform/embedded/btstack_tlv_flash_sector.c | 29 ++++++++++++++------ test/flash_tlv/tlv_test.c | 15 ++++++++-- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/platform/embedded/btstack_tlv_flash_sector.c b/platform/embedded/btstack_tlv_flash_sector.c index 90a6e89ee..c1bc04f67 100644 --- a/platform/embedded/btstack_tlv_flash_sector.c +++ b/platform/embedded/btstack_tlv_flash_sector.c @@ -120,18 +120,22 @@ static void btstack_tlv_flash_sector_write_header(btstack_tlv_flash_sector_t * s } /** - * @brief Check if erased + * @brief Check if erased from offset */ -static int btstack_tlv_flash_sector_test_erased(btstack_tlv_flash_sector_t * self, int bank){ - uint32_t offset; +static int btstack_tlv_flash_sector_test_erased(btstack_tlv_flash_sector_t * self, int bank, uint32_t offset){ + log_info("test erased: bank %u, offset %u", bank, offset); uint32_t size = self->hal_flash_sector_impl->get_size(self->hal_flash_sector_context); uint8_t buffer[16]; uint8_t empty16[16]; memset(empty16, 0xff, sizeof(empty16)); - for (offset = 0 ; offset <= size ; offset += sizeof(empty16)){ + while (offset < size){ uint32_t copy_size = (offset + sizeof(empty16) < size) ? sizeof(empty16) : (size - offset); self->hal_flash_sector_impl->read(self->hal_flash_sector_context, bank, offset, buffer, copy_size); - if (memcmp(buffer, empty16, sizeof(empty16))) return 0; + if (memcmp(buffer, empty16, copy_size)) { + log_info("not erased %x - %x", offset, offset + copy_size); + return 0; + } + offset += copy_size; } return 1; } @@ -140,11 +144,11 @@ static int btstack_tlv_flash_sector_test_erased(btstack_tlv_flash_sector_t * sel * @brief erase bank (only if not already erased) */ static void btstack_tlv_flash_sector_erase_bank(btstack_tlv_flash_sector_t * self, int bank){ - if (btstack_tlv_flash_sector_test_erased(self, 0)){ + if (btstack_tlv_flash_sector_test_erased(self, bank, 0)){ log_info("bank %u already erased", bank); } else { log_info("bank %u not empty, erase bank", bank); - self->hal_flash_sector_impl->erase(self->hal_flash_sector_context, 0); + self->hal_flash_sector_impl->erase(self->hal_flash_sector_context, bank); } } @@ -323,16 +327,25 @@ const btstack_tlv_t * btstack_tlv_flash_sector_init_instance(btstack_tlv_flash_s self->write_offset = it.offset; if (self->write_offset < self->hal_flash_sector_impl->get_size(self->hal_flash_sector_context)){ + // delete older instances of last_tag // this handles the unlikely case where MCU did reset after new value + header was written but before delete did complete if (last_tag){ btstack_tlv_flash_sector_delete_tag_until_offset(self, last_tag, last_offset); } + + // verify that rest of bank is empty + // this handles the unlikely case where MCU did reset after new value was written, but not the tag + if (!btstack_tlv_flash_sector_test_erased(self, self->current_bank, self->write_offset)){ + log_info("Flash not empty after last found tag -> migrate"); + btstack_tlv_flash_sector_migrate(self); + } else { + log_info("Flash clean after last found tag"); + } } else { // failure! self->current_bank = -1; } - } if (self->current_bank < 0) { diff --git a/test/flash_tlv/tlv_test.c b/test/flash_tlv/tlv_test.c index 68b7a06d1..f5b22c709 100644 --- a/test/flash_tlv/tlv_test.c +++ b/test/flash_tlv/tlv_test.c @@ -93,7 +93,6 @@ TEST(HAL_FLASH_SECTOR, TestWriteErase){ } /// TLV - TEST_GROUP(BSTACK_TLV){ const hal_flash_sector_t * hal_flash_sector_impl; @@ -227,8 +226,20 @@ TEST(BSTACK_TLV, TestMigrate2){ CHECK_EQUAL(buffer[0], data2[0]); } -// +TEST(BSTACK_TLV, TestWriteResetRead){ + btstack_tlv_impl = btstack_tlv_flash_sector_init_instance(&btstack_tlv_context, hal_flash_sector_impl, &hal_flash_sector_context); + uint32_t tag = 'abcd'; + uint8_t data = 7; + uint8_t buffer = data; + btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); + btstack_tlv_impl = btstack_tlv_flash_sector_init_instance(&btstack_tlv_context, hal_flash_sector_impl, &hal_flash_sector_context); + int size = btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, NULL, 0); + CHECK_EQUAL(size, 1); + btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, &buffer, 1); + CHECK_EQUAL(buffer, data); +} +// TEST_GROUP(LINK_KEY_DB){ const hal_flash_sector_t * hal_flash_sector_impl; hal_flash_sector_memory_t hal_flash_sector_context;