TDBStore: Handle odd number of sectors in block

Rework TDBStore::calc_area_params so that it can handle situations where
the block device size is not an even multiple of the sector size (while
retaining its ability to handle non-uniform erase sizes).
This avoids intermittent asserts on boards where TDBStore is implemented
in internal flash, in which case the size of the block device varies
with the application size and a minor change (or a shift in optimization
level) can shift TDBStore from an odd to an even number of sectors.
pull/12799/head
Kyle Kearney 2020-04-08 16:42:46 -07:00
parent 7fce7f552c
commit b46da65937
1 changed files with 22 additions and 3 deletions

View File

@ -200,16 +200,35 @@ void TDBStore::calc_area_params()
memset(_area_params, 0, sizeof(_area_params));
size_t area_0_size = 0;
size_t area_1_size = 0;
while (area_0_size < bd_size / 2) {
// The size calculations are a bit complex because we need to make sure we're
// always aligned to an erase block boundary (whose size may not be uniform
// across the address space), and we also need to make sure that the first
// area never goes over half of the total size even if bd_size is an odd
// number of sectors.
while (true) {
bd_size_t erase_unit_size = _bd->get_erase_size(area_0_size);
area_0_size += erase_unit_size;
if (area_0_size + erase_unit_size <= (bd_size / 2)) {
area_0_size += erase_unit_size;
} else {
break;
}
}
while (true) {
bd_size_t erase_unit_size = _bd->get_erase_size(area_0_size + area_1_size);
if (area_1_size + erase_unit_size <= (bd_size / 2)) {
area_1_size += erase_unit_size;
} else {
break;
}
}
_area_params[0].address = 0;
_area_params[0].size = area_0_size;
_area_params[1].address = area_0_size;
_area_params[1].size = bd_size - area_0_size;
_area_params[1].size = area_1_size;
// The areas must be of same size
MBED_ASSERT(_area_params[0].size == _area_params[1].size);