From b1e62890e77cb7751d4303a8a42fd2e4d9bc728d Mon Sep 17 00:00:00 2001 From: Mykhailo Tymchyshyn <47373593+mkbrwr@users.noreply.github.com> Date: Mon, 23 Dec 2024 21:05:58 +0200 Subject: [PATCH 1/5] Fix error in displaySize (#78) HAL.swift and Board.swift had different names for display width and display height. This change renames vars in Board.swift to have the same names as in HAL.swift --- stm32-lcd-logo/Support/Board.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stm32-lcd-logo/Support/Board.swift b/stm32-lcd-logo/Support/Board.swift index ebf2c37..bf850d2 100644 --- a/stm32-lcd-logo/Support/Board.swift +++ b/stm32-lcd-logo/Support/Board.swift @@ -53,8 +53,8 @@ struct STM32F746Board { var displaySize: Size { Size( - width: STM32F746.LTDCConstants.DISPLAY_WIDTH, - height: STM32F746.LTDCConstants.DISPLAY_HEIGHT) + width: STM32F746.LTDCConstants.displayWidth, + height: STM32F746.LTDCConstants.displayHeight) } var logoLayerSize: Size { From 7515fbcccc30412b4bc8491d004fea4310c291cf Mon Sep 17 00:00:00 2001 From: Eric Bariaux <375613+ebariaux@users.noreply.github.com> Date: Fri, 3 Jan 2025 06:10:35 +0100 Subject: [PATCH 2/5] Add community examples for nRF52840 microcontroller (#82) Adds two community examples of embedded swift running on nRF52840 microcontrollers. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6259e90..bbf6289 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ Note that the SDK integration examples (Pico SDK, Zephyr SDK, etc.) are not reco | ---- | -------- | ----------- | | [swift-matter-examples](https://github.com/apple/swift-matter-examples) | ESP32 | An Embedded Swift Matter application running on ESP32-C6. | | [swift-flipperzero-hello](https://github.com/Sameesunkaria/swift-flipperzero-hello) | Flipper Zero | A demonstration of running Swift apps on the Flipper Zero. | +| [EmbeddedSwift nRF52 Examples](https://github.com/nelcea/EmbeddedSwift-nRF52-Examples) | nRF52840 (Development Kit) | A collection of examples using Embedded Swift on top of nRF Connect SDK (Zephyr). | +| [Swatak](https://github.com/nelcea/EmbeddedSwift-nRF52-Swatak) | nRF52840 (Seeed Studio XIAO) | A reaction time game inspired by BATAKĀ© boards, implemented in Embedded Swift using nRF Connect SDK. | | [swift-picosystem-example](https://github.com/jerrodputman/swift-picosystem-example) | PicoSystem | An Embedded Swift demo running on the Pimoroni PicoSystem | | [PlaydateKit](https://github.com/finnvoor/PlaydateKit) | Playdate | A full featured framework for building Playdate games using Embedded Swift. | | [swift-playdate-examples](https://github.com/apple/swift-playdate-examples) | Playdate | An Embedded Swift game running on Playdate by Panic. | From 8815c9a8efeff10c99c1504ee0e2028c83deb22e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matheus=20C=2E=20Fran=C3=A7a?= Date: Fri, 3 Jan 2025 04:36:17 -0300 Subject: [PATCH 3/5] Add NuttX RV32 QEMU Example (#64) Adds an example project using the Apache NuttX RTOS which runs under QEMU. --- .github/workflows/build-nuttx.yml | 67 +++++++++ README.md | 17 +-- nuttx-riscv-blink/CMakeLists.txt | 134 ++++++++++++++++++ nuttx-riscv-blink/README.md | 71 ++++++++++ nuttx-riscv-blink/defconfig | 76 ++++++++++ nuttx-riscv-blink/leds_swift/BridgingHeader.h | 124 ++++++++++++++++ nuttx-riscv-blink/leds_swift/Kconfig | 30 ++++ nuttx-riscv-blink/leds_swift/Make.defs | 24 ++++ nuttx-riscv-blink/leds_swift/Makefile | 38 +++++ nuttx-riscv-blink/leds_swift/leds_swift.swift | 30 ++++ 10 files changed, 603 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/build-nuttx.yml create mode 100644 nuttx-riscv-blink/CMakeLists.txt create mode 100644 nuttx-riscv-blink/README.md create mode 100644 nuttx-riscv-blink/defconfig create mode 100644 nuttx-riscv-blink/leds_swift/BridgingHeader.h create mode 100644 nuttx-riscv-blink/leds_swift/Kconfig create mode 100644 nuttx-riscv-blink/leds_swift/Make.defs create mode 100644 nuttx-riscv-blink/leds_swift/Makefile create mode 100644 nuttx-riscv-blink/leds_swift/leds_swift.swift diff --git a/.github/workflows/build-nuttx.yml b/.github/workflows/build-nuttx.yml new file mode 100644 index 0000000..952fc7e --- /dev/null +++ b/.github/workflows/build-nuttx.yml @@ -0,0 +1,67 @@ +name: Build NuttX Examples + +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + schedule: + # Build on Mondays at 9am PST every week + - cron: '0 17 * * 1' + +jobs: + build-nuttx: + runs-on: ubuntu-24.04 + + strategy: + fail-fast: false + matrix: + example: [nuttx-riscv-blink] + swift: [swift-DEVELOPMENT-SNAPSHOT-2024-12-22-a] + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Install apt dependencies + run: | + sudo apt-get -qq update && sudo apt-get -qq -y install \ + bison flex gettext texinfo libncurses5-dev libncursesw5-dev \ + gperf automake libtool pkg-config build-essential gperf genromfs \ + libgmp-dev libmpc-dev libmpfr-dev libisl-dev binutils-dev libelf-dev \ + libexpat-dev gcc-multilib g++-multilib u-boot-tools util-linux \ + kconfig-frontends ninja-build + + - name: Install CMake 3.30.2 + run: | + ARCH=`uname -m` + curl -sL https://github.com/Kitware/CMake/releases/download/v3.30.2/cmake-3.30.2-linux-$ARCH.tar.gz -O + tar xzf cmake-3.30.2-linux-$ARCH.tar.gz + export PATH="`pwd`/cmake-3.30.2-linux-$ARCH/bin:$PATH" + echo "PATH=$PATH" >> $GITHUB_ENV + cmake --version + + - name: Install RISC-V toolchain + run: | + mkdir -p riscv-none-elf-gcc && \ + curl -s -L "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz" \ + | tar -C riscv-none-elf-gcc --strip-components 1 -xz + export PATH="$PATH:`pwd`/riscv-none-elf-gcc/bin/" + echo "PATH=$PATH" >> $GITHUB_ENV + riscv-none-elf-gcc --version + + - name: Install ${{ matrix.swift }} + run: | + wget -q https://download.swift.org/development/ubuntu2404/${{ matrix.swift }}/${{ matrix.swift }}-ubuntu24.04.tar.gz + tar xzf ${{ matrix.swift }}-ubuntu24.04.tar.gz + export PATH="`pwd`/${{ matrix.swift }}-ubuntu24.04/usr/bin/:$PATH" + echo "PATH=$PATH" >> $GITHUB_ENV + swiftc --version + + - name: Config ${{ matrix.example }} + working-directory: ${{ matrix.example }} + run: cmake -B build -GNinja -DBOARD_CONFIG=rv-virt:leds_swift -DENABLE_NUTTX_TRACE=ON + + - name: Build ${{ matrix.example }} + working-directory: ${{ matrix.example }} + run: cmake --build build diff --git a/README.md b/README.md index bbf6289..ff7051a 100644 --- a/README.md +++ b/README.md @@ -32,19 +32,20 @@ Each example in this repository contains build and deployment instructions, howe | Name | Platform | SDK | Description | Photo | | ---- | -------- | --- | ----------- | ----- | +| [esp32-led-blink-sdk](./esp32-led-blink-sdk) | ESP32-C6-Bug | ESP-IDF SDK | Blink an LED repeatedly with Swift & the ESP-IDF. | | +| [esp32-led-strip-sdk](./esp32-led-strip-sdk) | ESP32-C6-DevKitC-1 | ESP-IDF SDK | Control NeoPixel LEDs with Swift & the ESP-IDF. | | +| [nrfx-blink-sdk](./nrfx-blink-sdk) | nRF52840-DK | Zephyr SDK | Blink an LED repeatedly with Swift & Zephyr. | | +| [nuttx-riscv-blink] | QEMU | NuttX | Blink a virualized led in QEMU using the Apache NuttX RTOS | | +| [pico-blink-sdk](./pico-blink-sdk) | Raspberry Pi Pico, Pico 2 | Pico SDK | Blink an LED repeatedly with Swift & the Pico SDK. | | +| [pico-blink](./pico-blink) | Raspberry Pi Pico | None | Blink an LED repeatedly. | | +| [pico-w-blink-sdk](./pico-w-blink-sdk) | Raspberry Pi Pico W | Pico SDK | Blink an LED to signal 'SOS' in Morse code repeatedly with Swift & the Pico SDK. | | +| [pico2-neopixel](./pico2-neopixel) | Raspberry Pi Pico 2 | None | Control Neopixel LEDs using the RP2350 PIO. | | | [stm32-blink](./stm32-blink) | STM32F746G-DISCO | None | Blink an LED repeatedly. | | | [stm32-lcd-logo](./stm32-lcd-logo) | STM32F746G-DISCO | None | Animate the Swift Logo on the built-in LCD. | | | [stm32-neopixel](./stm32-neopixel) | STM32F746G-DISCO | None | Control NeoPixel LEDs using SPI. | | | [stm32-uart-echo](./stm32-uart-echo) | STM32F746G-DISCO | None | Echo user input using UART. | | -| [pico-blink](./pico-blink) | Raspberry Pi Pico | None | Blink an LED repeatedly. | | -| [pico-blink-sdk](./pico-blink-sdk) | Raspberry Pi Pico, Pico 2 | Pico SDK | Blink an LED repeatedly with Swift & the Pico SDK. | | -| [pico-w-blink-sdk](./pico-w-blink-sdk) | Raspberry Pi Pico W | Pico SDK | Blink an LED to signal 'SOS' in Morse code repeatedly with Swift & the Pico SDK. | | -| [pico2-neopixel](./pico2-neopixel) | Raspberry Pi Pico 2 | None | Control Neopixel LEDs using the RP2350 PIO. | | -| [nrfx-blink-sdk](./nrfx-blink-sdk) | nRF52840-DK | Zephyr SDK | Blink an LED repeatedly with Swift & Zephyr. | | -| [esp32-led-strip-sdk](./esp32-led-strip-sdk) | ESP32-C6-DevKitC-1 | ESP-IDF SDK | Control NeoPixel LEDs with Swift & the ESP-IDF. | | -| [esp32-led-blink-sdk](./esp32-led-blink-sdk) | ESP32-C6-Bug | ESP-IDF SDK | Blink an LED repeatedly with Swift & the ESP-IDF. | | -Note that the SDK integration examples (Pico SDK, Zephyr SDK, etc.) are not recommendations or endorsement, the same is true for build system choice (Make, CMake, SwiftPM, shell scripts). Embedded Swift aims to be versatile and to allow for integration into more existing SDKs and build systems, and the example projects are merely showing the possibilities. +Note that the SDK integration examples (Pico SDK, Zephyr SDK, etc.) are not recommendations or endorsement, the same is true for build system choice (Make, CMake, SwiftPM, shell scripts). Embedded Swift aims to be versatile and allowing integration into existing SDKs and build systems, and the example projects show some of the possibilities. ## Community Examples diff --git a/nuttx-riscv-blink/CMakeLists.txt b/nuttx-riscv-blink/CMakeLists.txt new file mode 100644 index 0000000..da191f0 --- /dev/null +++ b/nuttx-riscv-blink/CMakeLists.txt @@ -0,0 +1,134 @@ +cmake_minimum_required(VERSION 3.14...3.30) + +project(blink + VERSION 1.0 + DESCRIPTION "Blink on NuttX" + LANGUAGES Swift +) + +if("${CMAKE_Swift_COMPILER_VERSION}" VERSION_LESS 6.1) + message(FATAL_ERROR "Swift 6.1 or later is required") +endif() + +if(POLICY CMP0169) + # allow to call FetchContent_Populate directly + cmake_policy(SET CMP0169 OLD) +endif() + +option(LIST_ALL_BOARDS "List all available boards" OFF) +option(ENABLE_NUTTX_TRACE "Enable NuttX trace" OFF) + +if(ENABLE_NUTTX_TRACE) + set(TRACEFLAG "--trace") +else() + set(TRACEFLAG "") +endif() + +set(FETCHCONTENT_QUIET FALSE) +include(FetchContent) +FetchContent_Declare( + apps + GIT_REPOSITORY https://github.com/apache/nuttx-apps.git + GIT_TAG nuttx-12.7.0 + SOURCE_DIR ${CMAKE_BINARY_DIR}/apps + FIND_PACKAGE_ARGS +) +FetchContent_GetProperties(apps) +if(NOT apps_POPULATED) + FetchContent_Populate(apps) +endif() + +FetchContent_Declare( + nuttx + GIT_REPOSITORY https://github.com/apache/nuttx.git + GIT_TAG nuttx-12.7.0 + SOURCE_DIR ${CMAKE_BINARY_DIR}/nuttx + FIND_PACKAGE_ARGS +) +FetchContent_GetProperties(nuttx) +if(NOT nuttx_POPULATED) + FetchContent_Populate(nuttx) +endif() + +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + set(SCRIPT_SUFFIX .bat) +else() + set(SCRIPT_SUFFIX .sh) +endif() + +if(LIST_ALL_BOARDS) + execute_process( + COMMAND ${CMAKE_COMMAND} -E chdir ${nuttx_SOURCE_DIR} + ${CMAKE_COMMAND} -E env PATH=${nuttx_SOURCE_DIR}/tools:$ENV{PATH} + ${nuttx_SOURCE_DIR}/tools/configure${SCRIPT_SUFFIX} -L + RESULT_VARIABLE result + ) + if(result) + message(FATAL_ERROR "Failed to run tools/configure") + endif() +else() + if(NOT DEFINED BOARD_CONFIG) + message(FATAL_ERROR "Please define configuration with BOARD_CONFIG") + else() + message(STATUS "BOARD_CONFIG: ${BOARD_CONFIG}") + endif() + + # Send swift-blinky example to nuttx-apps path + file(COPY ${CMAKE_SOURCE_DIR}/leds_swift DESTINATION ${apps_SOURCE_DIR}/examples) + file(COPY ${CMAKE_SOURCE_DIR}/defconfig DESTINATION ${nuttx_SOURCE_DIR}/boards/risc-v/qemu-rv/rv-virt/configs/leds_swift) + + add_custom_target(distclean + COMMAND ${CMAKE_COMMAND} -E chdir ${nuttx_SOURCE_DIR} + ${CMAKE_COMMAND} -E env PATH=${nuttx_SOURCE_DIR}/tools:$ENV{PATH} + make distclean + COMMENT "Clean NuttX" + ) + + execute_process( + COMMAND ${CMAKE_COMMAND} -E chdir ${nuttx_SOURCE_DIR} + ${CMAKE_COMMAND} -E env PATH=${nuttx_SOURCE_DIR}/tools:$ENV{PATH} + ${nuttx_SOURCE_DIR}/tools/configure${SCRIPT_SUFFIX} -l ${BOARD_CONFIG} + RESULT_VARIABLE result + ) + if(result) + message(FATAL_ERROR "Failed to run tools/configure") + endif() + + add_custom_target(copy_swift_example + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/leds_swift ${apps_SOURCE_DIR}/examples/leds_swift + COMMENT "Copying leds_swift example to nuttx-apps" + ) + + add_custom_target(build_nuttx ALL + COMMAND ${CMAKE_COMMAND} -E chdir ${nuttx_SOURCE_DIR} + ${CMAKE_COMMAND} -E env PATH=${nuttx_SOURCE_DIR}/tools:$ENV{PATH} + make ${TRACEFLAG} -j ${JOB_POOLS} + DEPENDS copy_swift_example + COMMENT "Building NuttX" + ) + + add_custom_command( + TARGET build_nuttx + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${nuttx_SOURCE_DIR}/nuttx ${CMAKE_BINARY_DIR}/nuttx.elf + ) + + add_custom_target(export_nuttx + COMMAND ${CMAKE_COMMAND} -E chdir ${nuttx_SOURCE_DIR} + ${CMAKE_COMMAND} -E env PATH=${nuttx_SOURCE_DIR}/tools:$ENV{PATH} + make export + COMMENT "Exporting NuttX" + ) + + add_custom_target(extract_nuttx_export + COMMAND ${CMAKE_COMMAND} -E tar xzf ${nuttx_SOURCE_DIR}/nuttx-export-12.7.0.tar.gz + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E remove ${nuttx_SOURCE_DIR}/nuttx-export-12.7.0.tar.gz + DEPENDS export_nuttx + COMMENT "Extracting NuttX export" + ) + + add_custom_target(nuttx-libs + DEPENDS build_nuttx export_nuttx extract_nuttx_export + ) +endif() diff --git a/nuttx-riscv-blink/README.md b/nuttx-riscv-blink/README.md new file mode 100644 index 0000000..4a47239 --- /dev/null +++ b/nuttx-riscv-blink/README.md @@ -0,0 +1,71 @@ +# Swift 6 on NuttX RTOS using CMake + +## Description + +Run blink rv32-blink_leds (QEMU) example on NuttX RTOS. + +> [!NOTE] +> CMake is adapted to build NuttX and NuttX-apps (Makefiles) with Swift 6. + +## Requirements + +- [NuttX](https://github.com/apache/nuttx) & [NuttX-apps](https://github.com/apache/nuttx-apps) +- [kconfig-frontends](https://bitbucket.org/nuttx/tools) +- [CMake](https://cmake.org/download/) +- [QEMU](https://www.qemu.org/) +- [Swift 6](https://swift.org/download/) - Swift 6.1 or greater +- [RISC-V GNU Toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain/releases) + +## How to build + +```bash +# list all supported boards +cmake -B build -DLIST_ALL_BOARDS=ON | less +# build configuration +cmake -B build -GNinja -DBOARD_CONFIG=rv-virt:leds_swift -DENABLE_NUTTX_TRACE=[ON|OFF] +# build +cmake --build build +# clean +cmake --build build -t distclean +# export NuttX as library +cmake --build build -t nuttx-libs +``` + +- **Output** +```bash +qemu-system-riscv32 \ + -semihosting \ + -M virt,aclint=on \ + -cpu rv32 -smp 8 \ + -bios none \ + -kernel build/nuttx.elf -nographic +NuttShell (NSH) NuttX-12.7.0 +nsh> leds_swift +leds_main: led_daemon started + +led_daemon (pid# 4): Running +led_daemon: Opening /dev/userleds +led_daemon: Supported LEDs 0x7 +led_daemon: LED set 0x1 +board_userled: LED 1 set to 1 +board_userled: LED 2 set to 0 +board_userled: LED 3 set to 0 +nsh> led_daemon: LED set 0x0 +board_userled: LED 1 set to 0 +board_userled: LED 2 set to 0 +board_userled: LED 3 set to 0 +led_daemon: LED set 0x1 +board_userled: LED 1 set to 1 +board_userled: LED 2 set to 0 +board_userled: LED 3 set to 0 +led_daemon: LED set 0x0 +# [...] see output in QEMU +``` + +Quit from QEMU: `Ctrl-a x` + +## References + +- [Nuttx - Compiling with CMake](https://nuttx.apache.org/docs/latest/quickstart/compiling_cmake.html) +- [NuttX - C++ Example using CMake](https://nuttx.apache.org/docs/latest/guides/cpp_cmake.html) +- [NuttX - leds_rust](https://lupyuen.github.io/articles/rust6) diff --git a/nuttx-riscv-blink/defconfig b/nuttx-riscv-blink/defconfig new file mode 100644 index 0000000..5091081 --- /dev/null +++ b/nuttx-riscv-blink/defconfig @@ -0,0 +1,76 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_OS_API is not set +# CONFIG_NSH_DISABLE_LOSMART is not set +CONFIG_16550_ADDRWIDTH=0 +CONFIG_16550_UART0=y +CONFIG_16550_UART0_BASE=0x10000000 +CONFIG_16550_UART0_CLOCK=3686400 +CONFIG_16550_UART0_IRQ=37 +CONFIG_16550_UART0_SERIAL_CONSOLE=y +CONFIG_16550_UART=y +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="rv-virt" +CONFIG_ARCH_BOARD_QEMU_RV_VIRT=y +CONFIG_ARCH_CHIP="qemu-rv" +# CONFIG_ARCH_CHIP_QEMU_RV64=y +CONFIG_ARCH_CHIP_QEMU_RV=y +CONFIG_ARCH_CHIP_QEMU_RV_ISA_A=y +CONFIG_ARCH_CHIP_QEMU_RV_ISA_C=y +CONFIG_ARCH_CHIP_QEMU_RV_ISA_M=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BCH=y +CONFIG_BOARDCTL_POWEROFF=y +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BOARD_LOOPSPERMSEC=6366 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEVICE_TREE=y +CONFIG_DEV_ZERO=y +CONFIG_ELF=y +# CONFIG_EXAMPLES_HELLO=y +CONFIG_EXAMPLES_LEDS=y +CONFIG_EXAMPLES_LEDS_SWIFT=y +CONFIG_FS_HOSTFS=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3072 +CONFIG_LIBC_ENVPATH=y +CONFIG_LIBC_EXECFUNCS=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_LIBM=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PATH_INITIAL="/system/bin" +CONFIG_RAM_SIZE=33554432 +CONFIG_RAM_START=0x80000000 +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_RISCV_SEMIHOSTING_HOSTFS=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_UART_ARCH_MMIO=y +CONFIG_STACK_COLORATION=y +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2021 +CONFIG_SYMTAB_ORDEREDBYNAME=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_NSH_STACKSIZE=3072 +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_USEC_PER_TICK=1000 +CONFIG_USERLED=y +CONFIG_USERLED_LOWER=y diff --git a/nuttx-riscv-blink/leds_swift/BridgingHeader.h b/nuttx-riscv-blink/leds_swift/BridgingHeader.h new file mode 100644 index 0000000..7b2ceba --- /dev/null +++ b/nuttx-riscv-blink/leds_swift/BridgingHeader.h @@ -0,0 +1,124 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift project authors. +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LED_DEVPATH "/dev/userleds" + +const int LEDS_PRIORITY = CONFIG_EXAMPLES_LEDS_PRIORITY; +const int LEDS_STACKSIZE = CONFIG_EXAMPLES_LEDS_STACKSIZE; + +static bool g_led_daemon_started = false; + +static void sigterm_action(int signo, siginfo_t *siginfo, void *arg) { + if (signo == SIGTERM) { + printf("SIGTERM received\n"); + g_led_daemon_started = false; + printf("led_daemon: Terminated.\n"); + } else { + printf("\nsigterm_action: Received signo=%d siginfo=%p arg=%p\n", signo, + (void *)siginfo, arg); + } +} + +int led_daemon(int argc, char *argv[]) { + userled_set_t supported = 0; + userled_set_t ledset = 0; + bool incrementing = true; + + struct sigaction act = {.sa_sigaction = sigterm_action, + .sa_flags = SA_SIGINFO}; + + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, SIGTERM); + + if (sigaction(SIGTERM, &act, NULL) != 0) { + printf("Failed to install SIGTERM handler, errno=%d\n", errno); + return EXIT_FAILURE; + } + + pid_t mypid = getpid(); + g_led_daemon_started = true; + printf("\nled_daemon (pid# %d): Running\n", mypid); + + printf("led_daemon: Opening %s\n", CONFIG_EXAMPLES_LEDS_DEVPATH); + int fd = open(CONFIG_EXAMPLES_LEDS_DEVPATH, O_WRONLY); + if (fd < 0) { + printf("led_daemon: ERROR: Failed to open %s: %d\n", + CONFIG_EXAMPLES_LEDS_DEVPATH, errno); + g_led_daemon_started = false; + return EXIT_FAILURE; + } + + int ret = ioctl(fd, ULEDIOC_SUPPORTED, (unsigned long)&supported); + if (ret < 0) { + printf("led_daemon: ERROR: ioctl(ULEDIOC_SUPPORTED) failed: %d\n", errno); + close(fd); + g_led_daemon_started = false; + return EXIT_FAILURE; + } + + printf("led_daemon: Supported LEDs 0x%x\n", supported); + supported &= CONFIG_EXAMPLES_LEDS_LEDSET; + + while (g_led_daemon_started) { + userled_set_t newset = 0; + userled_set_t tmp = 0; + + if (incrementing) { + tmp = ledset; + while (newset == ledset) { + tmp++; + newset = tmp & supported; + } + + if (newset == 0) { + incrementing = false; + continue; + } + } else { + if (ledset == 0) { + incrementing = true; + continue; + } + + tmp = ledset; + while (newset == ledset) { + tmp--; + newset = tmp & supported; + } + } + + ledset = newset; + printf("led_daemon: LED set 0x%x\n", ledset); + + ret = ioctl(fd, ULEDIOC_SETALL, (unsigned long)ledset); + if (ret < 0) { + printf("led_daemon: ERROR: ioctl(ULEDIOC_SETALL) failed: %d\n", errno); + close(fd); + g_led_daemon_started = false; + return EXIT_FAILURE; + } + + usleep(500 * 1000); + } + + close(fd); + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/nuttx-riscv-blink/leds_swift/Kconfig b/nuttx-riscv-blink/leds_swift/Kconfig new file mode 100644 index 0000000..e39ce08 --- /dev/null +++ b/nuttx-riscv-blink/leds_swift/Kconfig @@ -0,0 +1,30 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_LEDS_SWIFT + tristate "\"LEDs Swift\" example" + default y + depends on USERLED + ---help--- + Enable the \"LEDs Swift\" example + +if EXAMPLES_LEDS_SWIFT + +config EXAMPLES_LEDS_SWIFT_PROGNAME + string "Program name" + default "leds_swift" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config EXAMPLES_LEDS_SWIFT_PRIORITY + int "LEDs Swift task priority" + default 100 + +config EXAMPLES_LEDS_SWIFT_STACKSIZE + int "LEDs Swift stack size" + default DEFAULT_TASK_STACKSIZE + +endif diff --git a/nuttx-riscv-blink/leds_swift/Make.defs b/nuttx-riscv-blink/leds_swift/Make.defs new file mode 100644 index 0000000..9070565 --- /dev/null +++ b/nuttx-riscv-blink/leds_swift/Make.defs @@ -0,0 +1,24 @@ +############################################################################ +# apps/examples/leds_swift/Make.defs +# +# Copyright (c) 2024 Apple Inc. and the Swift project authors. +# 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. +# +############################################################################ + +ifneq ($(CONFIG_EXAMPLES_LEDS_SWIFT),) +CONFIGURED_APPS += $(APPDIR)/examples/leds_swift +endif diff --git a/nuttx-riscv-blink/leds_swift/Makefile b/nuttx-riscv-blink/leds_swift/Makefile new file mode 100644 index 0000000..e2fc7df --- /dev/null +++ b/nuttx-riscv-blink/leds_swift/Makefile @@ -0,0 +1,38 @@ +############################################################################ +# apps/examples/leds_swift/Makefile +# +# Copyright (c) 2024 Apple Inc. and the Swift project authors. +# 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 $(APPDIR)/Make.defs + +# Blink in Swift Embedded Example + +MAINSRC = $(wildcard *.swift) $(wildcard *.h) + +# leds_swift built-in application info + +SWIFTFLAGS += -import-bridging-header BridgingHeader.h -I$(TOPDIR)/include +SWIFTFLAGS += -Xfrontend -function-sections -Xfrontend -disable-stack-protector +SWIFTFLAGS += -Xfrontend -enable-single-module-llvm-emission +PROGNAME = $(CONFIG_EXAMPLES_LEDS_SWIFT_PROGNAME) +PRIORITY = $(CONFIG_EXAMPLES_LEDS_SWIFT_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_LEDS_SWIFT_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_LEDS_SWIFT) + +include $(APPDIR)/Application.mk diff --git a/nuttx-riscv-blink/leds_swift/leds_swift.swift b/nuttx-riscv-blink/leds_swift/leds_swift.swift new file mode 100644 index 0000000..1cadcf4 --- /dev/null +++ b/nuttx-riscv-blink/leds_swift/leds_swift.swift @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift project authors. +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// +//===----------------------------------------------------------------------===// + +@_cdecl("leds_swift_main") +public func cMain( + _ argc: Int32, _ argv: UnsafeMutablePointer?> +) -> Int32 { + let ret = task_create( + "led_daemon", + LEDS_PRIORITY, + LEDS_STACKSIZE, + led_daemon, + nil) + + if ret < 0 { + print("leds_main: ERROR: Failed to start led_daemon") + return ret + } + + print("leds_main: led_daemon started") + return 0 +} From 34d0bb53db7c32d28b3f08be87c20bf1e472894b Mon Sep 17 00:00:00 2001 From: Rauhul Varma Date: Thu, 2 Jan 2025 23:42:43 -0800 Subject: [PATCH 4/5] Update build-pico-sdk.yml (#85) Avoid using docker instead just build directly in an ubuntu 24.04 VM. --- .github/workflows/build-pico-sdk.yml | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-pico-sdk.yml b/.github/workflows/build-pico-sdk.yml index caa7bcd..06283bd 100644 --- a/.github/workflows/build-pico-sdk.yml +++ b/.github/workflows/build-pico-sdk.yml @@ -11,8 +11,7 @@ on: jobs: build-pico-sdk: - runs-on: ubuntu-22.04 - container: swiftlang/swift:nightly-main-jammy + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -21,13 +20,14 @@ jobs: board: pico - name: pico-w-blink-sdk board: pico_w + swift: [swift-DEVELOPMENT-SNAPSHOT-2024-12-04-a] steps: - name: Checkout repo uses: actions/checkout@v4 - name: Install apt dependencies - run: apt-get -qq update && apt-get -qq -y install curl ninja-build python3 + run: sudo apt-get -qq update && sudo apt-get -qq -y install curl ninja-build python3 - name: Install CMake 3.30.2 run: | @@ -38,6 +38,21 @@ jobs: echo "PATH=$PATH" >> $GITHUB_ENV cmake --version + - name: Install GNU ARM toolchain + run: | + ARCH=`uname -m` + curl -sL https://developer.arm.com/-/media/Files/downloads/gnu/13.3.rel1/binrel/arm-gnu-toolchain-13.3.rel1-$ARCH-arm-none-eabi.tar.xz -O + tar xf arm-gnu-toolchain-13.3.rel1-$ARCH-arm-none-eabi.tar.xz + + - name: Install ${{ matrix.swift }} + run: | + wget -q https://download.swift.org/development/ubuntu2404/${{ matrix.swift }}/${{ matrix.swift }}-ubuntu24.04.tar.gz + tar xzf ${{ matrix.swift }}-ubuntu24.04.tar.gz + export PATH="$PATH:`pwd`/${{ matrix.swift }}-ubuntu24.04/usr/bin/" + echo "PATH=$PATH" >> $GITHUB_ENV + which swiftc + swiftc --version + - name: Clone Pico SDK run: | git clone https://github.com/raspberrypi/pico-sdk.git @@ -45,12 +60,6 @@ jobs: git submodule update --init --recursive cd .. - - name: Download GNU ARM toolchain - run: | - ARCH=`uname -m` - curl -sL https://developer.arm.com/-/media/Files/downloads/gnu/13.3.rel1/binrel/arm-gnu-toolchain-13.3.rel1-$ARCH-arm-none-eabi.tar.xz -O - tar xf arm-gnu-toolchain-13.3.rel1-$ARCH-arm-none-eabi.tar.xz - - name: Set Pico environment variables run: | ARCH=`uname -m` From 8795b3f240bfa1912cdea488d30eccd010c05969 Mon Sep 17 00:00:00 2001 From: Rauhul Varma Date: Thu, 2 Jan 2025 23:56:21 -0800 Subject: [PATCH 5/5] Adopt swiftlang soundness workflow (#80) Replaces our lint workflow with a more general solution from the swiftlang/github-workflow repo. --- .flake8 | 10 +++ .github/workflows/build-esp.yml | 2 +- .github/workflows/build-nuttx.yml | 2 +- .github/workflows/build-pico-sdk.yml | 2 +- .github/workflows/build-zephyr.yml | 2 +- .github/workflows/lint.yml | 18 ++++-- Tools/macho2bin.py | 68 ++++++++++++------- Tools/macho2uf2.py | 97 +++++++++++++++++----------- nrfx-blink-sdk/west.yml | 4 +- pico-blink/build.sh | 20 +++--- stm32-blink/build.sh | 26 ++++---- stm32-lcd-logo/build.sh | 4 -- 12 files changed, 155 insertions(+), 100 deletions(-) create mode 100644 .flake8 delete mode 100755 stm32-lcd-logo/build.sh diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..c7b743c --- /dev/null +++ b/.flake8 @@ -0,0 +1,10 @@ +[flake8] + +ignore = + # These are needed to make our license headers pass the linting + E265, + E266, + +# 10% larger than the standard 80 character limit. Conforms to the black +# standard and Bugbear's B950. +max-line-length = 88 diff --git a/.github/workflows/build-esp.yml b/.github/workflows/build-esp.yml index 0def652..b6efe03 100644 --- a/.github/workflows/build-esp.yml +++ b/.github/workflows/build-esp.yml @@ -7,7 +7,7 @@ on: branches: ["main"] schedule: # Build on Mondays at 9am PST every week - - cron: '0 17 * * 1' + - cron: '0 17 * * 1' jobs: build-esp: diff --git a/.github/workflows/build-nuttx.yml b/.github/workflows/build-nuttx.yml index 952fc7e..f9104e5 100644 --- a/.github/workflows/build-nuttx.yml +++ b/.github/workflows/build-nuttx.yml @@ -7,7 +7,7 @@ on: branches: ["main"] schedule: # Build on Mondays at 9am PST every week - - cron: '0 17 * * 1' + - cron: '0 17 * * 1' jobs: build-nuttx: diff --git a/.github/workflows/build-pico-sdk.yml b/.github/workflows/build-pico-sdk.yml index 06283bd..67b7600 100644 --- a/.github/workflows/build-pico-sdk.yml +++ b/.github/workflows/build-pico-sdk.yml @@ -7,7 +7,7 @@ on: branches: ["main"] schedule: # Build on Mondays at 9am PST every week - - cron: '0 17 * * 1' + - cron: '0 17 * * 1' jobs: build-pico-sdk: diff --git a/.github/workflows/build-zephyr.yml b/.github/workflows/build-zephyr.yml index 0233f15..51b507e 100644 --- a/.github/workflows/build-zephyr.yml +++ b/.github/workflows/build-zephyr.yml @@ -7,7 +7,7 @@ on: branches: ["main"] schedule: # Build on Mondays at 9am PST every week - - cron: '0 17 * * 1' + - cron: '0 17 * * 1' jobs: build-zephyr: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 52009c0..33b86f8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,22 +7,26 @@ on: branches: ["main"] jobs: - lint: - name: Lint + validate_format_config: + name: Validate Format Config runs-on: ubuntu-latest - container: swift:6.0-jammy - steps: - name: Checkout repo uses: actions/checkout@v4 - name: Install apt dependencies - run: apt-get -qq update && apt-get -qq -y install curl + run: sudo apt-get -qq update && sudo apt-get -qq -y install curl - name: Compare against swift-mmio swift-format config run: | curl -sL https://raw.githubusercontent.com/apple/swift-mmio/refs/heads/main/.swift-format -o .swift-format-mmio diff .swift-format .swift-format-mmio - - name: Lint - run: swift-format lint --recursive --strict . + soundness: + name: Soundness + uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main + with: + api_breakage_check_enabled: false # this repo doesn't vend any API + license_header_check_enabled: false # feature: https://github.com/swiftlang/github-workflows/issues/78 + license_header_check_project_name: "Swift.org" # bug: https://github.com/swiftlang/github-workflows/issues/76 + unacceptable_language_check_enabled: false # unfortunately many hardware specs use terms like master/slave in their documentation diff --git a/Tools/macho2bin.py b/Tools/macho2bin.py index 9b348f3..6ba74b3 100755 --- a/Tools/macho2bin.py +++ b/Tools/macho2bin.py @@ -8,36 +8,45 @@ # See https://swift.org/LICENSE.txt for license information # -# macho2bin -- Converts a statically-linked executable Mach-O into a flat "BIN" file suitable for flashing as a single -# contiguous blob onto some embedded devices. Note that this format assumes the embedded device can boot from a state -# where the entire firmware (all segments) are flashed contigously into one smalle address range. This is true for e.g. -# the STM32F746 devices if we place the vector table at 0x00200000, and code and data right after it, as the vector -# table also contains a pointer to the initial PC. This setup might not work for other devices. +# macho2bin -- Converts a statically-linked executable Mach-O into a flat "BIN" file +# suitable for flashing as a single contiguous blob onto some embedded devices. Note +# that this format assumes the embedded device can boot from a state where the entire +# firmware (all segments) are flashed contigously into one smalle address range. This +# is true for e.g. the STM32F746 devices if we place the vector table at 0x00200000, +# and code and data right after it, as the vector table also contains a pointer to the +# initial PC. This setup might not work for other devices. # # Usage: -# $ macho2bin.py --base-address --segments +# $ macho2bin.py --base-address --segments +# # # Example: -# $ macho2bin.py ./blink ./blink.bin --base-address 0x00200000 --segments '__TEXT,__DATA,__VECTORS' +# $ macho2bin.py ./blink ./blink.bin --base-address 0x00200000 --segments +# '__TEXT,__DATA,__VECTORS' # # Requirements and notes: -# * The output BIN file is a flat contiguous representation of the segments (--segments) based on their VM addresses. -# * The BIN file's first byte corresponds to the specified base address (--base-address). +# * The output BIN file is a flat contiguous representation of the segments +# (--segments) based on their VM addresses. +# * The BIN file's first byte corresponds to the specified base address +# (--base-address). # * Any gaps between segments are filled with zero bytes. -# * Because of that, you want the input Mach-O to have all segments "close", and not have gaps. +# * Because of that, you want the input Mach-O to have all segments "close", and not +# have gaps. # import argparse import os + from macholib import MachO from macholib import mach_o + def main(): parser = argparse.ArgumentParser() - parser.add_argument('input') - parser.add_argument('output') - parser.add_argument('--base-address', required=True) - parser.add_argument('--segments', required=True) + parser.add_argument("input") + parser.add_argument("output") + parser.add_argument("--base-address", required=True) + parser.add_argument("--segments", required=True) args = parser.parse_args() args.base_address = int(args.base_address, 16) args.segments = args.segments.split(",") @@ -49,17 +58,23 @@ def main(): for command in mh.commands: if isinstance(command[1], mach_o.segment_command): (_, segment, sections) = command - segname = segment.segname.decode().strip('\0') - if segname not in args.segments: continue + segname = segment.segname.decode().strip("\0") + if segname not in args.segments: + continue with open(args.input, "rb") as f: f.seek(mh.offset + segment.fileoff) data = f.read(segment.filesize) - segments.append({"vmaddr": segment.vmaddr, "data": data, "name": segname}) - + segments.append( + {"vmaddr": segment.vmaddr, "data": data, "name": segname} + ) + segments = sorted(segments, key=lambda x: x["vmaddr"]) - assert segments[0]["vmaddr"] == args.base_address, f"first segment's vmaddr 0x{segments[0]['vmaddr']:08x} does not match the passed --base-address 0x{args.base_address:08x}" + assert segments[0]["vmaddr"] == args.base_address, ( + f"first segment's vmaddr 0x{segments[0]['vmaddr']:08x} does not match the" + f" passed --base-address 0x{args.base_address:08x}" + ) if os.path.exists(args.output): os.unlink(args.output) @@ -69,15 +84,22 @@ def main(): for segment in segments: gap = segment["vmaddr"] - vmaddr if gap != 0: - print(f"Writing gap of size {gap} (0x{gap:0x}) at vmaddr 0x{vmaddr:08x}") - f.write(b'\0' * gap) + print( + f"Writing gap of size {gap} (0x{gap:0x}) at vmaddr 0x{vmaddr:08x}" + ) + f.write(b"\0" * gap) assert gap >= 0 vmaddr = segment["vmaddr"] - print(f"Writing segment {segment['name']} size {len(segment['data'])} (0x{len(segment['data']):x}) at vmaddr 0x{vmaddr:08x}") + print( + f"Writing segment {segment['name']} size" + f" {len(segment['data'])} (0x{len(segment['data']):x}) at vmaddr" + f" 0x{vmaddr:08x}" + ) f.write(segment["data"]) vmaddr = segment["vmaddr"] + len(segment["data"]) print(f"Produced {args.output} with {vmaddr - args.base_address} bytes") -if __name__ == '__main__': + +if __name__ == "__main__": main() diff --git a/Tools/macho2uf2.py b/Tools/macho2uf2.py index f0812e0..5043b4a 100755 --- a/Tools/macho2uf2.py +++ b/Tools/macho2uf2.py @@ -8,39 +8,44 @@ # See https://swift.org/LICENSE.txt for license information # -# macho2uf2 -- Converts a statically-linked executable Mach-O into a flat "UF2" file suitable for flashing as a single -# contiguous blob onto some embedded devices, in particular Raspberry Pi Pico (W). Note that the UF2 format allows for -# discontiguous memory regions, but this utility does not support that. +# macho2uf2 -- Converts a statically-linked executable Mach-O into a flat "UF2" file +# suitable for flashing as a single contiguous blob onto some embedded devices, in +# particular Raspberry Pi Pico (W). Note that the UF2 format allows for discontiguous +# memory regions, but this utility does not support that. # # Usage: -# $ macho2uf2.py --base-address --segments +# $ macho2uf2.py --base-address --segments +# # # Example: -# $ macho2uf2.py ./blink ./blink.uf2 --base-address 0x00200000 --segments '__TEXT,__DATA,__VECTORS' +# $ macho2uf2.py ./blink ./blink.uf2 --base-address 0x00200000 --segments +# '__TEXT,__DATA,__VECTORS' # # Requirements and notes: -# * The output UF2 file is a flat contiguous representation of the segments (--segments) based on their VM addresses. -# * The UF2 file's first byte corresponds to the specified base address (--base-address). +# * The output UF2 file is a flat contiguous representation of the segments +# (--segments) based on their VM addresses. +# * The UF2 file's first byte corresponds to the specified base address +# (--base-address). # * Any gaps between segments are filled with zero bytes. -# * Because of that, you want the input Mach-O to have all segments "close", and not have gaps. +# * Because of that, you want the input Mach-O to have all segments "close", and not +# have gaps. # import argparse import os -import subprocess import struct -from macholib import MachO -from macholib import mach_o +import subprocess MY_DIR = os.path.dirname(os.path.abspath(__file__)) + def main(): parser = argparse.ArgumentParser() - parser.add_argument('input') - parser.add_argument('output') - parser.add_argument('--base-address', required=True) - parser.add_argument('--segments', required=True) - parser.add_argument('--pico-family', required=True) + parser.add_argument("input") + parser.add_argument("output") + parser.add_argument("--base-address", required=True) + parser.add_argument("--segments", required=True) + parser.add_argument("--pico-family", required=True) args = parser.parse_args() args.base_address = int(args.base_address, 16) args.segments = args.segments.split(",") @@ -48,40 +53,52 @@ def main(): family_id = 0xE48BFF56 add_errata_block = False elif args.pico_family == "rp2350": - family_id = 0XE48BFF59 + family_id = 0xE48BFF59 add_errata_block = True else: assert False - subprocess.check_call([MY_DIR + "/macho2bin.py", args.input, args.input + ".bin", "--base-address", "0x%08x" % args.base_address, "--segments", ",".join(args.segments)]) + subprocess.check_call( + [ + MY_DIR + "/macho2bin.py", + args.input, + args.input + ".bin", + "--base-address", + "0x%08x" % args.base_address, + "--segments", + ",".join(args.segments), + ] + ) def emit_block(output, block, vmaddr, block_number, num_blocks, family_id): assert len(block) <= 256 - + if len(block) < 256: - block += b'\0' * (256 - len(block)) - + block += b"\0" * (256 - len(block)) + # UF2_Block header - output += struct.pack("