diff --git a/README.md b/README.md index 286f82d..736c07f 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ not require MCUboot. The `mcumgr` command line tool is available at: https://github.com/apache/mynewt-mcumgr-cli. The command line tool requires [Go -1.7 or later](https://golang.org/dl/). Once Go is installed and set up on your +1.12 or later](https://golang.org/dl/). Once Go is installed and set up on your system, you can install the mcumgr CLI tool by issuing the following `go get` command: diff --git a/cmd/img_mgmt/include/img_mgmt/img_mgmt_config.h b/cmd/img_mgmt/include/img_mgmt/img_mgmt_config.h index 928c525..1a0b1cd 100644 --- a/cmd/img_mgmt/include/img_mgmt/img_mgmt_config.h +++ b/cmd/img_mgmt/include/img_mgmt/img_mgmt_config.h @@ -40,8 +40,12 @@ #define IMG_MGMT_LAZY_ERASE CONFIG_IMG_ERASE_PROGRESSIVELY #define IMG_MGMT_DUMMY_HDR CONFIG_IMG_MGMT_DUMMY_HDR #define IMG_MGMT_BOOT_CURR_SLOT 0 +#ifdef CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER +/* Up to two images are supported */ +BUILD_ASSERT(CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER > 2, "Unsupported number of images"); #undef IMG_MGMT_UPDATABLE_IMAGE_NUMBER #define IMG_MGMT_UPDATABLE_IMAGE_NUMBER CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER +#endif /* No direct support for this OS. The application needs to define the above * settings itself. diff --git a/cmd/img_mgmt/port/zephyr/src/zephyr_img_mgmt.c b/cmd/img_mgmt/port/zephyr/src/zephyr_img_mgmt.c index 0cfe637..e1cfcdb 100644 --- a/cmd/img_mgmt/port/zephyr/src/zephyr_img_mgmt.c +++ b/cmd/img_mgmt/port/zephyr/src/zephyr_img_mgmt.c @@ -36,8 +36,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include "../../../src/img_mgmt_priv.h" -BUILD_ASSERT(CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 1 || - (CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 2 && +BUILD_ASSERT(IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 1 || + (IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 2 && FLASH_AREA_LABEL_EXISTS(image_2) && FLASH_AREA_LABEL_EXISTS(image_3)), "Missing partitions?"); @@ -153,7 +153,7 @@ zephyr_img_mgmt_flash_area_id(int slot) return fa_id; } -#if CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 1 +#if IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 1 /** * In normal operation this function will select between first two slot * (in reality it just checks whether second slot can be used), ignoring the @@ -199,20 +199,18 @@ img_mgmt_get_unused_slot_area_id(int slot) return slot != -1 ? zephyr_img_mgmt_flash_area_id(slot) : -1; #endif } -#elif CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 2 +#elif IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 2 static int img_mgmt_get_unused_slot_area_id(int image) { int area_id = -1; - if (image == 0) { + if (image == 0 || image == -1) { if (img_mgmt_slot_in_use(1) == 0) { area_id = zephyr_img_mgmt_flash_area_id(1); } } else if (image == 1) { area_id = zephyr_img_mgmt_flash_area_id(3); - } else { - assert(0); } return area_id; @@ -266,7 +264,7 @@ img_mgmt_impl_erase_slot(void) /* Select any non-active, unused slot */ best_id = img_mgmt_get_unused_slot_area_id(-1); if (best_id < 0) { - return MGMT_ERR_EUNKNOWN; + return MGMT_ERR_ENOENT; } rc = zephyr_img_mgmt_flash_check_empty(best_id, &empty); if (rc != 0) { @@ -289,7 +287,7 @@ img_mgmt_impl_write_pending(int slot, bool permanent) int rc; if (slot != 1 && - !(CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 2 && slot == 3)) { + !(IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 2 && slot == 3)) { return MGMT_ERR_EINVAL; } @@ -337,59 +335,83 @@ img_mgmt_impl_read(int slot, unsigned int offset, void *dst, return 0; } +/* + * The alloc_ctx and free_ctx are specifically provided for + * the img_mgmt_impl_write_image_data to allocate/free single flash_img_context + * type buffer. + * When heap is enabled these functions will operate on heap; when heap is not + * allocated the alloc_ctx just returns pointer to static, global life-time + * variable, and free_ctx does nothing. + * CONFIG_HEAP_MEM_POOL_SIZE is C preprocessor literal. + */ +static inline struct flash_img_context *alloc_ctx(void) +{ + struct flash_img_context *ctx = NULL; + + if (CONFIG_HEAP_MEM_POOL_SIZE > 0) { + ctx = k_malloc(sizeof(*ctx)); + } else { + static struct flash_img_context stcx; + ctx = &stcx; + } + return ctx; +} + +static inline void free_ctx(struct flash_img_context *ctx) +{ + if (CONFIG_HEAP_MEM_POOL_SIZE > 0) { + k_free(ctx); + } +} + int img_mgmt_impl_write_image_data(unsigned int offset, const void *data, unsigned int num_bytes, bool last) { - int rc; -#if (CONFIG_HEAP_MEM_POOL_SIZE > 0) - static struct flash_img_context *ctx = NULL; -#else - static struct flash_img_context ctx_data; -#define ctx (&ctx_data) -#endif + int rc = 0; + static struct flash_img_context *ctx = NULL; -#if (CONFIG_HEAP_MEM_POOL_SIZE > 0) - if (offset != 0 && ctx == NULL) { - return MGMT_ERR_EUNKNOWN; - } -#endif + if (CONFIG_HEAP_MEM_POOL_SIZE > 0 && offset != 0 && ctx == NULL) { + return MGMT_ERR_EUNKNOWN; + } - if (offset == 0) { -#if (CONFIG_HEAP_MEM_POOL_SIZE > 0) - if (ctx == NULL) { - ctx = k_malloc(sizeof(*ctx)); + if (offset == 0) { + if (ctx == NULL) { + ctx = alloc_ctx(); - if (ctx == NULL) { - return MGMT_ERR_ENOMEM; - } - } -#endif - rc = flash_img_init_id(ctx, g_img_mgmt_state.area_id); + if (ctx == NULL) { + rc = MGMT_ERR_ENOMEM; + goto out; + } + } - if (rc != 0) { - return MGMT_ERR_EUNKNOWN; - } - } + rc = flash_img_init_id(ctx, g_img_mgmt_state.area_id); - if (offset != ctx->stream.bytes_written + ctx->stream.buf_bytes) { - return MGMT_ERR_EUNKNOWN; - } + if (rc != 0) { + rc = MGMT_ERR_EUNKNOWN; + goto out; + } + } - /* Cast away const. */ - rc = flash_img_buffered_write(ctx, (void *)data, num_bytes, last); - if (rc != 0) { - return MGMT_ERR_EUNKNOWN; - } + if (offset != ctx->stream.bytes_written + ctx->stream.buf_bytes) { + rc = MGMT_ERR_EUNKNOWN; + goto out; + } -#if (CONFIG_HEAP_MEM_POOL_SIZE > 0) - if (last) { - k_free(ctx); - ctx = NULL; - } -#endif + /* Cast away const. */ + rc = flash_img_buffered_write(ctx, (void *)data, num_bytes, last); + if (rc != 0) { + rc = MGMT_ERR_EUNKNOWN; + goto out; + } - return 0; +out: + if (CONFIG_HEAP_MEM_POOL_SIZE > 0 && (last || rc != 0)) { + k_free(ctx); + ctx = NULL; + } + + return rc; } int @@ -569,7 +591,7 @@ img_mgmt_impl_upload_inspect(const struct img_mgmt_upload_req *req, if (action->area_id < 0) { /* No slot where to upload! */ *errstr = img_mgmt_err_str_no_slot; - return MGMT_ERR_ENOMEM; + return MGMT_ERR_ENOENT; } diff --git a/cmd/img_mgmt/src/img_mgmt.c b/cmd/img_mgmt/src/img_mgmt.c index b86d0ae..6e28906 100644 --- a/cmd/img_mgmt/src/img_mgmt.c +++ b/cmd/img_mgmt/src/img_mgmt.c @@ -515,6 +515,8 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt) } } #endif + } else { + cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_ONGOING; } /* Write the image data to flash. */ @@ -542,7 +544,7 @@ img_mgmt_upload(struct mgmt_ctxt *ctxt) if (g_img_mgmt_state.off == g_img_mgmt_state.size) { /* Done */ img_mgmt_dfu_pending(); - cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_ONGOING; + cmd_status_arg.status = IMG_MGMT_ID_UPLOAD_STATUS_COMPLETE; g_img_mgmt_state.area_id = -1; } } diff --git a/samples/smp_svr/zephyr/prj.conf b/samples/smp_svr/zephyr/prj.conf index 61b775e..b0d4e0f 100644 --- a/samples/smp_svr/zephyr/prj.conf +++ b/samples/smp_svr/zephyr/prj.conf @@ -3,6 +3,7 @@ CONFIG_MCUMGR=y # Some command handlers require a large stack. CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304 +CONFIG_MAIN_STACK_SIZE=2048 # Ensure an MCUboot-compatible binary is generated. CONFIG_BOOTLOADER_MCUBOOT=y