summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2025-03-30 17:03:15 +0200
committerxengineering <me@xengineering.eu>2025-03-30 18:51:33 +0200
commiteb52105fd05ffc2ff98e59e76b48ae0968dfdced (patch)
tree2e0df0e3753607ee592654c3610a0e7c622063c2
parent3ffdafa73301aad063e3637141d9d3b898757f79 (diff)
downloadiot-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.c44
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;
}