DFU: add module for store the image
Store image in sequence of certain blocks. Module is intended to be use by a higher-level image management protocol module Signed-off-by: Michael Scott <michael.scott@linaro.org> Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org> Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
This commit is contained in:
parent
49fccdd2ea
commit
25c6610a65
5 changed files with 231 additions and 0 deletions
3
subsys/dfu/img_util/Makefile
Normal file
3
subsys/dfu/img_util/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
obj-$(CONFIG_MCUBOOT_IMG_MANAGER) += flash_img.o
|
||||
ccflags-$(CONFIG_MCUBOOT_IMG_MANAGER) += -I${ZEPHYR_BASE}/include/dfu
|
||||
ccflags-$(CONFIG_MCUBOOT_IMG_MANAGER) += -I${ZEPHYR_BASE}/subsys/dfu
|
137
subsys/dfu/img_util/flash_img.c
Normal file
137
subsys/dfu/img_util/flash_img.c
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2017 Linaro Limited
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define SYS_LOG_DOMAIN "fota/flash_block"
|
||||
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_IMG_MANAGER_LEVEL
|
||||
#include <logging/sys_log.h>
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <flash.h>
|
||||
#include "boot/mcuboot_constraints.h"
|
||||
#include "flash_img.h"
|
||||
|
||||
BUILD_ASSERT_MSG((CONFIG_IMG_BLOCK_BUF_SIZE % FLASH_ALIGN == 0),
|
||||
"CONFIG_IMG_BLOCK_BUF_SIZE is not multiple of FLASH_ALIGN");
|
||||
|
||||
static bool flash_verify(struct device *dev, off_t offset,
|
||||
u8_t *data, size_t len)
|
||||
{
|
||||
size_t size;
|
||||
u32_t temp;
|
||||
int rc;
|
||||
|
||||
while (len) {
|
||||
size = (len >= sizeof(temp)) ? sizeof(temp) : len;
|
||||
rc = flash_read(dev, offset, &temp, size);
|
||||
if (rc) {
|
||||
SYS_LOG_ERR("flash_read error %d offset=0x%08x",
|
||||
rc, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
if (memcmp(data, &temp, size)) {
|
||||
SYS_LOG_ERR("offset=0x%08x VERIFY FAIL. "
|
||||
"expected: 0x%08x, actual: 0x%08x",
|
||||
offset, temp, *(__packed u32_t*)data);
|
||||
break;
|
||||
}
|
||||
len -= size;
|
||||
offset += size;
|
||||
data += size;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int processed = 0;
|
||||
int rc = 0;
|
||||
|
||||
while ((len - processed) >
|
||||
(CONFIG_IMG_BLOCK_BUF_SIZE - ctx->buf_bytes)) {
|
||||
memcpy(ctx->buf + ctx->buf_bytes, data + processed,
|
||||
(CONFIG_IMG_BLOCK_BUF_SIZE - ctx->buf_bytes));
|
||||
|
||||
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) {
|
||||
SYS_LOG_ERR("flash_write error %d offset=0x%08x",
|
||||
rc, 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;
|
||||
}
|
||||
|
||||
/* place rest of the data into ctx->buf */
|
||||
if (processed < len) {
|
||||
memcpy(ctx->buf + ctx->buf_bytes,
|
||||
data + processed, len - processed);
|
||||
ctx->buf_bytes += len - processed;
|
||||
}
|
||||
|
||||
if (finished && ctx->buf_bytes > 0) {
|
||||
/* pad the rest of ctx->buf and write it out */
|
||||
memset(ctx->buf + ctx->buf_bytes, 0xFF,
|
||||
CONFIG_IMG_BLOCK_BUF_SIZE - ctx->buf_bytes);
|
||||
|
||||
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) {
|
||||
SYS_LOG_ERR("flash_write error %d offset=0x%08x",
|
||||
rc, 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;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue