Skip to content

Commit 10481f2

Browse files
BlockDevice: multiple fixes to BlockDevice classes
Incorrect addresses only cause error return values instead of assertion. ExhaustibleBlockDevice has working get/set_erase_cycle functions and an array preventing programming without erase. Fixed MBRBlockDevice partitioning function.
1 parent d847f9f commit 10481f2

File tree

7 files changed

+96
-28
lines changed

7 files changed

+96
-28
lines changed

features/storage/blockdevice/BufferedBlockDevice.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,14 @@ int BufferedBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
271271

272272
int BufferedBlockDevice::erase(bd_addr_t addr, bd_size_t size)
273273
{
274-
MBED_ASSERT(is_valid_erase(addr, size));
275274
if (!_is_initialized) {
276275
return BD_ERROR_DEVICE_ERROR;
277276
}
278277

278+
if (!is_valid_erase(addr, size)) {
279+
return BD_ERROR_DEVICE_ERROR;
280+
}
281+
279282
if ((_write_cache_addr >= addr) && (_write_cache_addr <= addr + size)) {
280283
invalidate_write_cache();
281284
}
@@ -284,11 +287,14 @@ int BufferedBlockDevice::erase(bd_addr_t addr, bd_size_t size)
284287

285288
int BufferedBlockDevice::trim(bd_addr_t addr, bd_size_t size)
286289
{
287-
MBED_ASSERT(is_valid_erase(addr, size));
288290
if (!_is_initialized) {
289291
return BD_ERROR_DEVICE_ERROR;
290292
}
291293

294+
if (!is_valid_erase(addr, size)) {
295+
return BD_ERROR_DEVICE_ERROR;
296+
}
297+
292298
if ((_write_cache_addr >= addr) && (_write_cache_addr <= addr + size)) {
293299
invalidate_write_cache();
294300
}

features/storage/blockdevice/ChainingBlockDevice.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,14 @@ int ChainingBlockDevice::sync()
138138

139139
int ChainingBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
140140
{
141-
MBED_ASSERT(is_valid_read(addr, size));
142141
if (!_is_initialized) {
143142
return BD_ERROR_DEVICE_ERROR;
144143
}
145144

145+
if (!is_valid_read(addr, size)) {
146+
return BD_ERROR_DEVICE_ERROR;
147+
}
148+
146149
uint8_t *buffer = static_cast<uint8_t *>(b);
147150

148151
// Find block devices containing blocks, may span multiple block devices
@@ -173,11 +176,14 @@ int ChainingBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
173176

174177
int ChainingBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
175178
{
176-
MBED_ASSERT(is_valid_program(addr, size));
177179
if (!_is_initialized) {
178180
return BD_ERROR_DEVICE_ERROR;
179181
}
180182

183+
if (!is_valid_program(addr, size)) {
184+
return BD_ERROR_DEVICE_ERROR;
185+
}
186+
181187
const uint8_t *buffer = static_cast<const uint8_t *>(b);
182188

183189
// Find block devices containing blocks, may span multiple block devices
@@ -208,11 +214,14 @@ int ChainingBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
208214

209215
int ChainingBlockDevice::erase(bd_addr_t addr, bd_size_t size)
210216
{
211-
MBED_ASSERT(is_valid_erase(addr, size));
212217
if (!_is_initialized) {
213218
return BD_ERROR_DEVICE_ERROR;
214219
}
215220

221+
if (!is_valid_erase(addr, size)) {
222+
return BD_ERROR_DEVICE_ERROR;
223+
}
224+
216225
// Find block devices containing blocks, may span multiple block devices
217226
for (size_t i = 0; i < _bd_count && size > 0; i++) {
218227
bd_size_t bdsize = _bds[i]->size();

features/storage/blockdevice/ExhaustibleBlockDevice.cpp

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,31 @@
2121
namespace mbed {
2222

2323
ExhaustibleBlockDevice::ExhaustibleBlockDevice(BlockDevice *bd, uint32_t erase_cycles)
24-
: _bd(bd), _erase_array(NULL), _erase_cycles(erase_cycles), _init_ref_count(0), _is_initialized(false)
24+
: _bd(bd), _erase_array(NULL), _programmable_array(NULL), _erase_cycles(erase_cycles),
25+
_init_ref_count(0), _is_initialized(false)
2526
{
2627
}
2728

2829
ExhaustibleBlockDevice::~ExhaustibleBlockDevice()
2930
{
3031
delete[] _erase_array;
32+
delete[] _programmable_array;
33+
}
34+
35+
uint32_t ExhaustibleBlockDevice::get_erase_cycles(bd_addr_t addr) const
36+
{
37+
if (!_is_initialized) {
38+
return 0;
39+
}
40+
return _erase_array[addr / get_erase_size()];
41+
}
42+
43+
void ExhaustibleBlockDevice::set_erase_cycles(bd_addr_t addr, uint32_t cycles)
44+
{
45+
if (!_is_initialized) {
46+
return;
47+
}
48+
_erase_array[addr / get_erase_size()] = cycles;
3149
}
3250

3351
int ExhaustibleBlockDevice::init()
@@ -52,6 +70,13 @@ int ExhaustibleBlockDevice::init()
5270
}
5371
}
5472

73+
if (!_programmable_array) {
74+
_programmable_array = new bool[_bd->size() / _bd->get_erase_size()];
75+
for (size_t i = 0; i < _bd->size() / _bd->get_erase_size(); i++) {
76+
_programmable_array[i] = true;
77+
}
78+
}
79+
5580
_is_initialized = true;
5681
return BD_ERROR_OK;
5782

@@ -99,38 +124,53 @@ int ExhaustibleBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
99124

100125
int ExhaustibleBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size)
101126
{
102-
MBED_ASSERT(is_valid_program(addr, size));
103-
104127
if (!_is_initialized) {
105128
return BD_ERROR_DEVICE_ERROR;
106129
}
107130

131+
if (!is_valid_program(addr, size)) {
132+
return BD_ERROR_DEVICE_ERROR;
133+
}
134+
108135
if (_erase_array[addr / get_erase_size()] == 0) {
109-
return 0;
136+
return BD_ERROR_DEVICE_ERROR;
137+
}
138+
139+
if (!_programmable_array[addr / get_erase_size()]) {
140+
return BD_ERROR_DEVICE_ERROR;
141+
}
142+
143+
int ret = _bd->program(buffer, addr, size);
144+
145+
if (ret == BD_ERROR_OK) {
146+
_programmable_array[addr / get_erase_size()] = false;
110147
}
111148

112-
return _bd->program(buffer, addr, size);
149+
return ret;
113150
}
114151

115152
int ExhaustibleBlockDevice::erase(bd_addr_t addr, bd_size_t size)
116153
{
117-
MBED_ASSERT(is_valid_erase(addr, size));
118154
if (!_is_initialized) {
119155
return BD_ERROR_DEVICE_ERROR;
120156
}
121157

158+
if (!is_valid_erase(addr, size)) {
159+
return BD_ERROR_DEVICE_ERROR;
160+
}
161+
122162
bd_size_t eu_size = get_erase_size();
123163
while (size) {
124164
// use an erase cycle
125165
if (_erase_array[addr / eu_size] > 0) {
126166
_erase_array[addr / eu_size] -= 1;
127-
}
128-
129-
if (_erase_array[addr / eu_size] > 0) {
130167
int err = _bd->erase(addr, eu_size);
131168
if (err) {
132169
return err;
133170
}
171+
_programmable_array[addr / get_erase_size()] = true;
172+
} else {
173+
return BD_ERROR_DEVICE_ERROR;
134174
}
135175

136176
addr += eu_size;

features/storage/blockdevice/ExhaustibleBlockDevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ class ExhaustibleBlockDevice : public BlockDevice {
158158
private:
159159
BlockDevice *_bd;
160160
uint32_t *_erase_array;
161+
bool *_programmable_array;
161162
uint32_t _erase_cycles;
162163
uint32_t _init_ref_count;
163164
bool _is_initialized;

features/storage/blockdevice/FlashSimBlockDevice.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,14 @@ int FlashSimBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
153153

154154
int FlashSimBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
155155
{
156-
MBED_ASSERT(is_valid_program(addr, size));
157156
if (!_is_initialized) {
158157
return BD_ERROR_DEVICE_ERROR;
159158
}
160159

160+
if (!is_valid_program(addr, size)) {
161+
return BD_ERROR_DEVICE_ERROR;
162+
}
163+
161164
bd_addr_t curr_addr = addr;
162165
bd_size_t curr_size = size;
163166

@@ -185,12 +188,14 @@ int FlashSimBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
185188

186189
int FlashSimBlockDevice::erase(bd_addr_t addr, bd_size_t size)
187190
{
188-
MBED_ASSERT(is_valid_erase(addr, size));
189-
190191
if (!_is_initialized) {
191192
return BD_ERROR_DEVICE_ERROR;
192193
}
193194

195+
if (!is_valid_erase(addr, size)) {
196+
return BD_ERROR_DEVICE_ERROR;
197+
}
198+
194199
bd_addr_t curr_addr = addr;
195200
bd_size_t curr_size = size;
196201

features/storage/blockdevice/MBRBlockDevice.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,14 @@ int MBRBlockDevice::partition(BlockDevice *bd, int part, uint8_t type, bd_addr_t
174174
}
175175

176176
// Calculate dimensions
177-
bd_size_t offset = ((int64_t)start < 0) ? -start : start;
178-
bd_size_t size = bd->size();
177+
bd_size_t size = ((int64_t)start < 0) ? -start : start;
178+
bd_size_t offset = bd->size();
179179

180-
if (offset < 512) {
181-
offset += std::max<uint32_t>(bd->get_erase_size(), 512);
180+
if (size < 512) {
181+
size += std::max<uint32_t>(bd->get_erase_size(), 512);
182182
}
183183

184-
size -= offset;
184+
offset -= size;
185185

186186
err = partition_absolute(bd, part, type, offset, size);
187187
if (err) {
@@ -336,31 +336,40 @@ int MBRBlockDevice::sync()
336336

337337
int MBRBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
338338
{
339-
MBED_ASSERT(is_valid_read(addr, size));
340339
if (!_is_initialized) {
341340
return BD_ERROR_DEVICE_ERROR;
342341
}
343342

343+
if (!is_valid_read(addr, size)) {
344+
return BD_ERROR_DEVICE_ERROR;
345+
}
346+
344347
return _bd->read(b, addr + _offset, size);
345348
}
346349

347350
int MBRBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
348351
{
349-
MBED_ASSERT(is_valid_program(addr, size));
350352
if (!_is_initialized) {
351353
return BD_ERROR_DEVICE_ERROR;
352354
}
353355

356+
if (!is_valid_program(addr, size)) {
357+
return BD_ERROR_DEVICE_ERROR;
358+
}
359+
354360
return _bd->program(b, addr + _offset, size);
355361
}
356362

357363
int MBRBlockDevice::erase(bd_addr_t addr, bd_size_t size)
358364
{
359-
MBED_ASSERT(is_valid_erase(addr, size));
360365
if (!_is_initialized) {
361366
return BD_ERROR_DEVICE_ERROR;
362367
}
363368

369+
if (!is_valid_erase(addr, size)) {
370+
return BD_ERROR_DEVICE_ERROR;
371+
}
372+
364373
return _bd->erase(addr + _offset, size);
365374
}
366375

@@ -403,7 +412,7 @@ bd_size_t MBRBlockDevice::get_erase_size(bd_addr_t addr) const
403412
int MBRBlockDevice::get_erase_value() const
404413
{
405414
if (!_is_initialized) {
406-
return 0;
415+
return BD_ERROR_DEVICE_ERROR;
407416
}
408417

409418
return _bd->get_erase_value();

features/storage/blockdevice/ReadOnlyBlockDevice.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,11 @@ int ReadOnlyBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
6161

6262
int ReadOnlyBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size)
6363
{
64-
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_BLOCK_DEVICE, MBED_ERROR_CODE_WRITE_PROTECTED), "ReadOnlyBlockDevice::program() not allowed", addr);
6564
return MBED_ERROR_WRITE_PROTECTED;
6665
}
6766

6867
int ReadOnlyBlockDevice::erase(bd_addr_t addr, bd_size_t size)
6968
{
70-
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_BLOCK_DEVICE, MBED_ERROR_CODE_WRITE_PROTECTED), "ReadOnlyBlockDevice::erase() not allowed", addr);
7169
return MBED_ERROR_WRITE_PROTECTED;
7270
}
7371

0 commit comments

Comments
 (0)