diff --git a/README.md b/README.md index 0d46f40fb..6b94a0f4a 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ To install ARM build tools, use the `Boards Manager` option in the Arduino IDE t ## mbed-os-to-arduino script -The backbone of the packaging process is the https://github.com/arduino/ArduinoCore-mbed/blob/master/mbed-os-to-arduino script. It basically compiles a blank Mbed OS project for any supported target board, recovering the files that will be needed at compile time and copying them to the right location. This script is not compatible with MacOS, it must be run on Linux. +The backbone of the packaging process is the https://github.com/arduino/ArduinoCore-mbed/blob/master/mbed-os-to-arduino script. It basically compiles a blank Mbed OS project for any supported target board, recovering the files that will be needed at compile time and copying them to the right location. This script is compatible only with Linux. If you are using macOS, use the https://github.com/arduino/ArduinoCore-mbed/blob/master/mbed-os-to-arduino-macos script. It can be used for a variety of tasks including: diff --git a/mbed-os-to-arduino-macos b/mbed-os-to-arduino-macos new file mode 100755 index 000000000..077a4d7d0 --- /dev/null +++ b/mbed-os-to-arduino-macos @@ -0,0 +1,448 @@ +#!/usr/bin/env bash + +########################################################################################### +# mbed-os-to-arduino (macOS Version) +# +# This is an adapted version of the original 'mbed-os-to-arduino' script +# specifically tailored for macOS systems. +# +# Prerequisites: +# - jq (Installation: brew install jq) +# - rsync (Installation: brew install rsync) +# - gcc-arm-embedded (Installation: brew install gcc-arm-embedded) +# - hg (Installation: brew install hg) +# - bash (Installation: brew install bash) +# - python (Installation: brew install python) +# - gnu-utils (Installation: brew install gnu-utils) +# - gnu-sed (Installation: brew install gnu-sed) +# - coreutils (Installation: brew install coreutils) +# - ArduinoCore-mbed requirements (Installation: pip install -r requirements.txt) +# +# Troubleshooting for hidapi installation issues: +# If during the installation of ArduinoCore-mbed requirements 'hidapi' installation fails, +# you can modify the 'requirements.txt' file as follows: +# 1. Open 'requirements.txt' in a text editor +# 2. Locate the line that specifies 'hidapi>=...' +# 3. Change it to 'hidapi' +# 4. Save the file +# 5. Rerun this script to install requirements +# +# Initial Author: Martino Facchin @facchinm +# Authors who have contributed to updates: +# - Giampaolo Mancini @manchoz +# - Leonardo Cavagnis @leonardocavagnis +# +########################################################################################### + +set -ef + +check_tools () { + echo -n "Checking for prerequisites..." + if not hash jq &>/dev/null ; then + echo "Please, install jq." + exit 1 + fi + + if not hash rsync &>/dev/null ; then + echo "Please, install rsync." + exit 1 + fi + echo " done." +} + +mbed_new () { + echo -n "Creating MbedOS Application..." + #always work in /tmp + cd /tmp/ + + if [ ! -d mbed-os-program ]; then + mbed new mbed-os-program + fi + cd mbed-os-program + echo " done." +} + +mbed_revision () { + echo -n "Checking out preferred 'mbed-os' version..." + if [ "$MBED_UPDATE" -eq 1 ]; then + echo -n " Updating to latest..." + set +e + mbed update + set -e + fi + + if [ -n "$REMOTE_BRANCH" ]; then + echo -n " Checking out remote branch $REMOTE_BRANCH..." + # checkout the mbed-os version you prefer... + cd mbed-os + git checkout "$REMOTE_BRANCH" + cd .. + fi + + if [ -n "$LOCAL_REPO" ]; then + echo -n " Linking local repo $LOCAL_REPO..." + # ... or link your local repo + if [ -d mbed-os ]; then + if [ ! -L mbed-os ]; then + rm -rf mbed-os + ln -s "$LOCAL_REPO" mbed-os + fi + fi + fi + echo " done." + +} + +create_mbed_program () { + echo -n "Setting up Mbed Application..." + rm -rf .mbedignore + + mbed target "$BOARDNAME" + mbed toolchain GCC_ARM + + cat > main.cpp << MAIN_C +#include "mbed.h" +int main() {} +MAIN_C + + if [ ! -f "$ARDUINOVARIANT"/conf/mbed_app.json ]; then + echo "================================================" + echo "Please, consider creating a 'conf/mbed_app.json'" + echo "to avoid mbed-cli always recompile from scratch." + echo "================================================" + cat > mbed_app.json << MBED_APP +{ + "macros": [ + "MBED_HEAP_STATS_ENABLED=1", + "MBED_STACK_STATS_ENABLED=1", + "MBED_MEM_TRACING_ENABLED=1" + ], + "target_overrides": { + "*": { + "platform.stdio-buffered-serial": true, + "platform.stdio-baud-rate": 115200, + "platform.default-serial-baud-rate": 115200, + "rtos.main-thread-stack-size": 32768 + } + } +} +MBED_APP + fi + + if [ -d "$ARDUINOVARIANT"/conf ]; then + find "$ARDUINOVARIANT"/conf/ -type f -exec gcp -p '{}' . ';' + fi + + echo " done." +} + + +apply_patches () { + if [ "$APPLY_PATCHES" -eq 1 ]; then + echo -n "Applying patches..." + if [ -d "$MBED_CORE_LOCATION"/patches ]; then + cd mbed-os + find "$MBED_CORE_LOCATION"/patches/ -type f -print0 | sort -z | xargs -t -0 -n1 git apply + cd - + fi + echo " done." + if [ "$RESTORE_GDB_INFO" -eq 1 ]; then + echo "Restoring gdb info (this increases libmbed binary size, not suitable for release)" + cd mbed-os + git checkout tools/profiles/develop.json + cd - + fi + fi +} + +mbed_compile () { + echo -n "Compiling Mbed Application..." + if [ "$MBED_CLEAN" -eq 1 ]; then + echo -n "Cleaning..." + rm -rf BUILD + fi + + PROFILE_FLAG="" + if [ x"$PROFILE" != x ]; then + if [ -f "$ARDUINOVARIANT/conf/profile/$PROFILE.json" ]; then + PROFILE_FLAG=--profile="$ARDUINOVARIANT"/conf/profile/$PROFILE.json + else + PROFILE_FLAG=--profile="${PROFILE}" + fi + export PROFILE=-${PROFILE^^} + fi + + mbed compile $PROFILE_FLAG --source . -v \ + | tee >(cat | grep 'Compile \[' >&2) | grep "Macros:" > "$BOARDNAME".macros.txt + echo " done." +} + +generate_defines () { + echo -n "Generating defines..." + cut -f2 -d":" < "$BOARDNAME".macros.txt | tr ' ' '\n' | gsed 's#\"#\\"#g' | sort > "$ARDUINOVARIANT"/defines.txt + echo "-DMBED_NO_GLOBAL_USING_DIRECTIVE=1" >> "$ARDUINOVARIANT"/defines.txt + MAJOR=$(echo $VERSION| cut -d'.' -f 1) + MINOR=$(echo $VERSION| cut -d'.' -f 2) + PATCH=$(echo $VERSION| cut -d'.' -f 3) + echo "-DCORE_MAJOR=$MAJOR" >> "$ARDUINOVARIANT"/defines.txt + echo "-DCORE_MINOR=$MINOR" >> "$ARDUINOVARIANT"/defines.txt + echo "-DCORE_PATCH=$PATCH" >> "$ARDUINOVARIANT"/defines.txt + if [ -f "$ARDUINOVARIANT"/variant.cpp ]; then + echo '-DUSE_ARDUINO_PINOUT' >> "$ARDUINOVARIANT"/defines.txt + fi + echo " done." +} + +generate_includes () { + echo -n "Generating includes..." + + find ./BUILD/"$BOARDNAME"/GCC_ARM${PROFILE}/ -type f -name '.include*' -print0 | xargs -0 cat \ + | tr ' ' '\n' | tr -d '"' | gsed -e 's#-I./mbed-os#-iwithprefixbefore/mbed#g' \ + | gsed '/^-I./d' | gsed '/lwipstack/d' | cat \ + > "$ARDUINOVARIANT"/includes.txt + + echo -n " copying to destination... " + + cd mbed-os + cut -d'/' -f3- < "$ARDUINOVARIANT"/includes.txt | grep 'targets' \ + | xargs -I{} find {} -maxdepth 2 -name '*.h' \ + | xargs -I{} gcp --parent {} "$ARDUINOCOREMBED"/ + cd - + + echo " done." +} + +generate_flags () { + echo -n "Generating flags..." + for fl in c cxx ld; do + jq -r '.flags | .[] | select(. != "-MMD")' ./BUILD/"$BOARDNAME"/GCC_ARM${PROFILE}/.profile-${fl} \ + > "$ARDUINOVARIANT"/${fl}flags.txt + if [[ $ARDUINOVARIANT == *PORTENTA* || $ARDUINOVARIANT == *GIGA* || $ARDUINOVARIANT == *NICLA_VISION* || $ARDUINOVARIANT == *OPTA* ]]; then + echo "Patching '-fno-exceptions' flag for $ARDUINOVARIANT/${fl}flags.txt" + gsed -i '/-fno-exceptions/d' "$ARDUINOVARIANT"/${fl}flags.txt + set +e + HAS_OPENAMP_SECTION=`grep openamp_section "$ARDUINOVARIANT"/linker_script.ld` + set -e + if [ x"$HAS_OPENAMP_SECTION" == x ]; then + echo "Adding OpenAMP section to $ARDUINOVARIANT/linker_script.ld" + OPENAMP_SECTION=".openamp_section (NOLOAD) : {\n \ + . = ABSOLUTE(0x38000000);\n \ + *(.resource_table)\n \ + } >RAM_D3 AT > FLASH\n \ + .pdm_section (NOLOAD) : {\n \ + . = ABSOLUTE(0x3800FC00);\n \ + *(.pdm_buffer)\n \ + } > RAM_D3\n" + + if [[ $ARDUINOVARIANT == *PORTENTA*M7* || $ARDUINOVARIANT == *GIGA* || $ARDUINOVARIANT == *OPTA* ]]; then + OPENAMP_SECTION="${OPENAMP_SECTION} \ + _dtcm_lma = __etext + SIZEOF(.data);\n \ + .dtcm : AT(_dtcm_lma) {\n \ + _sdtcm = .;\n \ + *(.dtcm*)\n \ + _edtcm = .;\n \ + } > DTCMRAM" + fi + + gsed -i "s?.heap (COPY):?${OPENAMP_SECTION}\n .heap (COPY):?g" $ARDUINOVARIANT/linker_script.ld + OPENAMP_REGIONS="__OPENAMP_region_start__ = 0x38000400;\n__OPENAMP_region_end__ = 0x38000400 + LENGTH(RAM_D3) - 1K;" + gsed -i "s?ENTRY(Reset_Handler)?${OPENAMP_REGIONS}\nENTRY(Reset_Handler)?g" $ARDUINOVARIANT/linker_script.ld + fi + echo "Patching linker scripts" + gsed -i 's/0x8100000/CM4_BINARY_START/g' "$ARDUINOVARIANT"/linker_script.ld + gsed -i 's/LENGTH = 0x200000/LENGTH = CM4_BINARY_END - CM4_BINARY_START/g' "$ARDUINOVARIANT"/linker_script.ld + gsed -i 's/LENGTH = 0x1c0000/LENGTH = CM4_BINARY_START - 0x8040000/g' "$ARDUINOVARIANT"/linker_script.ld + fi + if [[ $ARDUINOVARIANT == *NANO_RP2040* ]]; then + set +e + HAS_2NDSTAGE_SECTION=`grep second_stage_ota "$ARDUINOVARIANT"/linker_script.ld` + set -e + if [ x"$HAS_2NDSTAGE_SECTION" == x ]; then + echo "Adding second stage bootloader section to Nano RP2040 Connect" + SECOND_STAGE_SECTION=".second_stage_ota : {\n \ + KEEP (*(.second_stage_ota))\n \ + } > FLASH" + gsed -i "s?.flash_begin?${SECOND_STAGE_SECTION}\n .flash_begin?g" $ARDUINOVARIANT/linker_script.ld + fi + fi + done + echo " done." +} + +generate_libs () { + echo -n "Generating libs..." + tr ' ' '\n' < ./BUILD/"$BOARDNAME"/GCC_ARM${PROFILE}/.link_options.txt | grep "\.o" | grep -v "/main\.o" \ + | xargs arm-none-eabi-ar rcs ./BUILD/mbed-core-"$BOARDNAME".a + + gcp ./BUILD/mbed-core-"$BOARDNAME".a "$ARDUINOVARIANT"/libs/libmbed.a + gcp ./BUILD/"$BOARDNAME"/GCC_ARM${PROFILE}/.link_script.ld "$ARDUINOVARIANT"/linker_script.ld + gcp ./BUILD/"$BOARDNAME"/GCC_ARM${PROFILE}/mbed_config.h "$ARDUINOVARIANT"/ + + gsed -i "s/custom_mbedtls_config.h/conf\/custom_mbedtls_config.h/" $ARDUINOVARIANT/mbed_config.h + + # TODO: discover needed libraries based on compile target + #find -L . -name 'lib*.a' -exec cp '{}' "$ARDUINOVARIANT"/libs/ ';' + echo " done." +} + +copy_core_files () { + echo -n "Copying generic MbedOS headers to core... " + + rsync -zar --exclude="targets/" --exclude="*TEST*/" --include="*/" --include="*.h" --exclude="*" \ + mbed-os/ "$ARDUINOCOREMBED"/ + + rsync -zar --exclude="targets/" --exclude="*TEST*/" --include="*/" --include="mstd_*" --exclude="*" \ + mbed-os/ "$ARDUINOCOREMBED"/ + + echo " done." +} + +patch_mbed_h () { + echo -n "Patching 'mbed.h'..." + if [ x`uname` == xLinux ]; then + gsed -i 's?#include "platform/mbed_version.h"?#include "platform/mbed_version.h"\n#include "mbed_config.h"?g' \ + "$ARDUINOCOREMBED"/mbed.h + else + ed "$ARDUINOCOREMBED"/mbed.h >/dev/null < .mbedignore +# #add ARDUINO_AS_MBED_LIBRARY=1 to macros section in mbed_app.json +# echo "https://github.com/arduino/ArduinoCore-mbed#bf6e64771ebe20285b0364756dff856ebbc679dc" > arduino.lib