zephyr: erase flash pages progressively
This commit adds the option to erase flash pages while receiving
the firmware, opposed to bulk-erasing the whole image area at
the beginning of the DFU process. This is required on some
hardware that has long erase times, to prevent a long wait
and possibly a timeout during DFU.
Signed-off-by: Emanuele Di Santo <emdi@nordicsemi.no>
Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig
index 96b5268..31c78a1 100644
--- a/boot/zephyr/Kconfig
+++ b/boot/zephyr/Kconfig
@@ -75,6 +75,15 @@
memory usage; larger values allow it to support larger images.
If unsure, leave at the default value.
+config BOOT_ERASE_PROGRESSIVELY
+ bool "Erase flash progressively when receiving new firmware"
+ default y if SOC_NRF52840
+ help
+ If enabled, flash is erased as necessary when receiving new firmware,
+ instead of erasing the whole image slot at once. This is necessary
+ on some hardware that has long erase times, to prevent long wait
+ times at the beginning of the DFU process.
+
config ZEPHYR_TRY_MASS_ERASE
bool "Try to mass erase flash when flashing MCUboot image"
default y
diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c
index ee2320c..7133c99 100644
--- a/boot/zephyr/flash_map_extended.c
+++ b/boot/zephyr/flash_map_extended.c
@@ -11,7 +11,6 @@
#include "target.h"
#include <flash_map_backend/flash_map_backend.h>
-#include <hal/hal_flash.h>
#include <sysflash/sysflash.h>
#include "bootutil/bootutil_log.h"
@@ -24,6 +23,16 @@
#define FLASH_DEVICE_ID SOC_FLASH_0_ID
#define FLASH_DEVICE_BASE CONFIG_FLASH_BASE_ADDRESS
+static struct device *flash_dev;
+
+struct device *flash_device_get_binding(char *dev_name)
+{
+ if (!flash_dev) {
+ flash_dev = device_get_binding(dev_name);
+ }
+ return flash_dev;
+}
+
int flash_device_base(uint8_t fd_id, uintptr_t *ret)
{
if (fd_id != FLASH_DEVICE_ID) {
@@ -43,3 +52,19 @@
{
return slot + FLASH_AREA_IMAGE_0;
}
+
+int flash_area_sector_from_off(off_t off, struct flash_sector *sector)
+{
+ int rc;
+ struct flash_pages_info page;
+
+ rc = flash_get_page_info_by_offs(flash_dev, off, &page);
+ if (rc) {
+ return rc;
+ }
+
+ sector->fs_off = page.start_offset;
+ sector->fs_size = page.size;
+
+ return rc;
+}
\ No newline at end of file
diff --git a/boot/zephyr/include/flash_map_backend/flash_map_backend.h b/boot/zephyr/include/flash_map_backend/flash_map_backend.h
index 18009c5..d09aa59 100644
--- a/boot/zephyr/include/flash_map_backend/flash_map_backend.h
+++ b/boot/zephyr/include/flash_map_backend/flash_map_backend.h
@@ -8,7 +8,7 @@
#ifndef __FLASH_MAP_BACKEND_H__
#define __FLASH_MAP_BACKEND_H__
-#include <flash_map.h> // the zephyr falsh_map
+#include <flash_map.h> // the zephyr flash_map
#ifdef __cplusplus
extern "C" {
@@ -32,7 +32,13 @@
* and match the target offset specified in download script.
*/
#include <inttypes.h>
+#include <sys/types.h>
+/* Retrieve the flash device with the given name.
+ *
+ * Returns the flash device on success, or NULL on failure.
+ */
+struct device *flash_device_get_binding(char *dev_name);
/*
* Retrieve a memory-mapped flash device's base address.
@@ -46,6 +52,12 @@
int flash_area_id_from_image_slot(int slot);
+/* Retrieve the flash sector a given offset belongs to.
+ *
+ * Returns 0 on success, or an error code on failure.
+ */
+int flash_area_sector_from_off(off_t off, struct flash_sector *sector);
+
#ifdef __cplusplus
}
#endif
diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c
index 5633a14..ca30bb5 100644
--- a/boot/zephyr/main.c
+++ b/boot/zephyr/main.c
@@ -39,8 +39,6 @@
};
#endif
-struct device *boot_flash_device;
-
void os_heap_init(void);
#if defined(CONFIG_ARM)
@@ -103,8 +101,7 @@
os_heap_init();
- boot_flash_device = device_get_binding(FLASH_DEV_NAME);
- if (!boot_flash_device) {
+ if (!flash_device_get_binding(FLASH_DEV_NAME)) {
BOOT_LOG_ERR("Flash device %s not found", FLASH_DEV_NAME);
while (1)
;