diff --git a/include/dfu/flash_img.h b/include/dfu/flash_img.h index 4a887913bb7..104e94d8162 100644 --- a/include/dfu/flash_img.h +++ b/include/dfu/flash_img.h @@ -12,9 +12,11 @@ extern "C" { #endif +#include + struct flash_img_context { u8_t buf[CONFIG_IMG_BLOCK_BUF_SIZE]; - struct device *dev; + const struct flash_area *flash_area; size_t bytes_written; u16_t buf_bytes; }; @@ -23,9 +25,10 @@ struct flash_img_context { * @brief Initialize context needed for writing the image to the flash. * * @param ctx context to be initialized - * @param dev flash driver to used while writing the image + * + * @return 0 on success, negative errno code on fail */ -void flash_img_init(struct flash_img_context *ctx, struct device *dev); +int flash_img_init(struct flash_img_context *ctx); /** * @brief Read number of bytes of the image written to the flash. diff --git a/subsys/dfu/img_util/flash_img.c b/subsys/dfu/img_util/flash_img.c index e1745a3beb3..c9438366d50 100644 --- a/subsys/dfu/img_util/flash_img.c +++ b/subsys/dfu/img_util/flash_img.c @@ -15,7 +15,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include -#include #include #include @@ -23,7 +22,7 @@ BUILD_ASSERT_MSG((CONFIG_IMG_BLOCK_BUF_SIZE % FLASH_WRITE_BLOCK_SIZE == 0), "CONFIG_IMG_BLOCK_BUF_SIZE is not a multiple of " "FLASH_WRITE_BLOCK_SIZE"); -static bool flash_verify(struct device *dev, off_t offset, +static bool flash_verify(const struct flash_area *fa, off_t offset, u8_t *data, size_t len) { size_t size; @@ -32,7 +31,7 @@ static bool flash_verify(struct device *dev, off_t offset, while (len) { size = (len >= sizeof(temp)) ? sizeof(temp) : len; - rc = flash_read(dev, offset, &temp, size); + rc = flash_area_read(fa, offset, &temp, size); if (rc) { LOG_ERR("flash_read error %d offset=0x%08"PRIx32, rc, (u32_t)offset); @@ -53,36 +52,54 @@ static bool flash_verify(struct device *dev, off_t offset, return (len == 0) ? true : false; } -/* buffer data into block writes */ -static int flash_block_write(struct flash_img_context *ctx, off_t offset, - u8_t *data, size_t len, bool finished) +static int flash_sync(struct flash_img_context *ctx) +{ + int rc = 0; + + if (ctx->buf_bytes < CONFIG_IMG_BLOCK_BUF_SIZE) { + (void)memset(ctx->buf + ctx->buf_bytes, 0xFF, + CONFIG_IMG_BLOCK_BUF_SIZE - ctx->buf_bytes); + } + + rc = flash_area_write(ctx->flash_area, ctx->bytes_written, ctx->buf, + CONFIG_IMG_BLOCK_BUF_SIZE); + if (rc) { + LOG_ERR("flash_write error %d offset=0x%08" PRIx32, rc, + (u32_t)ctx->bytes_written); + return rc; + } + + if (!flash_verify(ctx->flash_area, ctx->bytes_written, ctx->buf, + CONFIG_IMG_BLOCK_BUF_SIZE)) { + return -EIO; + } + + ctx->bytes_written += ctx->buf_bytes; + ctx->buf_bytes = 0; + + return rc; +} + +int flash_img_buffered_write(struct flash_img_context *ctx, u8_t *data, + size_t len, bool flush) { int processed = 0; int rc = 0; + int buf_empty_bytes; while ((len - processed) > - (CONFIG_IMG_BLOCK_BUF_SIZE - ctx->buf_bytes)) { + (buf_empty_bytes = CONFIG_IMG_BLOCK_BUF_SIZE - ctx->buf_bytes)) { memcpy(ctx->buf + ctx->buf_bytes, data + processed, - (CONFIG_IMG_BLOCK_BUF_SIZE - ctx->buf_bytes)); + buf_empty_bytes); + + ctx->buf_bytes = CONFIG_IMG_BLOCK_BUF_SIZE; + rc = flash_sync(ctx); - flash_write_protection_set(ctx->dev, false); - rc = flash_write(ctx->dev, offset + ctx->bytes_written, - ctx->buf, CONFIG_IMG_BLOCK_BUF_SIZE); - flash_write_protection_set(ctx->dev, true); if (rc) { - LOG_ERR("flash_write error %d offset=0x%08"PRIx32, - rc, (u32_t)(offset + ctx->bytes_written)); return rc; } - if (!flash_verify(ctx->dev, offset + ctx->bytes_written, - ctx->buf, CONFIG_IMG_BLOCK_BUF_SIZE)) { - return -EIO; - } - - ctx->bytes_written += CONFIG_IMG_BLOCK_BUF_SIZE; - processed += (CONFIG_IMG_BLOCK_BUF_SIZE - ctx->buf_bytes); - ctx->buf_bytes = 0; + processed += buf_empty_bytes; } /* place rest of the data into ctx->buf */ @@ -92,30 +109,22 @@ static int flash_block_write(struct flash_img_context *ctx, off_t offset, ctx->buf_bytes += len - processed; } - if (finished && ctx->buf_bytes > 0) { - /* pad the rest of ctx->buf and write it out */ - (void)memset(ctx->buf + ctx->buf_bytes, 0xFF, - CONFIG_IMG_BLOCK_BUF_SIZE - ctx->buf_bytes); + if (!flush) { + return rc; + } + + if (ctx->buf_bytes > 0) { + /* pad the rest of ctx->buf and write it out */ + rc = flash_sync(ctx); - flash_write_protection_set(ctx->dev, false); - rc = flash_write(ctx->dev, offset + ctx->bytes_written, - ctx->buf, CONFIG_IMG_BLOCK_BUF_SIZE); - flash_write_protection_set(ctx->dev, true); if (rc) { - LOG_ERR("flash_write error %d offset=0x%08"PRIx32, - rc, (u32_t)(offset + ctx->bytes_written)); return rc; } - - if (!flash_verify(ctx->dev, offset + ctx->bytes_written, - ctx->buf, CONFIG_IMG_BLOCK_BUF_SIZE)) { - return -EIO; - } - - ctx->bytes_written = ctx->bytes_written + ctx->buf_bytes; - ctx->buf_bytes = 0; } + flash_area_close(ctx->flash_area); + ctx->flash_area = NULL; + return rc; } @@ -124,16 +133,10 @@ size_t flash_img_bytes_written(struct flash_img_context *ctx) return ctx->bytes_written; } -void flash_img_init(struct flash_img_context *ctx, struct device *dev) +int flash_img_init(struct flash_img_context *ctx) { - ctx->dev = dev; ctx->bytes_written = 0; ctx->buf_bytes = 0; -} - -int flash_img_buffered_write(struct flash_img_context *ctx, u8_t *data, - size_t len, bool flush) -{ - return flash_block_write(ctx, FLASH_AREA_IMAGE_1_OFFSET, data, len, - flush); + return flash_area_open(DT_FLASH_AREA_IMAGE_1_ID, + (const struct flash_area **)&(ctx->flash_area)); } diff --git a/tests/subsys/dfu/img_util/src/main.c b/tests/subsys/dfu/img_util/src/main.c index 3904e5a1a63..1ee63ae2f19 100644 --- a/tests/subsys/dfu/img_util/src/main.c +++ b/tests/subsys/dfu/img_util/src/main.c @@ -5,24 +5,23 @@ */ #include -#include +#include #include void test_collecting(void) { - struct device *flash_dev; + const struct flash_area *fa; struct flash_img_context ctx; u32_t i, j; u8_t data[5], temp, k; + int ret; - flash_dev = device_get_binding(DT_FLASH_DEV_NAME); + ret = flash_img_init(&ctx); + zassert_true(ret == 0, "Flash img init"); - flash_write_protection_set(flash_dev, false); - flash_erase(flash_dev, FLASH_AREA_IMAGE_1_OFFSET, - FLASH_AREA_IMAGE_1_SIZE); - flash_write_protection_set(flash_dev, true); + ret = flash_area_erase(ctx.flash_area, 0, ctx.flash_area->fa_size); + zassert_true(ret == 0, "Flash erase"); - flash_img_init(&ctx, flash_dev); zassert(flash_img_bytes_written(&ctx) == 0, "pass", "fail"); k = 0U; @@ -37,10 +36,16 @@ void test_collecting(void) zassert(flash_img_buffered_write(&ctx, data, 0, true) == 0, "pass", "fail"); + + ret = flash_area_open(DT_FLASH_AREA_IMAGE_1_ID, &fa); + if (ret) { + printf("Flash driver was not found!\n"); + return; + } + k = 0U; for (i = 0U; i < 300 * sizeof(data); i++) { - zassert(flash_read(flash_dev, FLASH_AREA_IMAGE_1_OFFSET + i, - &temp, 1) == 0, "pass", "fail"); + zassert(flash_area_read(fa, i, &temp, 1) == 0, "pass", "fail"); zassert(temp == k, "pass", "fail"); k++; }