Skip to content

Commit 86640e5

Browse files
Jammu KekkonenVeijo Pesonen
authored andcommitted
Bugfix: won't rely on erase value to detect is a sector erased
When flashing a binary STLink won't skip writing padding which happens to be the same value as flash's erase value. STM32L4 based targets have an additional 8-bit of embedded ECC for each 64-bit word of data. The initial value, when a sector is erased, for the ECC bits is 0xFF. When you write the erase value to a given address these bits gets modified to something different due to the ECC algoritm in use. The visible bits are intact but difference in ECC value prevents flipping any 1's to 0's. Only way to proceed is to erase the whole sector.
1 parent 7e179f5 commit 86640e5

File tree

1 file changed

+5
-19
lines changed

1 file changed

+5
-19
lines changed

features/storage/kvstore/tdbstore/TDBStore.cpp

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,7 @@ int TDBStore::erase_erase_unit(uint8_t area, uint32_t offset)
167167
uint32_t bd_offset = _area_params[area].address + offset;
168168
uint32_t eu_size = _buff_bd->get_erase_size(bd_offset);
169169

170-
int os_ret = _buff_bd->erase(bd_offset, eu_size);
171-
if (os_ret) {
172-
return MBED_ERROR_WRITE_FAILED;
173-
}
174-
return MBED_SUCCESS;
170+
return _buff_bd->erase(bd_offset, eu_size);
175171
}
176172

177173
void TDBStore::calc_area_params()
@@ -1498,29 +1494,19 @@ int TDBStore::is_erase_unit_erased(uint8_t area, uint32_t offset, bool &erased)
14981494
int TDBStore::check_erase_before_write(uint8_t area, uint32_t offset, uint32_t size, bool force_check)
14991495
{
15001496
// In order to save init time, we don't check that the entire area is erased.
1501-
// Instead, whenever reaching an erase unit start, check that it's erased, and if not -
1502-
// erase it.
1497+
// Instead, whenever reaching an erase unit start erase it.
15031498

15041499
while (size) {
15051500
uint32_t dist, offset_from_start;
15061501
int ret;
15071502
offset_in_erase_unit(area, offset, offset_from_start, dist);
15081503
uint32_t chunk = std::min(size, dist);
15091504

1510-
if (!offset_from_start || force_check) {
1511-
// We're at the start of an erase unit. Here (and only here, if not forced),
1512-
// check if it's erased.
1513-
bool erased;
1514-
ret = is_erase_unit_erased(area, offset, erased);
1515-
if (ret) {
1505+
if (offset_from_start == 0 || force_check) {
1506+
ret = erase_erase_unit(area, offset - offset_from_start);
1507+
if (ret != MBED_SUCCESS) {
15161508
return MBED_ERROR_WRITE_FAILED;
15171509
}
1518-
if (!erased) {
1519-
ret = erase_erase_unit(area, offset - offset_from_start);
1520-
if (ret) {
1521-
return MBED_ERROR_WRITE_FAILED;
1522-
}
1523-
}
15241510
}
15251511
offset += chunk;
15261512
size -= chunk;

0 commit comments

Comments
 (0)