diff options
author | xengineering <me@xengineering.eu> | 2025-03-30 17:03:15 +0200 |
---|---|---|
committer | xengineering <me@xengineering.eu> | 2025-03-30 18:51:33 +0200 |
commit | eb52105fd05ffc2ff98e59e76b48ae0968dfdced (patch) | |
tree | 2e0df0e3753607ee592654c3610a0e7c622063c2 | |
parent | 3ffdafa73301aad063e3637141d9d3b898757f79 (diff) | |
download | iot-contact-eb52105fd05ffc2ff98e59e76b48ae0968dfdced.tar iot-contact-eb52105fd05ffc2ff98e59e76b48ae0968dfdced.tar.zst iot-contact-eb52105fd05ffc2ff98e59e76b48ae0968dfdced.zip |
fw: app: update: Write uploaded image to flash
This write the received firmware image data to the secondary MCUboot
slot. This prepares an update.
With the MCUboot shell it can be applied with:
mcuboot request_upgrade permanent
kernel reboot
If the signature is valid the device will permanently update to the new
application firmware. Otherwise it will refuse the new image and boot
the old one.
-rw-r--r-- | fw/app/src/update.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/fw/app/src/update.c b/fw/app/src/update.c index 9e91380..ff4ce6a 100644 --- a/fw/app/src/update.c +++ b/fw/app/src/update.c @@ -4,18 +4,18 @@ * obtain one at https://mozilla.org/MPL/2.0/. */ - #include <stdbool.h> +#include <stdint.h> #include <zephyr/dfu/flash_img.h> #include <zephyr/logging/log.h> #include <zephyr/net/http/server.h> #include <zephyr/net/http/service.h> #include <zephyr/net/http/status.h> +#include <zephyr/storage/flash_map.h> LOG_MODULE_REGISTER(update); - static int update_handler( struct http_client_ctx *client, enum http_data_status status, @@ -24,6 +24,8 @@ static int update_handler( void *user_data ) { static size_t processed; + static struct flash_img_context flash_img_context; + int ret; if (status == HTTP_SERVER_DATA_ABORTED) { LOG_WRN("Transaction aborted after %zd bytes.", processed); @@ -31,9 +33,47 @@ static int update_handler( return 0; } + bool is_first_call = processed == 0; + if (is_first_call == true) { + uint8_t upload_slot = flash_img_get_upload_slot(); + LOG_INF("Handling upload to flash slot %d", upload_slot); + + const struct flash_area *fa; + ret = flash_area_open(upload_slot, &fa); + if (ret < 0) { + LOG_ERR("Failed to open flash area (%d)", ret); + return ret; + } + + ret = flash_area_erase(fa, 0, FIXED_PARTITION_SIZE(slot1_partition)); + flash_area_close(fa); + if (ret < 0) { + LOG_ERR("Failed to erase flash area (%d)", ret); + return ret; + } + + ret = flash_img_init_id(&flash_img_context, upload_slot); + if (ret < 0) { + LOG_ERR("Failed to init flash image context (%d)", ret); + return ret; + } + } + + ret = flash_img_buffered_write(&flash_img_context, request_ctx->data, + request_ctx->data_len, true); + if (ret < 0) { + LOG_ERR("Failed to write data to flash (%d)", ret); + return ret; + } + processed += request_ctx->data_len; if (status == HTTP_SERVER_DATA_FINAL) { + size_t written = flash_img_bytes_written(&flash_img_context); + if (written != processed) { + LOG_ERR("Processed %zd octets but wrote %zd", processed, written); + return ret; + } LOG_INF("Handled update request receiving %zd octets.", processed); processed = 0; } |