Skip to content

Commit 01adde9

Browse files
author
Marko Kiiskila
committed
hal_flash; add function to hal_flash interface to query whether
a region is empty (erased or not).
1 parent efe1c82 commit 01adde9

File tree

5 files changed

+92
-21
lines changed

5 files changed

+92
-21
lines changed

hw/hal/include/hal/hal_flash.h

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ int hal_flash_write(uint8_t flash_id, uint32_t address, const void *src,
4040
uint32_t num_bytes);
4141
int hal_flash_erase_sector(uint8_t flash_id, uint32_t sector_address);
4242
int hal_flash_erase(uint8_t flash_id, uint32_t address, uint32_t num_bytes);
43+
int hal_flash_isempty(uint8_t flash_id, uint32_t address, uint32_t num_bytes);
4344
uint8_t hal_flash_align(uint8_t flash_id);
4445
int hal_flash_init(void);
4546

hw/hal/include/hal/hal_flash_int.h

+7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ struct hal_flash_funcs {
4040
uint32_t sector_address);
4141
int (*hff_sector_info)(const struct hal_flash *dev, int idx,
4242
uint32_t *address, uint32_t *size);
43+
int (*hff_is_empty)(const struct hal_flash *dev, uint32_t address,
44+
uint32_t num_bytes);
4345
int (*hff_init)(const struct hal_flash *dev);
4446
};
4547

@@ -56,6 +58,11 @@ struct hal_flash {
5658
*/
5759
uint32_t hal_flash_sector_size(const struct hal_flash *hf, int sec_idx);
5860

61+
/*
62+
* Use as hal_flash_funcs.hff_is_empty if flash is erased to zeroes.
63+
*/
64+
int hal_flash_is_zeroes(const struct hal_flash *, uint32_t, uint32_t);
65+
int hal_flash_is_ones(const struct hal_flash *, uint32_t, uint32_t);
5966

6067
#ifdef __cplusplus
6168
}

hw/hal/src/hal_flash.c

+61-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* to you under the Apache License, Version 2.0 (the
77
* "License"); you may not use this file except in compliance
88
* with the License. You may obtain a copy of the License at
9-
*
9+
*
1010
* http://www.apache.org/licenses/LICENSE-2.0
1111
*
1212
* Unless required by applicable law or agreed to in writing,
@@ -298,6 +298,66 @@ hal_flash_erase(uint8_t id, uint32_t address, uint32_t num_bytes)
298298
return 0;
299299
}
300300

301+
static int
302+
hal_flash_is_setto(const struct hal_flash *hf, uint32_t address,
303+
uint32_t num_bytes, uint8_t val)
304+
{
305+
uint8_t buf[32];
306+
uint32_t blksz;
307+
int i;
308+
309+
while (num_bytes) {
310+
blksz = sizeof(buf);
311+
if (blksz > num_bytes) {
312+
blksz = num_bytes;
313+
}
314+
if (hf->hf_itf->hff_read(hf, address, buf, blksz)) {
315+
return -1;
316+
}
317+
for (i = 0; i < blksz; i++) {
318+
if (buf[i] != val) {
319+
return 0;
320+
}
321+
}
322+
num_bytes -= blksz;
323+
}
324+
return 1;
325+
}
326+
327+
int
328+
hal_flash_is_ones(const struct hal_flash *hf, uint32_t address,
329+
uint32_t num_bytes)
330+
{
331+
return hal_flash_is_setto(hf, address, num_bytes, 0xff);
332+
}
333+
334+
int
335+
hal_flash_is_zeroes(const struct hal_flash *hf, uint32_t address,
336+
uint32_t num_bytes)
337+
{
338+
return hal_flash_is_setto(hf, address, num_bytes, 0);
339+
}
340+
341+
int
342+
hal_flash_isempty(uint8_t id, uint32_t address, uint32_t num_bytes)
343+
{
344+
const struct hal_flash *hf;
345+
346+
hf = hal_bsp_flash_dev(id);
347+
if (!hf) {
348+
return -1;
349+
}
350+
if (hal_flash_check_addr(hf, address) ||
351+
hal_flash_check_addr(hf, address + num_bytes)) {
352+
return -1;
353+
}
354+
if (hf->hf_itf->hff_is_empty) {
355+
return hf->hf_itf->hff_is_empty(hf, address, num_bytes);
356+
} else {
357+
return hal_flash_is_ones(hf, address, num_bytes);
358+
}
359+
}
360+
301361
int
302362
hal_flash_ioctl(uint8_t id, uint32_t cmd, void *args)
303363
{

sys/flash_map/include/flash_map/flash_map.h

+10
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,18 @@ int flash_area_read(const struct flash_area *, uint32_t off, void *dst,
7676
int flash_area_write(const struct flash_area *, uint32_t off, const void *src,
7777
uint32_t len);
7878
int flash_area_erase(const struct flash_area *, uint32_t off, uint32_t len);
79+
80+
/*
81+
* Whether the whole area is empty.
82+
*/
7983
int flash_area_is_empty(const struct flash_area *, bool *);
8084

85+
/*
86+
* Whether a region of flash_area is empty
87+
*/
88+
int flash_area_isempty_at(const struct flash_area *, uint32_t off,
89+
uint32_t len);
90+
8191
/*
8292
* Alignment restriction for flash writes.
8393
*/

sys/flash_map/src/flash_map.c

+13-20
Original file line numberDiff line numberDiff line change
@@ -182,32 +182,25 @@ flash_area_align(const struct flash_area *fa)
182182
int
183183
flash_area_is_empty(const struct flash_area *fa, bool *empty)
184184
{
185-
uint32_t data[64 >> 2];
186-
uint32_t data_off = 0;
187-
int8_t bytes_to_read;
188-
uint8_t i;
189185
int rc;
190186

191-
while (data_off < fa->fa_size) {
192-
bytes_to_read = min(64, fa->fa_size - data_off);
193-
rc = flash_area_read(fa, data_off, data, bytes_to_read);
194-
if (rc) {
195-
return rc;
196-
}
197-
for (i = 0; i < bytes_to_read >> 2; i++) {
198-
if (data[i] != (uint32_t) -1) {
199-
goto not_empty;
200-
}
201-
}
202-
data_off += bytes_to_read;
187+
rc = hal_flash_isempty(fa->fa_device_id, fa->fa_off, fa->fa_size);
188+
if (rc < 0) {
189+
return rc;
190+
} else if (rc == 1) {
191+
*empty = true;
192+
} else {
193+
*empty = false;
203194
}
204-
*empty = true;
205-
return 0;
206-
not_empty:
207-
*empty = false;
208195
return 0;
209196
}
210197

198+
int
199+
flash_area_isempty_at(const struct flash_area *fa, uint32_t off, uint32_t len)
200+
{
201+
return hal_flash_isempty(fa->fa_device_id, fa->fa_off + off, len);
202+
}
203+
211204
/**
212205
* Converts the specified image slot index to a flash area ID. If the
213206
* specified value is not a valid image slot index (0 or 1), a crash is

0 commit comments

Comments
 (0)