Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TDBStore refactoring #11987

Merged
merged 8 commits into from
Dec 4, 2019
Merged

TDBStore refactoring #11987

merged 8 commits into from
Dec 4, 2019

Conversation

SeppoTakalo
Copy link
Contributor

Description

Summary of change

Small fixes, refactoring and one functionality change to TDBStore:

  • TDBStore: Don't copy more data than what we can hold
  • TDBStore: Move Assert to init(), so Block parameter are initialised correctly
  • Do not require Flash device for TDBStore <-- Functional change, but not API change
  • TDBStore: Do no garbage_collect() on init()
  • TDBStore: Keep copy of reserved data on both areas.
  • TDBStore: Erase one program unit more, when cleaning areas

Assuming underlying device was FLASH device was error prone, as we cannot trust erase values. Logic has changed to that we always erase before writing to new area.

Documentation

We can remove then requirements from documentation that TDBStore would require FLASH device. After these changes, it does not anymore.

More module+unit tests have been implemented but can only be submitted once Mbed CRC changes are submitted into master.


Pull request type

[] Patch update (Bug fix / Target update / Docs update / Test update / Refactor)
[X] Feature update (New feature / Functionality change / New API)
[] Major update (Breaking change E.g. Return code change / API behaviour change)

Test results

[] No Tests required for this change (E.g docs only update)
[X] Covered by existing mbed-os tests (Greentea or Unittest)
[] Tests / results supplied as part of this PR

Reviewers

@VeijoPesonen


Release Notes

Summary of changes

TDBStore does not anymore require Flash based block device.

Impact of changes

Migration actions required

Copy link
Contributor

@VeijoPesonen VeijoPesonen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@mbed-ci
Copy link

mbed-ci commented Nov 29, 2019

Test run: FAILED

Summary: 1 of 11 test jobs failed
Build number : 1
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_greentea-test

@ciarmcom ciarmcom requested review from VeijoPesonen and a team November 29, 2019 12:00
@ciarmcom
Copy link
Member

@SeppoTakalo, thank you for your changes.
@VeijoPesonen @ARMmbed/mbed-os-storage @ARMmbed/mbed-os-maintainers please review.

Seppo Takalo added 8 commits December 3, 2019 14:38
Change the "reserved data" logic so that every time we erase and area,
the content of reserved data is then immediately copied to newly erased
area. This keeps two copies of the data.
When data is requested, return only if checksum is matching.
When data is written, only allow if BOTH checksums are incorrect, meaning
that areas are either corrupted or erased.
Only exception is TDBStore::reset() which erases all keys and reserved data.

Removed all logic that tried to detect, if reserved are was erased or
corrupted. Rely entirely on checksum.

Add moduletest for reserved data.
Previous logic caused garbage collection to kick in, if the init() was
called on empty storage. This has effect of erasing areas twice, if both
areas were empty.

Re-write logic so that we erase areas only on garbage_collect() or reset().
The init() logic already chooses the active area, so no need to touch,
until keys are modified.

Removed also the is_erase_unit_erased() as this is working only on
FLASH devices, and TDBStore should be refactored to work on all storages.
TDBStore used to rely on Flash devices erase value.
This logic has been removed, and TDBStore can do the entire erase
logic itself, in case the given BlockDevice does not offer erase().
This relies on BlockDevice to properly return -1 in BlockDevice::get_erase_value().
@SeppoTakalo SeppoTakalo force-pushed the feature_tdbstore_refactoring branch from e79de64 to ce7b196 Compare December 3, 2019 13:22
@SeppoTakalo
Copy link
Contributor Author

Cherry-picked two commits from #11986 which should also fix the failing test case here.

Rebased and started a test run.

@0xc0170 0xc0170 added needs: CI release-version: 6.0.0-alpha-1 First pre-release version of 6.0.0 and removed needs: review labels Dec 3, 2019
@mbed-ci
Copy link

mbed-ci commented Dec 3, 2019

Test run: FAILED

Summary: 1 of 11 test jobs failed
Build number : 2
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_greentea-test

@SeppoTakalo
Copy link
Contributor Author

Failed test NUCLEO_F429ZI IAR / tests-netsocket-tls – NUCLEO_F429ZI-IAR.tests-netsocket-tls looks unrelated.

@0xc0170
Copy link
Contributor

0xc0170 commented Dec 4, 2019

@SeppoTakalo You could have just restarted greentea test (exporters, test after build OK can be restarted separately), all restarted is also fine.

Copy link
Contributor

@VeijoPesonen VeijoPesonen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@mbed-ci
Copy link

mbed-ci commented Dec 4, 2019

Test run: FAILED

Summary: 1 of 11 test jobs failed
Build number : 3
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_greentea-test

@SeppoTakalo
Copy link
Contributor Author

@VeliMattiLahtela Any idea why TCP tests on F429ZI are now failing?

@0xc0170 0xc0170 removed the needs: CI label Dec 4, 2019
@0xc0170
Copy link
Contributor

0xc0170 commented Dec 4, 2019

Looks like network problem as all failed on the first run, second run is all good

@0xc0170 0xc0170 merged commit 7a085b4 into master Dec 4, 2019
@SeppoTakalo
Copy link
Contributor Author

Yes, verified from CI room that ethernet cable was unplugged.

@SeppoTakalo SeppoTakalo deleted the feature_tdbstore_refactoring branch December 4, 2019 12:52
JanneKiiskila pushed a commit to JanneKiiskila/mbed-os that referenced this pull request Oct 29, 2020
Copy over the TDBStore.cpp|.h as they contain a few bug fixes which we seem
to be needing (in some corner cases). The files are copied over from Mbed OS master
at the tip of master as of today, hash pointing at 2f87d59.

This brings in a number of changes, but primarily we are interested in this:
ARMmbed#11987

Device 943 ended up in a state, where it would not boot up and in the debug
image I was able to spot it died in the TDBStore.cpp,

00> ++ MbedOS Error Info ++
00> Error Status: 0x80FF011B Code: 283 Module: 255
00> Error Message: TDBSTORE: Unable to build RAM table at init
00> Location: 0x71347
00> Error Value: 0x0
00> Current Thread: main Id: 0x20012C68 Entry: 0x7482F StackSize: 0x1400 StackMem: 0x200168E8 SP: 0x20017AEC
00> For more info, visit: https://mbed.com/s/error?error=0x80FF011B&tgt=EPEN3

This is due to corrupted QSPIF. This should prevent that from happening or at least
recover from it in a more sensible way, as it will not "guess if it's been erased or not",
but more deterministily just erase properly.

Device was recoverable even with existing SW by forcing an erase in the error branch,
patch below:

--- start of patch:

```
diff --git i/features/storage/kvstore/tdbstore/TDBStore.cpp w/features/storage/kvstore/tdbstore/TDBStore.cpp
index efeedf42c2..701ce7d044 100644
--- i/features/storage/kvstore/tdbstore/TDBStore.cpp
+++ w/features/storage/kvstore/tdbstore/TDBStore.cpp
@@ -1027,6 +1027,7 @@ int TDBStore::init()
     }

 #endif
+    printf("_bd.type == %s\n", _bd->get_type());

     _max_keys = initial_max_keys;

@@ -1097,6 +1098,7 @@ int TDBStore::init()

     // In case we have two empty areas, arbitrarily use area 0 as the active one.
     if ((area_state[0] == TDBSTORE_AREA_STATE_EMPTY) && (area_state[1] == TDBSTORE_AREA_STATE_EMPTY)) {
+        printf("active area = 0\n");
         _active_area = 0;
         _active_area_version = 1;
         ret = write_master_record(_active_area, _active_area_version, _free_space_offset); @@ -1115,6 +1117,7 @@ int TDBStore::init()
         } else {
             _active_area = 1;
         }
+        printf("active area = %d\n", _active_area);
         _active_area_version = versions[_active_area];
         ret = reset_area(1 - _active_area);
         if (ret) {
@@ -1128,6 +1131,11 @@ int TDBStore::init()
     ret = build_ram_table();

     if ((ret != MBED_SUCCESS) && (ret != MBED_ERROR_INVALID_DATA_DETECTED)) {
+        printf("TDBSTORE: Unable to build RAM table at init - try erase area!");
+        ret = reset_area(0);
+        printf("reset_area(0))=%d\n", ret);
+        ret = reset_area(1);
+        printf("reset_area(1))=%d\n", ret);
         MBED_ERROR(ret, "TDBSTORE: Unable to build RAM table at init");
     }

@@ -1159,6 +1167,7 @@ int TDBStore::init()
     }

 end:
+    printf("TDBStore init() done for %s\n", _bd->get_type());
     _is_initialized = true;
     _mutex.unlock();
     return ret;
```
--- end of patch
LDong-Arm added a commit to LDong-Arm/mbed-os-5-docs that referenced this pull request Dec 7, 2020
Since ARMmbed/mbed-os#11987 was merged
to Mbed OS, a flash device or a simulated flash device is no
longer a requirement.
@JanneKiiskila
Copy link
Contributor

@0xc0170 @adbridge - could this patch be ported to a 5.15.x release?

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 24, 2022

@0xc0170 @adbridge - could this patch be ported to a 5.15.x release?

We are not able to port this feature request to 5.15 branch. If it's required (not certain which parts are, as this pull request includes multiple changes), it needs to be contributed.

@JanneKiiskila
Copy link
Contributor

This is not just a feature request, this is actually a bug fix in many respects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release-version: 6.0.0-alpha-1 First pre-release version of 6.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants