This is an automated email from the ASF dual-hosted git repository. ccollins pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-mcumgr.git
commit e5ec68560e40fb279a39a13ad5cc754ec636ceab Author: Christopher Collins <ccoll...@apache.org> AuthorDate: Wed Jan 17 17:15:18 2018 -0800 Zephyr support. --- CMakeLists.txt | 12 ++ Kconfig | 29 ++++ cmd/CMakeLists.txt | 3 + cmd/Kconfig | 24 +++ cmd/fs_mgmt/CMakeLists.txt | 9 + cmd/fs_mgmt/Kconfig | 50 ++++++ cmd/fs_mgmt/port/zephyr/src/zephyr_fs_mgmt.c | 151 ++++++++++++++++ cmd/img_mgmt/CMakeLists.txt | 11 ++ cmd/img_mgmt/Kconfig | 38 +++++ cmd/img_mgmt/port/zephyr/src/zephyr_img_mgmt.c | 227 +++++++++++++++++++++++++ cmd/os_mgmt/CMakeLists.txt | 9 + cmd/os_mgmt/Kconfig | 35 ++++ cmd/os_mgmt/port/zephyr/src/zephyr_os_mgmt.c | 85 +++++++++ ext/CMakeLists.txt | 2 + 14 files changed, 685 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a88725a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,12 @@ +add_library(MCUMGR INTERFACE) + +zephyr_library() +add_subdirectory(cborattr) +add_subdirectory(cmd) +add_subdirectory(ext) +add_subdirectory(mgmt) +add_subdirectory(smp) + +zephyr_library_link_libraries(MCUMGR) + +target_link_libraries(MCUMGR INTERFACE zephyr_interface BASE64 TINYCBOR) diff --git a/Kconfig b/Kconfig new file mode 100644 index 0000000..89de3ee --- /dev/null +++ b/Kconfig @@ -0,0 +1,29 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +menuconfig MCUMGR + bool + prompt "mcumgr Support" + select TINYCBOR + default n + help + This option enables the mcumgr management library. + +if MCUMGR +source "ext/mcumgr/mgmt/port/zephyr/Kconfig" +source "ext/mcumgr/cmd/Kconfig" +endif diff --git a/cmd/CMakeLists.txt b/cmd/CMakeLists.txt new file mode 100644 index 0000000..bc91e2f --- /dev/null +++ b/cmd/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory_ifdef(CONFIG_MCUMGR_CMD_FS_MGMT fs_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_CMD_IMG_MGMT img_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_CMD_OS_MGMT os_mgmt) diff --git a/cmd/Kconfig b/cmd/Kconfig new file mode 100644 index 0000000..a0e2031 --- /dev/null +++ b/cmd/Kconfig @@ -0,0 +1,24 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +menu "Command handlers" + +source "ext/mcumgr/cmd/fs_mgmt/Kconfig" +source "ext/mcumgr/cmd/img_mgmt/Kconfig" +source "ext/mcumgr/cmd/os_mgmt/Kconfig" + +endmenu diff --git a/cmd/fs_mgmt/CMakeLists.txt b/cmd/fs_mgmt/CMakeLists.txt new file mode 100644 index 0000000..974d0a9 --- /dev/null +++ b/cmd/fs_mgmt/CMakeLists.txt @@ -0,0 +1,9 @@ +target_include_directories(MCUMGR INTERFACE + include +) + +zephyr_library_sources( + cmd/fs_mgmt/port/zephyr/src/zephyr_fs_mgmt.c + cmd/fs_mgmt/src/fs_mgmt.c + cmd/fs_mgmt/src/stubs.c +) diff --git a/cmd/fs_mgmt/Kconfig b/cmd/fs_mgmt/Kconfig new file mode 100644 index 0000000..62602d6 --- /dev/null +++ b/cmd/fs_mgmt/Kconfig @@ -0,0 +1,50 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# Under the License. + +menuconfig MCUMGR_CMD_FS_MGMT + bool + prompt "Enable mcumgr handlers for file management" + default n + help + Enables mcumgr handlers for file management + +if MCUMGR_CMD_FS_MGMT +config FS_MGMT_UL_CHUNK_SIZE + int + prompt "Maximum chunk size for file uploads" + default 512 + help + Limits the maximum chunk size in file uploads. A buffer of this size + gets allocated on the stack during handling of a file upload command. + +config FS_MGMT_DL_CHUNK_SIZE + int + prompt "Maximum chunk size for file downloads" + default 512 + help + Limits the maximum chunk size in file downloads. A buffer of this size + gets allocated on the stack during handling of a file download command. + +config FS_MGMT_PATH_SIZE + int + prompt "Maximum file path length" + default 64 + help + Limits the maximum path length in file operations. A buffer of this size + gets allocated on the stack during handling of file upload and download + commands. +endif diff --git a/cmd/fs_mgmt/port/zephyr/src/zephyr_fs_mgmt.c b/cmd/fs_mgmt/port/zephyr/src/zephyr_fs_mgmt.c new file mode 100644 index 0000000..42b7d80 --- /dev/null +++ b/cmd/fs_mgmt/port/zephyr/src/zephyr_fs_mgmt.c @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "mgmt/mgmt.h" +#include "fs_mgmt/fs_mgmt_impl.h" +#include "fs.h" + +int +fs_mgmt_impl_filelen(const char *path, size_t *out_len) +{ + struct fs_dirent dirent; + int rc; + + rc = fs_stat(path, &dirent); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + if (dirent.type != FS_DIR_ENTRY_FILE) { + return MGMT_ERR_EUNKNOWN; + } + + *out_len = dirent.size; + + return 0; +} + +int +fs_mgmt_impl_read(const char *path, size_t offset, size_t len, + void *out_data, size_t *out_len) +{ + fs_file_t file; + ssize_t bytes_read; + int rc; + + rc = fs_open(&file, path); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + rc = fs_seek(&file, offset, FS_SEEK_SET); + if (rc != 0) { + goto done; + } + + bytes_read = fs_read(&file, out_data, len); + if (bytes_read < 0) { + goto done; + } + + *out_len = bytes_read; + +done: + fs_close(&file); + + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } else { + return 0; + } +} + +static int +zephyr_fs_mgmt_truncate(const char *path) +{ + size_t len; + int rc; + + /* Attempt to get the length of the file at the specified path. This is a + * quick way to determine if there is already a file there. + */ + rc = fs_mgmt_impl_filelen(path, &len); + if (rc == 0) { + /* There is already a file with the specified path. Unlink it to + * simulate a truncate operation. + * + * XXX: This isn't perfect - if the file is currently open, the unlink + * operation won't actually delete the file. Consequently, the file + * will get partially overwritten rather than truncated. The NFFS port + * doesn't support the truncate operation, so this is an imperfect + * workaround. + */ + rc = fs_unlink(path); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + } + + return 0; +} + +int +fs_mgmt_impl_write(const char *path, size_t offset, const void *data, + size_t len) +{ + fs_file_t file; + int rc; + + /* Truncate the file before writing the first chunk. This is done to + * properly handle an overwrite of an existing file. + * + */ + if (offset == 0) { + rc = zephyr_fs_mgmt_truncate(path); + if (rc != 0) { + return rc; + } + } + + rc = fs_open(&file, path); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + rc = fs_seek(&file, offset, FS_SEEK_SET); + if (rc != 0) { + goto done; + } + + rc = fs_write(&file, data, len); + if (rc < 0) { + goto done; + } + + rc = 0; + +done: + fs_close(&file); + + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } else { + return 0; + } +} diff --git a/cmd/img_mgmt/CMakeLists.txt b/cmd/img_mgmt/CMakeLists.txt new file mode 100644 index 0000000..9b52e71 --- /dev/null +++ b/cmd/img_mgmt/CMakeLists.txt @@ -0,0 +1,11 @@ +target_include_directories(MCUMGR INTERFACE + include +) + +zephyr_library_sources( + cmd/img_mgmt/port/zephyr/src/zephyr_img_mgmt.c + cmd/img_mgmt/src/img_mgmt.c + cmd/img_mgmt/src/img_mgmt_state.c + cmd/img_mgmt/src/img_mgmt_util.c + cmd/img_mgmt/src/stubs.c +) diff --git a/cmd/img_mgmt/Kconfig b/cmd/img_mgmt/Kconfig new file mode 100644 index 0000000..2ac6c61 --- /dev/null +++ b/cmd/img_mgmt/Kconfig @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE image +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this image +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this image except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# Under the License. + +menuconfig MCUMGR_CMD_IMG_MGMT + bool + prompt "Enable mcumgr handlers for image management" + select FLASH + select MPU_ALLOW_FLASH_WRITE + select IMG_MANAGER + select MCUBOOT_IMG_MANAGER + + default n + help + Enables mcumgr handlers for image management + +if MCUMGR_CMD_IMG_MGMT +config IMG_MGMT_UL_CHUNK_SIZE + int + prompt "Maximum chunk size for image uploads" + default 512 + help + Limits the maximum chunk size in image uploads. A buffer of this size + gets allocated on the stack during handling of a image upload command. +endif diff --git a/cmd/img_mgmt/port/zephyr/src/zephyr_img_mgmt.c b/cmd/img_mgmt/port/zephyr/src/zephyr_img_mgmt.c new file mode 100644 index 0000000..dc71d8f --- /dev/null +++ b/cmd/img_mgmt/port/zephyr/src/zephyr_img_mgmt.c @@ -0,0 +1,227 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <assert.h> +#include <flash.h> +#include <zephyr.h> +#include <soc.h> +#include <init.h> +#include <dfu/mcuboot.h> +#include <dfu/flash_img.h> +#include "mgmt/mgmt.h" +#include "img_mgmt/img_mgmt_impl.h" +#include "img_mgmt/img_mgmt.h" +#include "../../../src/img_mgmt_priv.h" + +static struct device *zephyr_img_flash_dev; +static struct flash_img_context zephyr_img_flash_ctxt; + +/** + * Determines if the specified area of flash is completely unwritten. + */ +static int +img_mgmt_impl_flash_check_empty(off_t offset, size_t size, bool *out_empty) +{ + uint32_t data[16]; + off_t addr; + off_t end; + int bytes_to_read; + int rc; + int i; + + assert(size % 4 == 0); + + end = offset + size; + for (addr = offset; addr < end; addr += sizeof data) { + if (end - addr < sizeof data) { + bytes_to_read = end - addr; + } else { + bytes_to_read = sizeof data; + } + + rc = flash_read(zephyr_img_flash_dev, addr, data, bytes_to_read); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + for (i = 0; i < bytes_to_read / 4; i++) { + if (data[i] != 0xffffffff) { + *out_empty = false; + return 0; + } + } + } + + *out_empty = true; + return 0; +} + +/** + * Converts an offset within an image slot to an absolute address. + */ +static off_t +img_mgmt_impl_abs_offset(int slot, off_t sub_offset) +{ + off_t slot_start; + + switch (slot) { + case 0: + slot_start = FLASH_AREA_IMAGE_0_OFFSET; + break; + + case 1: + slot_start = FLASH_AREA_IMAGE_1_OFFSET; + break; + + default: + assert(0); + slot_start = FLASH_AREA_IMAGE_1_OFFSET; + break; + } + + return slot_start + sub_offset; +} + +int +img_mgmt_impl_erase_slot(void) +{ + bool empty; + int rc; + + rc = img_mgmt_impl_flash_check_empty(FLASH_AREA_IMAGE_1_OFFSET, + FLASH_AREA_IMAGE_1_SIZE, + &empty); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + if (!empty) { + rc = boot_erase_img_bank(FLASH_AREA_IMAGE_1_OFFSET); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + } + + return 0; +} + +int +img_mgmt_impl_write_pending(int slot, bool permanent) +{ + int rc; + + if (slot != 1) { + return MGMT_ERR_EINVAL; + } + + rc = boot_request_upgrade(permanent); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + return 0; +} + +int +img_mgmt_impl_write_confirmed(void) +{ + int rc; + + rc = boot_write_img_confirmed(); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + return 0; +} + +int +img_mgmt_impl_read(int slot, unsigned int offset, void *dst, + unsigned int num_bytes) +{ + off_t abs_offset; + int rc; + + abs_offset = img_mgmt_impl_abs_offset(slot, offset); + rc = flash_read(zephyr_img_flash_dev, abs_offset, dst, num_bytes); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + return 0; +} + +int +img_mgmt_impl_write_image_data(unsigned int offset, const void *data, + unsigned int num_bytes, bool last) +{ + int rc; + + if (offset == 0) { + flash_img_init(&zephyr_img_flash_ctxt, zephyr_img_flash_dev); + } + + /* Cast away const. */ + rc = flash_img_buffered_write(&zephyr_img_flash_ctxt, (void *)data, + num_bytes, false); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + + if (last) { + rc = flash_img_buffered_write(&zephyr_img_flash_ctxt, NULL, 0, true); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + } + + return 0; +} + +int +img_mgmt_impl_swap_type(void) +{ + switch (boot_swap_type()) { + case BOOT_SWAP_TYPE_NONE: + return IMG_MGMT_SWAP_TYPE_NONE; + case BOOT_SWAP_TYPE_TEST: + return IMG_MGMT_SWAP_TYPE_TEST; + case BOOT_SWAP_TYPE_PERM: + return IMG_MGMT_SWAP_TYPE_PERM; + case BOOT_SWAP_TYPE_REVERT: + return IMG_MGMT_SWAP_TYPE_REVERT; + default: + assert(0); + return IMG_MGMT_SWAP_TYPE_NONE; + } +} + +static int +img_mgmt_impl_init(struct device *dev) +{ + ARG_UNUSED(dev); + + zephyr_img_flash_dev = device_get_binding(FLASH_DRIVER_NAME); + if (zephyr_img_flash_dev == NULL) { + return -ENODEV; + } + return 0; +} + +SYS_INIT(img_mgmt_impl_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/cmd/os_mgmt/CMakeLists.txt b/cmd/os_mgmt/CMakeLists.txt new file mode 100644 index 0000000..0a9176a --- /dev/null +++ b/cmd/os_mgmt/CMakeLists.txt @@ -0,0 +1,9 @@ +target_include_directories(MCUMGR INTERFACE + include +) + +zephyr_library_sources( + cmd/os_mgmt/port/zephyr/src/zephyr_os_mgmt.c + cmd/os_mgmt/src/os_mgmt.c + cmd/os_mgmt/src/stubs.c +) diff --git a/cmd/os_mgmt/Kconfig b/cmd/os_mgmt/Kconfig new file mode 100644 index 0000000..10f0abc --- /dev/null +++ b/cmd/os_mgmt/Kconfig @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE image +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this image +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this image except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# Under the License. + +menuconfig MCUMGR_CMD_OS_MGMT + bool + prompt "Enable mcumgr handlers for OS management" + select REBOOT + default n + help + Enables mcumgr handlers for OS management + +if MCUMGR_CMD_OS_MGMT +config OS_MGMT_RESET_MS + int + prompt "Delay before executing reset command (ms)" + default 250 + help + When a reset command is received, the system waits this many milliseconds + before performing the reset. This delay allows time for the mcumgr + response to be delivered. +endif diff --git a/cmd/os_mgmt/port/zephyr/src/zephyr_os_mgmt.c b/cmd/os_mgmt/port/zephyr/src/zephyr_os_mgmt.c new file mode 100644 index 0000000..221da97 --- /dev/null +++ b/cmd/os_mgmt/port/zephyr/src/zephyr_os_mgmt.c @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <zephyr.h> +#include <misc/reboot.h> +#include <debug/object_tracing.h> +#include <kernel_structs.h> +#include "mgmt/mgmt.h" +#include "os_mgmt/os_mgmt.h" +#include "os_mgmt/os_mgmt_impl.h" + +static void zephyr_os_mgmt_reset_cb(struct k_timer *timer); + +static K_TIMER_DEFINE(zephyr_os_mgmt_reset_timer, + zephyr_os_mgmt_reset_cb, NULL); + +#ifdef CONFIG_THREAD_MONITOR +static const struct k_thread * +zephyr_os_mgmt_task_at(int idx) +{ + const struct k_thread *thread; + int i; + + thread = SYS_THREAD_MONITOR_HEAD; + for (i = 0; i < idx; i++) { + if (thread == NULL) { + break; + } + thread = SYS_THREAD_MONITOR_NEXT(thread); + } + + return thread; +} + +int +os_mgmt_impl_task_info(int idx, struct os_mgmt_task_info *out_info) +{ + const struct k_thread *thread; + + thread = zephyr_os_mgmt_task_at(idx); + if (thread == NULL) { + return MGMT_ERR_ENOENT; + } + + *out_info = (struct os_mgmt_task_info){ 0 }; + + snprintf(out_info->oti_name, sizeof out_info->oti_name, "%d", + thread->base.prio); + out_info->oti_prio = thread->base.prio; + out_info->oti_taskid = idx; + out_info->oti_state = thread->base.thread_state; + out_info->oti_stksize = thread->stack_info.size / 4; + + return 0; +} +#endif /* CONFIG_THREAD_MONITOR */ + +static void +zephyr_os_mgmt_reset_cb(struct k_timer *timer) +{ + sys_reboot(SYS_REBOOT_WARM); +} + +int +os_mgmt_impl_reset(unsigned int delay_ms) +{ + k_timer_start(&zephyr_os_mgmt_reset_timer, K_MSEC(delay_ms), 0); + return 0; +} diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt new file mode 100644 index 0000000..f32ffb5 --- /dev/null +++ b/ext/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(base64) +add_subdirectory(tinycbor) -- To stop receiving notification emails like this one, please contact ccoll...@apache.org.