21
21
namespace mbed {
22
22
23
23
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 )
25
26
{
26
27
}
27
28
28
29
ExhaustibleBlockDevice::~ExhaustibleBlockDevice ()
29
30
{
30
31
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;
31
49
}
32
50
33
51
int ExhaustibleBlockDevice::init ()
@@ -52,6 +70,13 @@ int ExhaustibleBlockDevice::init()
52
70
}
53
71
}
54
72
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
+
55
80
_is_initialized = true ;
56
81
return BD_ERROR_OK;
57
82
@@ -99,38 +124,53 @@ int ExhaustibleBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
99
124
100
125
int ExhaustibleBlockDevice::program (const void *buffer, bd_addr_t addr, bd_size_t size)
101
126
{
102
- MBED_ASSERT (is_valid_program (addr, size));
103
-
104
127
if (!_is_initialized) {
105
128
return BD_ERROR_DEVICE_ERROR;
106
129
}
107
130
131
+ if (!is_valid_program (addr, size)) {
132
+ return BD_ERROR_DEVICE_ERROR;
133
+ }
134
+
108
135
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 ;
110
147
}
111
148
112
- return _bd-> program (buffer, addr, size) ;
149
+ return ret ;
113
150
}
114
151
115
152
int ExhaustibleBlockDevice::erase (bd_addr_t addr, bd_size_t size)
116
153
{
117
- MBED_ASSERT (is_valid_erase (addr, size));
118
154
if (!_is_initialized) {
119
155
return BD_ERROR_DEVICE_ERROR;
120
156
}
121
157
158
+ if (!is_valid_erase (addr, size)) {
159
+ return BD_ERROR_DEVICE_ERROR;
160
+ }
161
+
122
162
bd_size_t eu_size = get_erase_size ();
123
163
while (size) {
124
164
// use an erase cycle
125
165
if (_erase_array[addr / eu_size] > 0 ) {
126
166
_erase_array[addr / eu_size] -= 1 ;
127
- }
128
-
129
- if (_erase_array[addr / eu_size] > 0 ) {
130
167
int err = _bd->erase (addr, eu_size);
131
168
if (err) {
132
169
return err;
133
170
}
171
+ _programmable_array[addr / get_erase_size ()] = true ;
172
+ } else {
173
+ return BD_ERROR_DEVICE_ERROR;
134
174
}
135
175
136
176
addr += eu_size;
0 commit comments