dfu/mcuboot: use flash_map instead of flash API

Patch introduces flash_map subsystem to operate on flash
footprint instead of direct operation using flash_driver API.
Flash area ID is used in API instead of direct flash-bank-offsets.
Changes allows to support operation on the partition in any flash
device.

flash_map was not available when this subsystem was introduced.

Signed-off-by: Findlay Feng <i@fengch.me>
This commit is contained in:
Findlay Feng 2018-08-01 14:50:48 +08:00 committed by Kumar Gala
commit 04bf2e1bd1
5 changed files with 176 additions and 158 deletions

View file

@ -92,12 +92,10 @@ struct mcuboot_img_header {
/** /**
* @brief Read the MCUboot image header information from an image bank. * @brief Read the MCUboot image header information from an image bank.
* *
* This attempts to parse the image header, which must begin at offset * This attempts to parse the image header,
* @a bank_offset from the beginning of the flash device used by * From the start of the @a area_id image.
* MCUboot.
* *
* @param bank_offset Offset of the image header from the start of the * @param area_id flash_area ID of image bank which stores the image.
* flash device used by MCUboot to store firmware.
* @param header On success, the returned header information is available * @param header On success, the returned header information is available
* in this structure. * in this structure.
* @param header_size Size of the header structure passed by the caller. * @param header_size Size of the header structure passed by the caller.
@ -105,7 +103,7 @@ struct mcuboot_img_header {
* necessary information, an error is returned. * necessary information, an error is returned.
* @return Zero on success, a negative value on error. * @return Zero on success, a negative value on error.
*/ */
int boot_read_bank_header(u32_t bank_offset, int boot_read_bank_header(u8_t area_id,
struct mcuboot_img_header *header, struct mcuboot_img_header *header,
size_t header_size); size_t header_size);
@ -162,9 +160,9 @@ int boot_request_upgrade(int permanent);
/** /**
* @brief Erase the image Bank. * @brief Erase the image Bank.
* *
* @param bank_offset address of the image bank * @param area_id flash_area ID of image bank to be erased.
* @return 0 on success, negative errno code on fail. * @return 0 on success, negative errno code on fail.
*/ */
int boot_erase_img_bank(u32_t bank_offset); int boot_erase_img_bank(u8_t area_id);
#endif /* ZEPHYR_INCLUDE_DFU_MCUBOOT_H_ */ #endif /* ZEPHYR_INCLUDE_DFU_MCUBOOT_H_ */

View file

@ -28,6 +28,7 @@ choice
config MCUBOOT_IMG_MANAGER config MCUBOOT_IMG_MANAGER
bool "Image manager for mcuboot" bool "Image manager for mcuboot"
select FLASH_MAP
help help
Enable support for managing DFU image downloaded using mcuboot. Enable support for managing DFU image downloaded using mcuboot.
endchoice endchoice

View file

@ -10,6 +10,7 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <flash.h> #include <flash.h>
#include <flash_map.h>
#include <zephyr.h> #include <zephyr.h>
#include <init.h> #include <init.h>
@ -67,20 +68,17 @@ struct mcuboot_v1_raw_header {
#define BOOT_FLAG_COPY_DONE 1 #define BOOT_FLAG_COPY_DONE 1
#define FLASH_MIN_WRITE_SIZE FLASH_WRITE_BLOCK_SIZE #define FLASH_MIN_WRITE_SIZE FLASH_WRITE_BLOCK_SIZE
#define FLASH_BANK0_OFFSET FLASH_AREA_IMAGE_0_OFFSET
/* FLASH_AREA_IMAGE_XX_YY values used below are auto-generated thanks to DT */ /* FLASH_AREA_IMAGE_XX_YY values used below are auto-generated thanks to DT */
#define FLASH_BANK_SIZE FLASH_AREA_IMAGE_0_SIZE #define FLASH_BANK0_ID DT_FLASH_AREA_IMAGE_0_ID
#define FLASH_BANK1_OFFSET FLASH_AREA_IMAGE_1_OFFSET #define FLASH_BANK1_ID DT_FLASH_AREA_IMAGE_1_ID
#define FLASH_STATE_OFFSET (FLASH_AREA_IMAGE_SCRATCH_OFFSET +\
FLASH_AREA_IMAGE_SCRATCH_SIZE)
#define COPY_DONE_OFFS(bank_offs) (bank_offs + FLASH_BANK_SIZE -\ #define COPY_DONE_OFFS(bank_area) ((bank_area)->fa_size -\
BOOT_MAGIC_SZ - BOOT_MAX_ALIGN * 2) BOOT_MAGIC_SZ - BOOT_MAX_ALIGN * 2)
#define IMAGE_OK_OFFS(bank_offs) (bank_offs + FLASH_BANK_SIZE - BOOT_MAGIC_SZ -\ #define IMAGE_OK_OFFS(bank_area) ((bank_area)->fa_size - BOOT_MAGIC_SZ -\
BOOT_MAX_ALIGN) BOOT_MAX_ALIGN)
#define MAGIC_OFFS(bank_offs) (bank_offs + FLASH_BANK_SIZE - BOOT_MAGIC_SZ) #define MAGIC_OFFS(bank_area) ((bank_area)->fa_size - BOOT_MAGIC_SZ)
static const u32_t boot_img_magic[4] = { static const u32_t boot_img_magic[4] = {
0xf395c277, 0xf395c277,
@ -163,72 +161,66 @@ static const struct boot_swap_table boot_swap_tables[] = {
}; };
#define BOOT_SWAP_TABLES_COUNT (ARRAY_SIZE(boot_swap_tables)) #define BOOT_SWAP_TABLES_COUNT (ARRAY_SIZE(boot_swap_tables))
static struct device *flash_dev; static int boot_flag_offs(int flag, const struct flash_area *fa, u32_t *offs)
static int boot_flag_offs(int flag, u32_t bank_offs, u32_t *offs)
{ {
switch (flag) { switch (flag) {
case BOOT_FLAG_COPY_DONE: case BOOT_FLAG_COPY_DONE:
*offs = COPY_DONE_OFFS(bank_offs); *offs = COPY_DONE_OFFS(fa);
return 0; return 0;
case BOOT_FLAG_IMAGE_OK: case BOOT_FLAG_IMAGE_OK:
*offs = IMAGE_OK_OFFS(bank_offs); *offs = IMAGE_OK_OFFS(fa);
return 0; return 0;
default: default:
return -ENOTSUP; return -ENOTSUP;
} }
} }
static int boot_flash_write(off_t offs, const void *data, size_t len) static int boot_flag_write(int flag, u8_t bank_id)
{
int rc;
rc = flash_write_protection_set(flash_dev, false);
if (rc) {
return rc;
}
rc = flash_write(flash_dev, offs, data, len);
if (rc) {
return rc;
}
rc = flash_write_protection_set(flash_dev, true);
return rc;
}
static int boot_flag_write(int flag, u32_t bank_offs)
{ {
const struct flash_area *fa;
u8_t buf[FLASH_MIN_WRITE_SIZE]; u8_t buf[FLASH_MIN_WRITE_SIZE];
u32_t offs; u32_t offs;
int rc; int rc;
rc = boot_flag_offs(flag, bank_offs, &offs); rc = flash_area_open(bank_id, &fa);
if (rc) {
return rc;
}
rc = boot_flag_offs(flag, fa, &offs);
if (rc != 0) { if (rc != 0) {
flash_area_close(fa);
return rc; return rc;
} }
(void)memset(buf, BOOT_FLAG_UNSET, sizeof(buf)); (void)memset(buf, BOOT_FLAG_UNSET, sizeof(buf));
buf[0] = BOOT_FLAG_SET; buf[0] = BOOT_FLAG_SET;
rc = boot_flash_write(offs, buf, sizeof(buf)); rc = flash_area_write(fa, offs, buf, sizeof(buf));
flash_area_close(fa);
return rc; return rc;
} }
static int boot_flag_read(int flag, u32_t bank_offs) static int boot_flag_read(int flag, u8_t bank_id)
{ {
const struct flash_area *fa;
u32_t offs; u32_t offs;
int rc; int rc;
u8_t flag_val; u8_t flag_val;
rc = boot_flag_offs(flag, bank_offs, &offs); rc = flash_area_open(bank_id, &fa);
if (rc != 0) { if (rc) {
return rc; return rc;
} }
rc = flash_read(flash_dev, offs, &flag_val, sizeof(flag_val)); rc = boot_flag_offs(flag, fa, &offs);
if (rc != 0) {
flash_area_close(fa);
return rc;
}
rc = flash_area_read(fa, offs, &flag_val, sizeof(flag_val));
if (rc != 0) { if (rc != 0) {
return rc; return rc;
} }
@ -236,42 +228,56 @@ static int boot_flag_read(int flag, u32_t bank_offs)
return flag_val; return flag_val;
} }
static int boot_image_ok_read(u32_t bank_offs) static int boot_image_ok_read(u8_t bank_id)
{ {
return boot_flag_read(BOOT_FLAG_IMAGE_OK, bank_offs); return boot_flag_read(BOOT_FLAG_IMAGE_OK, bank_id);
} }
static int boot_image_ok_write(u32_t bank_offs) static int boot_image_ok_write(u8_t bank_id)
{ {
return boot_flag_write(BOOT_FLAG_IMAGE_OK, bank_offs); return boot_flag_write(BOOT_FLAG_IMAGE_OK, bank_id);
} }
static int boot_copy_done_read(u32_t bank_offs) static int boot_copy_done_read(u8_t bank_id)
{ {
return boot_flag_read(BOOT_FLAG_COPY_DONE, bank_offs); return boot_flag_read(BOOT_FLAG_COPY_DONE, bank_id);
} }
static int boot_magic_write(u32_t bank_offs) static int boot_magic_write(u8_t bank_id)
{ {
const struct flash_area *fa;
u32_t offs; u32_t offs;
int rc; int rc;
offs = MAGIC_OFFS(bank_offs); rc = flash_area_open(bank_id, &fa);
if (rc) {
return rc;
}
rc = boot_flash_write(offs, boot_img_magic, BOOT_MAGIC_SZ); offs = MAGIC_OFFS(fa);
rc = flash_area_write(fa, offs, boot_img_magic, BOOT_MAGIC_SZ);
flash_area_close(fa);
return rc; return rc;
} }
static int boot_read_v1_header(u32_t bank_offset, static int boot_read_v1_header(u8_t area_id,
struct mcuboot_v1_raw_header *v1_raw) struct mcuboot_v1_raw_header *v1_raw)
{ {
const struct flash_area *fa;
int rc; int rc;
rc = flash_area_open(area_id, &fa);
if (rc) {
return rc;
}
/* /*
* Read and sanity-check the raw header. * Read and sanity-check the raw header.
*/ */
rc = flash_read(flash_dev, bank_offset, v1_raw, sizeof(*v1_raw)); rc = flash_area_read(fa, 0, v1_raw, sizeof(*v1_raw));
flash_area_close(fa);
if (rc) { if (rc) {
return rc; return rc;
} }
@ -302,7 +308,7 @@ static int boot_read_v1_header(u32_t bank_offset,
return 0; return 0;
} }
int boot_read_bank_header(u32_t bank_offset, int boot_read_bank_header(u8_t area_id,
struct mcuboot_img_header *header, struct mcuboot_img_header *header,
size_t header_size) size_t header_size)
{ {
@ -318,7 +324,7 @@ int boot_read_bank_header(u32_t bank_offset,
if (header_size < v1_min_size) { if (header_size < v1_min_size) {
return -ENOMEM; return -ENOMEM;
} }
rc = boot_read_v1_header(bank_offset, &v1_raw); rc = boot_read_v1_header(area_id, &v1_raw);
if (rc) { if (rc) {
return rc; return rc;
} }
@ -360,14 +366,22 @@ static int boot_magic_code_check(const u32_t *magic)
return BOOT_MAGIC_UNSET; return BOOT_MAGIC_UNSET;
} }
static int boot_magic_state_read(u32_t bank_offs) static int boot_magic_state_read(u8_t bank_id)
{ {
u32_t magic[4]; const struct flash_area *fa;
u32_t magic[(sizeof(u32_t) - 1 + BOOT_MAGIC_SZ) / sizeof(u32_t)];
u32_t offs; u32_t offs;
int rc; int rc;
offs = MAGIC_OFFS(bank_offs); rc = flash_area_open(bank_id, &fa);
rc = flash_read(flash_dev, offs, magic, sizeof(magic)); if (rc) {
return rc;
}
offs = MAGIC_OFFS(fa);
rc = flash_area_read(fa, offs, magic, BOOT_MAGIC_SZ);
flash_area_close(fa);
if (rc != 0) { if (rc != 0) {
return rc; return rc;
} }
@ -375,25 +389,25 @@ static int boot_magic_state_read(u32_t bank_offs)
return boot_magic_code_check(magic); return boot_magic_code_check(magic);
} }
static int boot_read_swap_state(u32_t bank_offs, struct boot_swap_state *state) static int boot_read_swap_state(u8_t bank_id, struct boot_swap_state *state)
{ {
int rc; int rc;
rc = boot_magic_state_read(bank_offs); rc = boot_magic_state_read(bank_id);
if (rc < 0) { if (rc < 0) {
return rc; return rc;
} }
state->magic = rc; state->magic = rc;
if (bank_offs != FLASH_AREA_IMAGE_SCRATCH_OFFSET) { if (bank_id != DT_FLASH_AREA_IMAGE_SCRATCH_ID) {
rc = boot_copy_done_read(bank_offs); rc = boot_copy_done_read(bank_id);
if (rc < 0) { if (rc < 0) {
return rc; return rc;
} }
state->copy_done = rc; state->copy_done = rc;
} }
rc = boot_image_ok_read(bank_offs); rc = boot_image_ok_read(bank_id);
if (rc < 0) { if (rc < 0) {
return rc; return rc;
} }
@ -410,12 +424,12 @@ int boot_swap_type(void)
int rc; int rc;
int i; int i;
rc = boot_read_swap_state(FLASH_BANK0_OFFSET, &state_slot0); rc = boot_read_swap_state(FLASH_BANK0_ID, &state_slot0);
if (rc != 0) { if (rc != 0) {
return rc; return rc;
} }
rc = boot_read_swap_state(FLASH_BANK1_OFFSET, &state_slot1); rc = boot_read_swap_state(FLASH_BANK1_ID, &state_slot1);
if (rc != 0) { if (rc != 0) {
return rc; return rc;
} }
@ -448,9 +462,9 @@ int boot_request_upgrade(int permanent)
{ {
int rc; int rc;
rc = boot_magic_write(FLASH_BANK1_OFFSET); rc = boot_magic_write(FLASH_BANK1_ID);
if (rc == 0 && permanent) { if (rc == 0 && permanent) {
rc = boot_image_ok_write(FLASH_BANK1_OFFSET); rc = boot_image_ok_write(FLASH_BANK1_ID);
} }
return rc; return rc;
@ -458,54 +472,36 @@ int boot_request_upgrade(int permanent)
bool boot_is_img_confirmed(void) bool boot_is_img_confirmed(void)
{ {
return boot_image_ok_read(FLASH_BANK0_OFFSET) == BOOT_FLAG_SET; return boot_image_ok_read(FLASH_BANK0_ID) == BOOT_FLAG_SET;
} }
int boot_write_img_confirmed(void) int boot_write_img_confirmed(void)
{ {
int rc; int rc;
if (boot_image_ok_read(FLASH_BANK0_OFFSET) != BOOT_FLAG_UNSET) { if (boot_image_ok_read(FLASH_BANK0_ID) != BOOT_FLAG_UNSET) {
/* Already confirmed. */ /* Already confirmed. */
return 0; return 0;
} }
rc = boot_image_ok_write(FLASH_BANK0_OFFSET); rc = boot_image_ok_write(FLASH_BANK0_ID);
return rc; return rc;
} }
int boot_erase_img_bank(u32_t bank_offset) int boot_erase_img_bank(u8_t area_id)
{ {
const struct flash_area *fa;
int rc; int rc;
rc = flash_write_protection_set(flash_dev, false); rc = flash_area_open(area_id, &fa);
if (rc) { if (rc) {
return rc; return rc;
} }
rc = flash_erase(flash_dev, bank_offset, FLASH_BANK_SIZE); rc = flash_area_erase(fa, 0, fa->fa_size);
if (rc) {
return rc;
}
rc = flash_write_protection_set(flash_dev, true); flash_area_close(fa);
return rc; return rc;
} }
static int boot_init(struct device *dev)
{
ARG_UNUSED(dev);
#if defined(DT_FLASH_DEV_NAME)
flash_dev = device_get_binding(DT_FLASH_DEV_NAME);
#elif defined(DT_SPI_NOR_DRV_NAME)
flash_dev = device_get_binding(DT_SPI_NOR_DRV_NAME);
#endif
if (!flash_dev) {
return -ENODEV;
}
return 0;
}
SYS_INIT(boot_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);

View file

@ -0,0 +1,38 @@
/* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
&flash0 {
/*
* For more information, see:
* http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions
*/
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
boot_partition: partition@0 {
label = "mcuboot";
reg = <0x000000000 0x0000E000>;
};
slot0_partition: partition@c000 {
label = "image-0";
reg = <0x0000E000 0x000068000>;
};
slot1_partition: partition@75000 {
label = "image-1";
reg = <0x00076000 0x000068000>;
};
scratch_partition: partition@de000 {
label = "image-scratch";
reg = <0x000de000 0x0001e000>;
};
storage_partition: partition@fc000 {
label = "storage";
reg = <0x000fc000 0x00004000>;
};
};
};

View file

@ -5,7 +5,7 @@
*/ */
#include <ztest.h> #include <ztest.h>
#include <flash.h> #include <flash_map.h>
#include <dfu/mcuboot.h> #include <dfu/mcuboot.h>
#define BOOT_MAGIC_VAL_W0 0xf395c277 #define BOOT_MAGIC_VAL_W0 0xf395c277
@ -17,44 +17,32 @@
void test_bank_erase(void) void test_bank_erase(void)
{ {
struct device *flash_dev; const struct flash_area *fa;
u32_t temp; u32_t temp;
u32_t temp2 = 0x5a; u32_t temp2 = 0x5a5a5a5a;
off_t offs; off_t offs;
int ret; int ret;
flash_dev = device_get_binding(DT_FLASH_DEV_NAME); ret = flash_area_open(DT_FLASH_AREA_IMAGE_1_ID, &fa);
if (ret) {
for (offs = FLASH_AREA_IMAGE_1_OFFSET; printf("Flash driver was not found!\n");
offs < FLASH_AREA_IMAGE_1_OFFSET + FLASH_AREA_IMAGE_1_SIZE;
offs += sizeof(temp)) {
ret = flash_read(flash_dev, offs, &temp, sizeof(temp));
zassert_true(ret == 0, "Reading from flash");
if (temp != 0xFFFFFFFF) {
ret = flash_write_protection_set(flash_dev, false);
zassert_true(ret == 0, "Disabling flash protection");
ret = flash_write(flash_dev, offs, &temp2,
sizeof(temp));
zassert_true(ret == 0, "Writing to flash");
ret = flash_write_protection_set(flash_dev, true);
zassert_true(ret == 0, "Enabling flash protection");
}
}
zassert(boot_erase_img_bank(FLASH_AREA_IMAGE_1_OFFSET) == 0,
"pass", "fail");
if (!flash_dev) {
printf("Nordic nRF5 flash driver was not found!\n");
return; return;
} }
for (offs = FLASH_AREA_IMAGE_1_OFFSET; for (offs = 0; offs < fa->fa_size; offs += sizeof(temp)) {
offs < FLASH_AREA_IMAGE_1_OFFSET + FLASH_AREA_IMAGE_1_SIZE; ret = flash_area_read(fa, offs, &temp, sizeof(temp));
offs += sizeof(temp)) { zassert_true(ret == 0, "Reading from flash");
ret = flash_read(flash_dev, offs, &temp, sizeof(temp)); if (temp == 0xFFFFFFFF) {
ret = flash_area_write(fa, offs, &temp2, sizeof(temp));
zassert_true(ret == 0, "Writing to flash");
}
}
zassert(boot_erase_img_bank(DT_FLASH_AREA_IMAGE_1_ID) == 0,
"pass", "fail");
for (offs = 0; offs < fa->fa_size; offs += sizeof(temp)) {
ret = flash_area_read(fa, offs, &temp, sizeof(temp));
zassert_true(ret == 0, "Reading from flash"); zassert_true(ret == 0, "Reading from flash");
zassert(temp == 0xFFFFFFFF, "pass", "fail"); zassert(temp == 0xFFFFFFFF, "pass", "fail");
} }
@ -62,7 +50,7 @@ void test_bank_erase(void)
void test_request_upgrade(void) void test_request_upgrade(void)
{ {
struct device *flash_dev; const struct flash_area *fa;
const u32_t expectation[6] = { const u32_t expectation[6] = {
0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff,
@ -74,25 +62,27 @@ void test_request_upgrade(void)
u32_t readout[ARRAY_SIZE(expectation)]; u32_t readout[ARRAY_SIZE(expectation)];
int ret; int ret;
flash_dev = device_get_binding(DT_FLASH_DEV_NAME); ret = flash_area_open(DT_FLASH_AREA_IMAGE_1_ID, &fa);
if (ret) {
printf("Flash driver was not found!\n");
return;
}
zassert(boot_request_upgrade(false) == 0, "pass", "fail"); zassert(boot_request_upgrade(false) == 0, "pass", "fail");
ret = flash_read(flash_dev, FLASH_AREA_IMAGE_1_OFFSET + ret = flash_area_read(fa, fa->fa_size - sizeof(expectation),
FLASH_AREA_IMAGE_1_SIZE - sizeof(expectation), &readout, sizeof(readout));
&readout, sizeof(readout));
zassert_true(ret == 0, "Read from flash"); zassert_true(ret == 0, "Read from flash");
zassert(memcmp(expectation, readout, sizeof(expectation)) == 0, zassert(memcmp(expectation, readout, sizeof(expectation)) == 0,
"pass", "fail"); "pass", "fail");
boot_erase_img_bank(FLASH_AREA_IMAGE_1_OFFSET); boot_erase_img_bank(DT_FLASH_AREA_IMAGE_1_ID);
zassert(boot_request_upgrade(true) == 0, "pass", "fail"); zassert(boot_request_upgrade(true) == 0, "pass", "fail");
ret = flash_read(flash_dev, FLASH_AREA_IMAGE_1_OFFSET + ret = flash_area_read(fa, fa->fa_size - sizeof(expectation),
FLASH_AREA_IMAGE_1_SIZE - sizeof(expectation), &readout, sizeof(readout));
&readout, sizeof(readout));
zassert_true(ret == 0, "Read from flash"); zassert_true(ret == 0, "Read from flash");
zassert(memcmp(&expectation[2], &readout[2], sizeof(expectation) - zassert(memcmp(&expectation[2], &readout[2], sizeof(expectation) -
@ -105,37 +95,32 @@ void test_write_confirm(void)
{ {
const u32_t img_magic[4] = BOOT_MAGIC_VALUES; const u32_t img_magic[4] = BOOT_MAGIC_VALUES;
u32_t readout[ARRAY_SIZE(img_magic)]; u32_t readout[ARRAY_SIZE(img_magic)];
struct device *flash_dev; const struct flash_area *fa;
int ret; int ret;
flash_dev = device_get_binding(DT_FLASH_DEV_NAME); ret = flash_area_open(DT_FLASH_AREA_IMAGE_0_ID, &fa);
if (ret) {
printf("Flash driver was not found!\n");
return;
}
zassert(boot_erase_img_bank(FLASH_AREA_IMAGE_0_OFFSET) == 0, zassert(boot_erase_img_bank(DT_FLASH_AREA_IMAGE_0_ID) == 0,
"pass", "fail"); "pass", "fail");
ret = flash_read(flash_dev, FLASH_AREA_IMAGE_0_OFFSET + ret = flash_area_read(fa, fa->fa_size - sizeof(img_magic),
FLASH_AREA_IMAGE_0_SIZE - sizeof(img_magic), &readout, &readout, sizeof(img_magic));
sizeof(img_magic));
zassert_true(ret == 0, "Read from flash"); zassert_true(ret == 0, "Read from flash");
if (memcmp(img_magic, readout, sizeof(img_magic)) != 0) { if (memcmp(img_magic, readout, sizeof(img_magic)) != 0) {
ret = flash_write_protection_set(flash_dev, false); ret = flash_area_write(fa, fa->fa_size - 16,
zassert_true(ret == 0, "Disable flash protection"); img_magic, 16);
ret = flash_write(flash_dev, FLASH_AREA_IMAGE_0_OFFSET +
FLASH_AREA_IMAGE_0_SIZE - 16,
img_magic, 16);
zassert_true(ret == 0, "Write to flash"); zassert_true(ret == 0, "Write to flash");
ret = flash_write_protection_set(flash_dev, true);
zassert_true(ret == 0, "Enable flash protection");
} }
zassert(boot_write_img_confirmed() == 0, "pass", "fail"); zassert(boot_write_img_confirmed() == 0, "pass", "fail");
ret = flash_read(flash_dev, FLASH_AREA_IMAGE_0_OFFSET + ret = flash_area_read(fa, fa->fa_size - 24, readout,
FLASH_AREA_IMAGE_0_SIZE - 24, readout, sizeof(readout[0]));
sizeof(readout[0]));
zassert_true(ret == 0, "Read from flash"); zassert_true(ret == 0, "Read from flash");
zassert_equal(1, readout[0] & 0xff, "confirmation error"); zassert_equal(1, readout[0] & 0xff, "confirmation error");