diff --git a/.editorconfig-checker.json b/.editorconfig-checker.json index 378291c67..7fb58abf3 100644 --- a/.editorconfig-checker.json +++ b/.editorconfig-checker.json @@ -12,6 +12,10 @@ "loader/blobs/", "llext-edk/", "extra/build.sh", + "extra/bootstrap.sh", + "extra/package_tool.sh", + "\\.github/workflows/package_core\\.yml", + "\\.github/workflows/package_tool\\.yml", "loader/CMakeLists.txt", "^CMakeLists\\.txt$" ] diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ed4f36657..62e42f6ff 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,6 +13,11 @@ updates: schedule: interval: "weekly" + - package-ecosystem: "gomod" + directory: "/tools/mcumgr" + schedule: + interval: "weekly" + - package-ecosystem: "gomod" directory: "/tools/sync-zephyr-artifacts" schedule: diff --git a/.github/workflows/package_core.yml b/.github/workflows/package_core.yml index 754d67f3b..1b7f39508 100644 --- a/.github/workflows/package_core.yml +++ b/.github/workflows/package_core.yml @@ -221,11 +221,12 @@ jobs: grep -i "warning:" $REPORT.stdout > $REPORT.warnings || true # extract the memory usage table (from the header to the first non-% line) + # There is one table per image with sysbuild, so skip the MCUboot one. # override the size of the Flash with the size of the loader partition # and add the size of the sketch partition (not reported by Zephyr) LOADER_SIZE=$(( $(cat variants/${{ matrix.variant }}/syms-static.ld | grep '_loader_max_size' | cut -d '=' -f 2 | tr -d ') ;') )) SKETCH_SIZE=$(( $(cat variants/${{ matrix.variant }}/syms-static.ld | grep '_sketch_max_size' | cut -d '=' -f 2 | tr -d ') ;') )) - cat $REPORT.stdout | sed -n '/^Memory region/,/^[^%]*$/p' | head -n -1 \ + cat $REPORT.stdout | awk '/^Memory region/ {t=""; f=1; next} f && /%/ {t=t $0 "\n"; next} f {f=0; if ($0 !~ /\/mcuboot\//) printf "%s", t}' \ | awk 'BEGIN {split("B KB MB GB", u); for(i in u) m[u[i]]=1024^(i-1)} /:/ {print "[\"" $1 "\"," $2*m[$3] "," $4*m[$5] "]"}' \ | sort \ | jq -s "map((select(.[0] == \"FLASH:\") | .[2]) |= ${LOADER_SIZE}) + [ [ \"SKETCH:\", 0, ${SKETCH_SIZE} ] ]" > $REPORT.meminfo @@ -245,7 +246,7 @@ jobs: ls reports/* >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV - # Preprare an archive of the built binaries (and build dir on failure) + # Prepare an archive of the built binaries (and build dir on failure) [ "${{ job.status }}" == "failure" ] && FULL_BUILD_DIR="build/${{ matrix.variant }}/" sed -e '/^#/d' boards.local.txt > boards.local_${{ matrix.variant }}.txt tar chf - \ diff --git a/.github/workflows/package_tool.yml b/.github/workflows/package_tool.yml index bacd2afbd..90f130833 100644 --- a/.github/workflows/package_tool.yml +++ b/.github/workflows/package_tool.yml @@ -97,7 +97,8 @@ jobs: build-tool: name: Build ${{ matrix.tool }} ${{ matrix.version }} needs: setup - runs-on: ubuntu-latest + # MCUmgr's macOS binaries need cgo, so they cannot be cross-compiled on Linux. + runs-on: ${{ matrix.tool == 'mcumgr' && 'macos-latest' || 'ubuntu-latest' }} strategy: matrix: ${{ fromJSON(needs.setup.outputs.matrix) }} steps: diff --git a/.github/workflows/rak-build.yml b/.github/workflows/rak-build.yml index b31cb4d1a..bfaa1357e 100644 --- a/.github/workflows/rak-build.yml +++ b/.github/workflows/rak-build.yml @@ -67,7 +67,7 @@ jobs: run: | mkdir -p venv/bin && touch venv/bin/activate ./extra/build.sh nrf52840dk - ./extra/build.sh rak4631 --mcuboot + ./extra/build.sh rak4631 - name: Build samples # Standalone Zephyr build of the samples. The sample list comes diff --git a/.vscode/flash_loader.jlink b/.vscode/flash_loader.jlink index 57fccf76c..8f66b95eb 100644 --- a/.vscode/flash_loader.jlink +++ b/.vscode/flash_loader.jlink @@ -1,4 +1,4 @@ -loadfile firmwares/mcuboot-rak4631_nrf52840.hex +loadfile firmwares/zephyr-rak4631_nrf52840.mcuboot.hex loadfile firmwares/zephyr-rak4631_nrf52840.hex r g diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d264e2e70..d2ddafae6 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -34,7 +34,6 @@ "args": [ "${BOARD_ARD}", // "--debug", - "--mcuboot" ], "group": "build", "problemMatcher": ["$gcc"] diff --git a/boards.txt b/boards.txt index 2af8b76a9..6b788f6b4 100644 --- a/boards.txt +++ b/boards.txt @@ -795,7 +795,7 @@ rak4631.menu.baseboard.rak19007=RAK19007 rak4631.menu.baseboard.rak19007.build.extra_flags=-DWISBLOCK_BASE_19007 rak4631.build.zephyr_target=rak4631/nrf52840 -rak4631.build.zephyr_args= +rak4631.build.zephyr_args=--sysbuild rak4631.build.zephyr_hals=hal_nordic rak4631.build.zephyr_toolchain=arm-zephyr-eabi rak4631.build.variant=rak4631_nrf52840 @@ -803,12 +803,12 @@ rak4631.build.variant=rak4631_nrf52840 rak4631.build.extra_flags= rak4631.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit rak4631.build.board=RAK4631 -rak4631.vid.0=0x1915 -rak4631.pid.0=0x5300 -rak4631.upload_port.0.vid=0x1915 -rak4631.upload_port.0.pid=0x5300 -rak4631.upload_port.1.vid=0x1915 -rak4631.upload_port.1.pid=0x5301 +rak4631.vid.0=0x1209 +rak4631.pid.0=0x0003 +rak4631.upload_port.0.vid=0x1209 +rak4631.upload_port.0.pid=0x0003 +rak4631.upload_port.1.vid=0x1209 +rak4631.upload_port.1.pid=0x0004 rak4631.upload.target=nrf52840 rak4631.upload.tool=mcumgr diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index 5e47c3e2b..cbfc10360 100644 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -25,15 +25,7 @@ void __attribute__((weak)) __loopHook(void) { int main(void) { #if ZARD_BOARD_HAS_SERIALUSB - /* - * Skip the auto-begin only when a shell runs on the sketch's own CDC - * port (chosen zephyr,shell-uart == cdc-acm-serial). - */ -#if !(defined(CONFIG_SHELL) && DT_HAS_CHOSEN(zephyr_shell_uart) && \ - DT_SAME_NODE(DT_CHOSEN(zephyr_shell_uart), \ - DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), cdc_acm_serial, 0))) SerialUSB.begin(115200); -#endif #endif initVariant(); diff --git a/extra/bootstrap.sh b/extra/bootstrap.sh index f9ccde109..d7f20768a 100755 --- a/extra/bootstrap.sh +++ b/extra/bootstrap.sh @@ -70,6 +70,7 @@ west config manifest.project-filter -- "$HAL_FILTER" west update $WEST_MODULES_CACHE "$@" west zephyr-export pip3 install -r ../zephyr/scripts/requirements-base.txt +pip3 install -r ../bootloader/mcuboot/scripts/requirements.txt log_msg "endgroup" TOOLCHAIN_VERSIONS=$(for tc in $NEEDED_TOOLCHAINS; do diff --git a/extra/build.sh b/extra/build.sh index 8420d7263..21a093b2e 100755 --- a/extra/build.sh +++ b/extra/build.sh @@ -21,7 +21,7 @@ fi if [ $# -eq 0 ] || [ x$1 == x"-h" ] || [ x$1 == x"--help" ]; then cat << EOF Usage: - $0 [--debug] [--mcuboot] + $0 [--debug] $0 [] Build the loader for the given target. @@ -60,21 +60,15 @@ if ! [ -z "$chosen_board" ]; then fi upload_offset=$(jq -cr '.upload_offset' <<< "$chosen_board") - # Check for debug and mcuboot flags and append - for opt in "${@:2}"; do - case "$opt" in - --debug) debug=1 ;; - --mcuboot) mcuboot=1 ;; - *) echo "Unknown option: $opt"; exit 1 ;; - esac - done - + # Boards with '--sysbuild' in their zephyr_args boot the loader through MCUboot conf="" - if [ -n "$mcuboot" ]; then - args+=(--sysbuild) + if [[ " ${args[*]} " == *" --sysbuild "* ]]; then + mcuboot=1 conf="overlay_mcuboot.conf" fi - if [ -n "$debug" ]; then + + # Check for debug flag and append + if [ x$2 == x"--debug" ]; then conf="${conf:+$conf;}../extra/debug.conf" fi if [ -n "$conf" ]; then @@ -150,7 +144,7 @@ IMG=${LOADER_DIR}/zephyr/zephyr if [ -n "$mcuboot" ]; then for ext in bin hex; do if [ ! -f $IMG.signed.$ext ]; then - echo "error: --mcuboot build produced no $IMG.signed.$ext" >&2 + echo "error: MCUboot build produced no $IMG.signed.$ext" >&2 exit 1 fi done @@ -165,9 +159,10 @@ for ext in elf bin hex uf2; do fi done done -rm -f firmwares/mcuboot-$variant.hex +# named zephyr-$variant.* so that package_core.sh ships it with the core +rm -f firmwares/zephyr-$variant.mcuboot.hex if [ -n "$mcuboot" ]; then - cp ${BUILD_DIR}/mcuboot/zephyr/zephyr.hex firmwares/mcuboot-$variant.hex + cp ${BUILD_DIR}/mcuboot/zephyr/zephyr.hex firmwares/zephyr-$variant.mcuboot.hex fi cp ${LOADER_DIR}/zephyr/zephyr.dts firmwares/zephyr-$variant.dts cp ${LOADER_DIR}/zephyr/.config firmwares/zephyr-$variant.config diff --git a/extra/debug.conf b/extra/debug.conf index 10b7a507b..94e86ebf6 100644 --- a/extra/debug.conf +++ b/extra/debug.conf @@ -20,41 +20,18 @@ CONFIG_THREAD_MONITOR=y CONFIG_THREAD_NAME=y CONFIG_DEBUG_THREAD_INFO=y -# Keep optimizing for size. -CONFIG_SIZE_OPTIMIZATIONS=y +# Disable compiler optimizations +#CONFIG_DEBUG_OPTIMIZATIONS=y # Enable and configure the shell CONFIG_SHELL=y -CONFIG_SHELL_BACKEND_SERIAL=y -CONFIG_SHELL_BACKEND_SERIAL_CHECK_DTR=y -CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL_NONE=y -# Print log messages into the shell session if debug port cannot print logs. -# The shell backend is DTR-gated, so nothing is emitted discarded before a -# terminal attaches. +#CONFIG_NET_SHELL=y +#CONFIG_NET_L2_WIFI_SHELL=y CONFIG_SHELL_LOG_BACKEND=n CONFIG_SHELL_STACK_SIZE=8192 -CONFIG_LOG_BACKEND_UART_AUTOSTART=n +CONFIG_LOG_BACKEND_UART_AUTOSTART=y CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n -CONFIG_REBOOT=y -CONFIG_LORA_SHELL=y # Enable runtime statistics CONFIG_SYS_HEAP_RUNTIME_STATS=y CONFIG_THREAD_RUNTIME_STATS=y - -# Logging -# Keep the whole USB path quiet -CONFIG_USBD_CDC_ACM_LOG_LEVEL_OFF=y -CONFIG_UDC_DRIVER_LOG_LEVEL_ERR=y -CONFIG_USBD_LOG_LEVEL_ERR=y -CONFIG_NRF_USBD_COMMON_LOG_LEVEL_OFF=y -CONFIG_LOG_DEFAULT_LEVEL=3 -CONFIG_LOG_RUNTIME_FILTERING=n -CONFIG_LOG_BUFFER_SIZE=4096 -# Buffer log messages and send them from the log thread instead of the -# without sending directly; drops on overflow rather than blocking, so verbose -# logging cannot deadlock the CDC-ACM console it is routed through -CONFIG_LOG_MODE_DEFERRED=y -# Enabled log modules -CONFIG_LORA_LOG_LEVEL_INF=y -CONFIG_LORAWAN_LOG_LEVEL_DBG=y diff --git a/extra/package_tool.sh b/extra/package_tool.sh index ed3126a36..42b819444 100755 --- a/extra/package_tool.sh +++ b/extra/package_tool.sh @@ -22,8 +22,8 @@ hash_file() { plat=$1 file=$2 name=$(basename $file) - hash=$(sha256sum $file | cut -d ' ' -f 1) - len=$(stat -c %s $file) + hash=$(shasum -a 256 $file | cut -d ' ' -f 1) + len=$(wc -c < $file | tr -d ' ') cat << EOF { "host": "$plat", @@ -55,9 +55,14 @@ build_for_arch() { local build_file="$TOOL_NAME$app_ext" local package_file="$tool_stem-$plat$pkg_ext" + # The macOS binaries of MCUmgr need cgo, which Go only enables for the + # native target: force it on for both macOS targets when the host is a Mac + local cgo_env="" + [ "$os" == "darwin" ] && [ "$(uname)" == "Darwin" ] && cgo_env="CGO_ENABLED=1" + echo "Building $TOOL_NAME for $os/$arch ($plat)" mkdir -p "$build_dir" - (cd $TOOL_DIR && GOOS="$os" GOARCH="$arch" go build -o "$build_dir/$build_file") + (cd $TOOL_DIR && env $cgo_env GOOS="$os" GOARCH="$arch" go build -o "$build_dir/$build_file") (cd "$tool_stem" && $pkg_cmd "$package_file" $plat/) hash_file $plat "$package_file" > $build_dir.json } diff --git a/extra/rak/checkall.py b/extra/rak/checkall.py index ceb2f66b0..f709b52d5 100644 --- a/extra/rak/checkall.py +++ b/extra/rak/checkall.py @@ -62,12 +62,17 @@ def _build_checks(board): if not variant or not target: log.die(f"Board '{board}' not found in boards.txt / boards.local.txt") + # Boards with --sysbuild in their zephyr_args boot through MCUboot (see + # extra/build.sh); the loader is then one image among several and has + # its own build directory, which is where compile_commands.json lives. + zephyr_args = utils.board_property(board, "build.zephyr_args") or "" + build_dir = f"build/{variant}" + if "--sysbuild" in zephyr_args.split(): + build_dir += "/loader" + return [ - (f"loader build ({board})", ["./extra/build.sh", board, "--mcuboot"]), - ( - "cppcheck static analysis", - ["west", "rak-lint", "-b", f"build/{variant}/loader"], - ), + (f"loader build ({board})", ["./extra/build.sh", board]), + ("cppcheck static analysis", ["west", "rak-lint", "-b", build_dir]), (f"sketch compilation ({board})", ["west", "rak-sketch-check", "-b", board]), (f"sample build ({target})", ["west", "rak-sample-check", "-b", target]), ] diff --git a/extra/rak/license_check.py b/extra/rak/license_check.py index 536d244f7..d25b239be 100644 --- a/extra/rak/license_check.py +++ b/extra/rak/license_check.py @@ -35,7 +35,7 @@ } # Never checked, matched by exact file name (dotfiles have no suffix). -IGNORE_NAMES = {".gitignore", "VERSION"} +IGNORE_NAMES = {".gitignore", "VERSION", "dependabot.yml"} # Checked even though their suffix is ignored. SOURCE_NAMES = {"CMakeLists.txt"} diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index 623a1ae68..fbec87430 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -8,8 +8,7 @@ cmake_minimum_required(VERSION 3.20.0) # get value of NORMALIZED_BOARD_TARGET early # 'basic_settings' must load before 'boards' so the board lookup works under -# sysbuild: it creates the sysbuild_cache target that the boards module reads. -# It is a no-op in a non-sysbuild build, so plain builds are unaffected. +# sysbuild. find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS basic_settings yaml boards) set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay) diff --git a/loader/main.c b/loader/main.c index 1b6b566ce..91981547e 100644 --- a/loader/main.c +++ b/loader/main.c @@ -100,18 +100,19 @@ int loader_usb_enable(void) { #if CONFIG_SHELL /* - * The shell starts on the zephyr,shell-uart chosen device. If that is a - * CDC-ACM port, leave it there; otherwise restart the shell on the sketch's - * USB port once USB is enabled. + * If the zephyr,shell-uart chosen device is a CDC-ACM port of its own, not the + * sketch's 'Serial' port, the shell stays there. Otherwise it is moved to the + * sketch's USB port once USB is enabled. */ -#define SHELL_ON_CDC_PORT \ +#define SHELL_ON_OWN_CDC_PORT \ (DT_HAS_CHOSEN(zephyr_shell_uart) && \ - DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_shell_uart), zephyr_cdc_acm_uart)) -#if SHELL_ON_CDC_PORT + DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_shell_uart), zephyr_cdc_acm_uart) && \ + !DT_SAME_NODE(DT_CHOSEN(zephyr_shell_uart), \ + DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), cdc_acm_serial, 0))) + +#if SHELL_ON_OWN_CDC_PORT static const struct device *const shell_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart)); #else -#define shell_dev usb_dev - static int enable_shell_usb(void) { bool log_backend = CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL > 0; uint32_t level = (CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL > LOG_LEVEL_DBG) ? @@ -119,11 +120,11 @@ static int enable_shell_usb(void) { CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL; static const struct shell_backend_config_flags cfg_flags = SHELL_DEFAULT_BACKEND_CONFIG_FLAGS; - shell_init(shell_backend_uart_get_ptr(), shell_dev, cfg_flags, log_backend, level); + shell_init(shell_backend_uart_get_ptr(), usb_dev, cfg_flags, log_backend, level); return 0; } -#endif /* SHELL_ON_CDC_PORT */ +#endif #endif #endif @@ -196,29 +197,11 @@ static int loader(const struct shell *sh) { } #if ZARD_FIRST_SERIAL_IS_SERIALUSB - __maybe_unused int debug = (!sketch_valid) || (sketch_hdr->flags & SKETCH_FLAG_DEBUG); -#if CONFIG_SHELL - LOG_INF("shell: device '%s'%s, debug: %d, sketch_valid: %d", shell_dev->name, - SHELL_ON_CDC_PORT ? "" : " (moving to the sketch USB port)", debug, sketch_valid); + int debug = (!sketch_valid) || (sketch_hdr->flags & SKETCH_FLAG_DEBUG); +#if CONFIG_SHELL && SHELL_ON_OWN_CDC_PORT if (strcmp(k_thread_name_get(k_current_get()), "main") == 0) { -#if !SHELL_ON_CDC_PORT - // disables default shell on UART - const struct shell *default_sh = shell_backend_uart_get_ptr(); - if (default_sh->ctx->tid) { - shell_uninit(default_sh, NULL); - for (int i = 0; i < 100; i++) { - if (default_sh->ctx->tid == NULL) { - break; - } - k_sleep(K_MSEC(1)); - } - if (default_sh->ctx->tid) { - LOG_WRN("shell: uninit did not complete, continuing..."); - } - } -#endif + // the shell already runs on its own port, only enable USB loader_usb_enable(); -#if SHELL_ON_CDC_PORT if (debug) { int dtr; do { @@ -228,15 +211,38 @@ static int loader(const struct shell *sh) { } while (!dtr); LOG_INF("shell: port open (DTR set)"); } + } +#if CONFIG_LOG + for (int i = 0; i < log_backend_count_get(); i++) { + const struct log_backend *backend; + backend = log_backend_get(i); + if (log_backend_is_active(backend)) { + // autostarted or already managed by the shell + continue; + } + log_backend_init(backend); + log_backend_enable(backend, backend->cb->ctx, CONFIG_LOG_DEFAULT_LEVEL); + if (!debug) { + break; + } + } #endif -#if !SHELL_ON_CDC_PORT +#elif CONFIG_SHELL + if (strcmp(k_thread_name_get(k_current_get()), "main") == 0) { + // disables default shell on UART + shell_uninit(shell_backend_uart_get_ptr(), NULL); + // enables USB and starts the shell + loader_usb_enable(); + int dtr; + do { + // wait for the serial port to open + uart_line_ctrl_get(usb_dev, UART_LINE_CTRL_DTR, &dtr); + k_sleep(K_MSEC(100)); + } while (!dtr); enable_shell_usb(); - LOG_INF("shell: restarted on '%s'", shell_dev->name); -#endif } -#endif -#if CONFIG_LOG -#if !CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT && !CONFIG_SHELL +#elif CONFIG_LOG +#if !CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT if (debug) { loader_usb_enable(); } @@ -244,10 +250,6 @@ static int loader(const struct shell *sh) { for (int i = 0; i < log_backend_count_get(); i++) { const struct log_backend *backend; backend = log_backend_get(i); - if (log_backend_is_active(backend)) { - // autostarted or already managed by the shell - continue; - } log_backend_init(backend); log_backend_enable(backend, backend->cb->ctx, CONFIG_LOG_DEFAULT_LEVEL); if (!debug) { @@ -343,7 +345,6 @@ static int loader(const struct shell *sh) { size_t sketch_buf_len = sketch_hdr->len; - // an erased sketch area reads flags 0xff, never jump into it if (sketch_valid && (sketch_hdr->flags & SKETCH_FLAG_LINKED)) { #ifdef CONFIG_BOARD_ARDUINO_PORTENTA_C33 #if CONFIG_MPU @@ -417,9 +418,6 @@ static int loader(const struct shell *sh) { recoverable_error_led(); return -ENOENT; } - - LOG_INF("Starting llext sketch, %u bytes", (unsigned int)sketch_buf_len); - log_flush(); #endif #ifdef CONFIG_USERSPACE diff --git a/loader/sysbuild.conf b/loader/sysbuild.conf index 31ba83690..54def7e9c 100644 --- a/loader/sysbuild.conf +++ b/loader/sysbuild.conf @@ -5,7 +5,7 @@ # Enable MCUboot bootloader support SB_CONFIG_BOOTLOADER_MCUBOOT=y -# Do not forget to use your own key at your production code!!! +# Use your own key at your production code! SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="${APP_DIR}/../key/arduino_key_ecdsa-p256.pem" SB_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y diff --git a/loader/sysbuild/mcuboot/boards/rak4631_nrf52840.conf b/loader/sysbuild/mcuboot/boards/rak4631_nrf52840.conf index 87021a79e..8e08629fb 100644 --- a/loader/sysbuild/mcuboot/boards/rak4631_nrf52840.conf +++ b/loader/sysbuild/mcuboot/boards/rak4631_nrf52840.conf @@ -10,11 +10,11 @@ CONFIG_BOOT_SERIAL_CDC_ACM=y CONFIG_WARN_DEPRECATED=n -# USB identity of the bootloader; a different PID from the loader (0x5300). +# USB identity of the bootloader; a different PID from the loader (0x0003). CONFIG_USB_DEVICE_PRODUCT="RAKwireless RAK4631" CONFIG_USB_DEVICE_MANUFACTURER="RAKwireless" -CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x5301 +CONFIG_USB_DEVICE_VID=0x1209 +CONFIG_USB_DEVICE_PID=0x0004 # MCUboot enables USB itself when it enters recovery. CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n CONFIG_USB_CDC_ACM_RINGBUF_SIZE=4096 diff --git a/loader/sysbuild/mcuboot/boards/rak4631_nrf52840.overlay b/loader/sysbuild/mcuboot/boards/rak4631_nrf52840.overlay index bb5f7902c..aee2b840d 100644 --- a/loader/sysbuild/mcuboot/boards/rak4631_nrf52840.overlay +++ b/loader/sysbuild/mcuboot/boards/rak4631_nrf52840.overlay @@ -12,7 +12,7 @@ / { aliases { mcuboot-led0 = &blue_led; - }; + }; }; / { diff --git a/samples/blinky_arduino/boards/rak4631_nrf52840.conf b/samples/blinky_arduino/boards/rak4631_nrf52840.conf index 0d16c0332..80eb919c4 100644 --- a/samples/blinky_arduino/boards/rak4631_nrf52840.conf +++ b/samples/blinky_arduino/boards/rak4631_nrf52840.conf @@ -9,9 +9,8 @@ CONFIG_RAK_REGOUT0_FIX=y CONFIG_USB_DEVICE_STACK_NEXT=y CONFIG_USB_DEVICE_PRODUCT="RAKwireless RAK4631" CONFIG_USB_DEVICE_MANUFACTURER="RAKwireless" -# Use Nordic's VID and PID -CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x5300 +CONFIG_USB_DEVICE_VID=0x1209 +CONFIG_USB_DEVICE_PID=0x0003 CONFIG_USB_CONFIGURATION_STRING_DESC_ENABLE=n CONFIG_USBD_CDC_ACM_CLASS=y diff --git a/samples/hello_arduino/boards/rak4631_nrf52840.conf b/samples/hello_arduino/boards/rak4631_nrf52840.conf index 0d16c0332..80eb919c4 100644 --- a/samples/hello_arduino/boards/rak4631_nrf52840.conf +++ b/samples/hello_arduino/boards/rak4631_nrf52840.conf @@ -9,9 +9,8 @@ CONFIG_RAK_REGOUT0_FIX=y CONFIG_USB_DEVICE_STACK_NEXT=y CONFIG_USB_DEVICE_PRODUCT="RAKwireless RAK4631" CONFIG_USB_DEVICE_MANUFACTURER="RAKwireless" -# Use Nordic's VID and PID -CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x5300 +CONFIG_USB_DEVICE_VID=0x1209 +CONFIG_USB_DEVICE_PID=0x0003 CONFIG_USB_CONFIGURATION_STRING_DESC_ENABLE=n CONFIG_USBD_CDC_ACM_CLASS=y diff --git a/tools/mcumgr/README.md b/tools/mcumgr/README.md index 5533f5ab6..8e5c9ffb8 100644 --- a/tools/mcumgr/README.md +++ b/tools/mcumgr/README.md @@ -1,13 +1,13 @@ -## mcumgr +## MCUmgr -This directory packages the [mcumgr] command-line tool from the Apache Mynewt +This directory packages the [MCUmgr] command-line tool from the Apache Mynewt project as an Arduino tool, so the core can upload images to boards running MCUboot. **None of the code here is original work.** It is a copy of the upstream -mcumgr CLI, and all rights to it belong to mcumgr contributors. +MCUmgr CLI, and all rights to it belong to MCUmgr contributors. -[mcumgr]: https://github.com/apache/mynewt-mcumgr-cli +[MCUmgr]: https://github.com/apache/mynewt-mcumgr-cli ### Building manually diff --git a/variants/rak4631_nrf52840/doc/index.txt b/variants/rak4631_nrf52840/doc/index.txt index 852501b81..9cf47babf 100644 --- a/variants/rak4631_nrf52840/doc/index.txt +++ b/variants/rak4631_nrf52840/doc/index.txt @@ -77,7 +77,7 @@ Buses: On the RAK19007 base board: - Sensor slots A-D get their switched 3V3_S rail through WB_IO2 (D1): - IO2=1 on, IO2=0 off. The loader drives it low at boot , so the rail is off until a + IO2=1 on, IO2=0 off. The loader drives it low at boot, so the rail is off until a sketch enables it. Modules that only use VDD, such as the RAK1901, are unaffected. - A0 is also wired to the battery voltage divider (1.5 MOhm / 2.5 MOhm), so `VBAT = analogRead(A0)` scaled by 5/3 @@ -88,13 +88,16 @@ How to use MCUboot bootloader with arduino-cli: Requirement: arduino-cli uploads through MCUboot's serial recovery (mcumgr over USB), so MCUboot must already be on the board. Before the first arduino-cli -upload, flash the MCUboot hex (`firmwares/mcuboot-rak4631_nrf52840.hex`, built by -`extra/build.sh rak4631 --mcuboot`) over SWD with a J-Link or a RAKDAP1 probe. -arduino-cli cannot install MCUboot itself. +upload, flash the MCUboot hex over SWD with a J-Link or a RAKDAP1 probe. The +core ships it as `firmwares/zephyr-rak4631_nrf52840.mcuboot.hex`, and +`extra/build.sh rak4631` writes it to the same path. arduino-cli cannot install +MCUboot itself. Images are signed with `key/arduino_key_ecdsa-p256.pem`, +which is public in this repository, so this does not provide secure boot. Entering serial recovery: `arduino-cli upload` first sends a 1200-bps touch to -the board's USB port. A sketch that has called `Serial.begin()` handles it; with -no sketch on the board (or with a `--debug` loader) the loader handles it. When -the board shows no USB port (the sketch never opens `Serial`, or it has -crashed), the touch is lost: double-tap the reset button to enter serial -recovery, then upload. +the board's USB port. A running sketch handles it (the core opens `Serial` +before `setup()`); with no sketch on the board (or with a `--debug` loader) the +loader handles it. A sketch that crashes before USB comes up leaves no port for +the touch. In that case press the reset button, then press it again while the +blue LED is on (500 ms): MCUboot stays in serial recovery and opens its own USB +port; upload to that port. SWD is only needed when MCUboot itself is missing. diff --git a/variants/rak4631_nrf52840/rak4631_nrf52840.conf b/variants/rak4631_nrf52840/rak4631_nrf52840.conf index aa67273e6..37da81500 100644 --- a/variants/rak4631_nrf52840/rak4631_nrf52840.conf +++ b/variants/rak4631_nrf52840/rak4631_nrf52840.conf @@ -21,9 +21,9 @@ CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 CONFIG_USB_DEVICE_STACK_NEXT=y CONFIG_USB_DEVICE_PRODUCT="RAKwireless RAK4631" CONFIG_USB_DEVICE_MANUFACTURER="RAKwireless" -# Use Nordic's VID and PID -CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x5300 +# pid.codes test VID/PID; MCUboot enumerates as 0x0004 +CONFIG_USB_DEVICE_VID=0x1209 +CONFIG_USB_DEVICE_PID=0x0003 CONFIG_USB_CONFIGURATION_STRING_DESC_ENABLE=n CONFIG_USBD_CDC_ACM_CLASS=y @@ -35,6 +35,9 @@ CONFIG_USBD_CDC_ACM_LOG_LEVEL_ERR=y CONFIG_UDC_DRIVER_LOG_LEVEL_ERR=y CONFIG_USBD_LOG_LEVEL_ERR=y +# Keep optimizing for size. +CONFIG_SIZE_OPTIMIZATIONS=y + # Boot mode (rak4631_nrf52840_bootmode.dtsi): the 1200 bps touch in # variant.cpp (sketch) or loader/main.c (no sketch, debug shell) asks # MCUboot for serial recovery through it. diff --git a/variants/rak4631_nrf52840/rak4631_nrf52840.overlay b/variants/rak4631_nrf52840/rak4631_nrf52840.overlay index 861e1423b..94d5d5a9d 100644 --- a/variants/rak4631_nrf52840/rak4631_nrf52840.overlay +++ b/variants/rak4631_nrf52840/rak4631_nrf52840.overlay @@ -9,7 +9,7 @@ /* Boot-mode retention area, shared with the MCUboot image as well. */ #include "rak4631_nrf52840_bootmode.dtsi" -/{ +/ { chosen { zephyr,console = &board_cdc_acm_logging; zephyr,log-uart = &log_uarts; @@ -33,7 +33,7 @@ * USB CDC-ACM ports, in enumeration order: * 1. sketch: the sketch's 'Serial' (SerialUSB) * 2. shell: Zephyr shell (debug builds only, unused otherwise) - * 3. logging: console (printk/stdout msg)+ log backend (debug builds only, unused otherwise) + * 3. logging: console (printk/stdout msg) + log backend (debug builds only, unused otherwise) */ &zephyr_udc0 { board_cdc_acm_sketch: board_cdc_acm_sketch { @@ -124,7 +124,6 @@ pinctrl-names = "default", "sleep"; }; - /* Arduino API pin mappings */ / { zephyr,user {