2121namespace mbed {
2222
2323ExhaustibleBlockDevice::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
2829ExhaustibleBlockDevice::~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
3351int 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
100125int 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
115152int 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;
0 commit comments