diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b81fa972..a079dac63 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -251,7 +251,11 @@ jobs: timeout-minutes: 180 runs-on: ${{matrix.os}} - container: ${{matrix.container}} + container: + image: ${{matrix.container}} + volumes: + - /node20217:/node20217:rw,rshared + - ${{ startsWith(matrix.container, 'ubuntu:1') && '/node20217:/__e/node20:ro,rshared' || ' ' }} steps: - name: Setup environment @@ -275,9 +279,13 @@ jobs: fi apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ $PYTHON_PACKAGE python3 perl git cmake fi + if [[ "${{matrix.container}}" == "ubuntu:1"* ]]; then + # Node 20 doesn't work with Ubuntu 16/18 glibc: https://github.com/actions/checkout/issues/1590 + curl -sL https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz | tar -xJ --strip-components 1 -C /node20217 + fi fi git config --global pack.threads 0 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages if: matrix.install @@ -489,7 +497,7 @@ jobs: runs-on: ${{matrix.os}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Boost shell: cmd @@ -533,11 +541,11 @@ jobs: runs-on: ${{matrix.os}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages if: matrix.install - run: sudo apt install ${{matrix.install}} + run: sudo apt-get -y install ${{matrix.install}} - name: Setup Boost run: | @@ -582,7 +590,7 @@ jobs: runs-on: ${{matrix.os}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages if: matrix.install @@ -641,7 +649,7 @@ jobs: runs-on: ${{matrix.os}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages if: matrix.install @@ -698,7 +706,7 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup MSYS2 environment uses: msys2/setup-msys2@v2 @@ -709,7 +717,7 @@ jobs: pacboy: gcc:p cmake:p ninja:p - name: Fetch Boost.CI - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: boostorg/boost-ci ref: master diff --git a/.github/workflows/metal.yml b/.github/workflows/metal.yml index b0c426136..dcbf89837 100644 --- a/.github/workflows/metal.yml +++ b/.github/workflows/metal.yml @@ -1,6 +1,6 @@ # ------------------------------------------------------------------------------ -# Copyright Matt Borland 2023. -# Copyright Christopher Kormanyos 2023. +# Copyright Matt Borland 2023 - 2024. +# Copyright Christopher Kormanyos 2023 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -27,28 +27,44 @@ jobs: fetch-depth: '0' - name: update-tools run: | - sudo apt install libncurses5 libpython2.7 + sudo apt update + wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb + sudo apt install ./libtinfo5_6.3-2ubuntu0.1_amd64.deb + wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libncursesw5_6.3-2ubuntu0.1_amd64.deb + sudo apt install ./libncursesw5_6.3-2ubuntu0.1_amd64.deb mkdir -p emu_env && cd emu_env - wget --no-check-certificate https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 - tar -xf gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 - wget --no-check-certificate https://github.com/xpack-dev-tools/qemu-arm-xpack/releases/download/v7.1.0-1/xpack-qemu-arm-7.1.0-1-linux-x64.tar.gz - tar -xzf xpack-qemu-arm-7.1.0-1-linux-x64.tar.gz + wget --no-check-certificate https://developer.arm.com/-/media/Files/downloads/gnu/13.3.rel1/binrel/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi.tar.xz + tar -xf arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi.tar.xz + wget --no-check-certificate https://github.com/xpack-dev-tools/qemu-arm-xpack/releases/download/v8.2.6-1/xpack-qemu-arm-8.2.6-1-linux-x64.tar.gz + tar -xzf xpack-qemu-arm-8.2.6-1-linux-x64.tar.gz working-directory: ./test/metal/ - name: build benchmark_single-stm32f429 run: | + PATH="${{ runner.workspace }}/decimal/test/metal/emu_env/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi/bin:$PATH" + echo 'Query arm-none-eabi-g++ version' + echo + arm-none-eabi-g++ -v + echo mkdir -p bin - emu_env/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-g++ -std=c++17 -Wall -Wextra -Wpedantic -Os -g -gdwarf-2 -ffunction-sections -fdata-sections -x c++ -fno-rtti -fno-use-cxa-atexit -fno-exceptions -fno-nonansi-builtins -fno-threadsafe-statics -fno-enforce-eh-specs -fno-inline-functions -mcpu=cortex-m4 -mtune=cortex-m4 -mthumb -mfloat-abi=soft -mno-unaligned-access -mno-long-calls -I../../include -DBOOST_DECIMAL_DISABLE_CLIB -DAPP_BENCHMARK_STANDALONE_MAIN app_benchmark_non_std_decimal.cpp ./target/micros/stm32f429/make/single/crt.cpp ./target/micros/stm32f429/make/single/mcal_gcc_cxx_completion_with_stdlib.cpp -nostartfiles -Wl,--gc-sections -Wl,-Map,./bin/app_benchmark_non_std_decimal.map -T ./target/micros/stm32f429/make/stm32f429.ld --specs=nano.specs --specs=nosys.specs -Wl,--print-memory-usage -o ./bin/app_benchmark_non_std_decimal.elf - emu_env/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-objcopy ./bin/app_benchmark_non_std_decimal.elf -O ihex ./bin/app_benchmark_non_std_decimal.hex + arm-none-eabi-g++ -std=c++20 -Wall -Wextra -Wpedantic -Os -g -gdwarf-2 -ffunction-sections -fdata-sections -x c++ -fno-rtti -fno-use-cxa-atexit -fno-exceptions -fno-nonansi-builtins -fno-threadsafe-statics -fno-enforce-eh-specs -fno-inline-functions -mcpu=cortex-m4 -mtune=cortex-m4 -mthumb -mfloat-abi=soft -mno-unaligned-access -mno-long-calls -I../../include -DBOOST_DECIMAL_DISABLE_CLIB -DAPP_BENCHMARK_STANDALONE_MAIN app_benchmark_non_std_decimal.cpp ./target/micros/stm32f429/make/single/crt.cpp ./target/micros/stm32f429/make/single/mcal_gcc_cxx_completion_with_stdlib.cpp -nostartfiles -Wl,--gc-sections -Wl,-Map,./bin/app_benchmark_non_std_decimal.map -T ./target/micros/stm32f429/make/stm32f429.ld --specs=nano.specs --specs=nosys.specs -Wl,--print-memory-usage -o ./bin/app_benchmark_non_std_decimal.elf + arm-none-eabi-objcopy ./bin/app_benchmark_non_std_decimal.elf -O ihex ./bin/app_benchmark_non_std_decimal.hex ls -la ./bin/app_benchmark_non_std_decimal.elf ./bin/app_benchmark_non_std_decimal.hex ./bin/app_benchmark_non_std_decimal.map working-directory: ./test/metal/ - name: emulate-target stm32f429 run: | - ./emu_env/xpack-qemu-arm-7.1.0-1/bin/qemu-system-gnuarmeclipse --verbose --mcu STM32F429ZI --nographic --gdb tcp::9999 -d unimp,guest_errors & + PATH="${{ runner.workspace }}/decimal/test/metal/emu_env/xpack-qemu-arm-8.2.6-1/bin:$PATH" + qemu-system-gnuarmeclipse --verbose --mcu STM32F429ZI --nographic --gdb tcp::9999 -d unimp,guest_errors & + sleep 2 working-directory: ./test/metal/ - name: run-test-on-target run: | - ./emu_env/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gdb-py ./bin/app_benchmark_non_std_decimal.elf -x ./target/build/test_app_benchmarks_emulator.py - qemu_result=$? - echo "qemu_result" "$qemu_result" - echo "qemu_result" "$qemu_result" | grep 'qemu_result 0' + sleep 2 + PATH="${{ runner.workspace }}/decimal/test/metal/emu_env/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi/bin:$PATH" + echo 'Run test on target' + echo + arm-none-eabi-gdb ./bin/app_benchmark_non_std_decimal.elf -x ./target/build/test_app_benchmarks_emulator.gdb > ./app_benchmark_non_std_decimal.txt + cat ./app_benchmark_non_std_decimal.txt + echo + echo 'We will now grep for the right answer...' + grep 'value 0xF00DCAFE' ./app_benchmark_non_std_decimal.txt working-directory: ./test/metal/ diff --git a/test/metal/app_benchmark_non_std_decimal.cpp b/test/metal/app_benchmark_non_std_decimal.cpp index 4a6599c76..b818d9595 100644 --- a/test/metal/app_benchmark_non_std_decimal.cpp +++ b/test/metal/app_benchmark_non_std_decimal.cpp @@ -12,7 +12,7 @@ // cd /mnt/c/MyGitRepos/cppalliance/decimal/test/metal // mkdir -p bin -// arm-none-eabi-g++ -std=c++17 -Wall -Wextra -Wpedantic -O0 -g -gdwarf-2 -ffunction-sections -fdata-sections -x c++ -fno-rtti -fno-use-cxa-atexit -fno-exceptions -fno-nonansi-builtins -fno-threadsafe-statics -fno-enforce-eh-specs -ftemplate-depth=128 -mcpu=cortex-m4 -mtune=cortex-m4 -mthumb -mfloat-abi=soft -mno-unaligned-access -mno-long-calls -I../../include -DBOOST_DECIMAL_DISABLE_CLIB -DAPP_BENCHMARK_STANDALONE_MAIN app_benchmark_non_std_decimal.cpp ./target/micros/stm32f429/make/single/crt.cpp ./target/micros/stm32f429/make/single/mcal_gcc_cxx_completion_with_stdlib.cpp -nostartfiles -Wl,--gc-sections -Wl,-Map,./bin/app_benchmark_non_std_decimal.map -T ./target/micros/stm32f429/make/stm32f429.ld --specs=nano.specs --specs=nosys.specs -Wl,--print-memory-usage -o ./bin/app_benchmark_non_std_decimal.elf +// arm-none-eabi-g++ -std=c++20 -Wall -Wextra -Wpedantic -O0 -g -gdwarf-2 -ffunction-sections -fdata-sections -x c++ -fno-rtti -fno-use-cxa-atexit -fno-exceptions -fno-nonansi-builtins -fno-threadsafe-statics -fno-enforce-eh-specs -ftemplate-depth=128 -mcpu=cortex-m4 -mtune=cortex-m4 -mthumb -mfloat-abi=soft -mno-unaligned-access -mno-long-calls -I../../include -DBOOST_DECIMAL_DISABLE_CLIB -DAPP_BENCHMARK_STANDALONE_MAIN app_benchmark_non_std_decimal.cpp ./target/micros/stm32f429/make/single/crt.cpp ./target/micros/stm32f429/make/single/mcal_gcc_cxx_completion_with_stdlib.cpp -nostartfiles -Wl,--gc-sections -Wl,-Map,./bin/app_benchmark_non_std_decimal.map -T ./target/micros/stm32f429/make/stm32f429.ld --specs=nano.specs --specs=nosys.specs -Wl,--print-memory-usage -o ./bin/app_benchmark_non_std_decimal.elf // arm-none-eabi-objcopy ./bin/app_benchmark_non_std_decimal.elf -O ihex ./bin/app_benchmark_non_std_decimal.hex // ls -la ./bin/app_benchmark_non_std_decimal.elf ./bin/app_benchmark_non_std_decimal.hex ./bin/app_benchmark_non_std_decimal.map diff --git a/test/metal/target/build/test_app_benchmarks_emulator.gdb b/test/metal/target/build/test_app_benchmarks_emulator.gdb new file mode 100644 index 000000000..c85858ba3 --- /dev/null +++ b/test/metal/target/build/test_app_benchmarks_emulator.gdb @@ -0,0 +1,28 @@ +# /////////////////////////////////////////////////////////////////// +# // Copyright Christopher Kormanyos 2020 - 2024. +# // Distributed under the Boost Software License, +# // Version 1.0. (See accompanying file LICENSE_1_0.txt +# // or copy at http://www.boost.org/LICENSE_1_0.txt) +# // + +# Connect to the target (e.g., OpenOCD or another GDB server). +target remote localhost:9999 +monitor halt + +# Ensure that the program is loaded. +load + +# Set a breakpoint at the specified subroutine. +break app_benchmark_get_standalone_result + +# Start or continue program execution. +continue + +# Format and print the value of a variable. +printf "value 0x%X\n\n", app_benchmark_standalone_result + +# Delete (all) breakpoint(s). +delete + +# Perform a non-elegant quit of the GDB session. +quit diff --git a/test/metal/target/build/test_app_benchmarks_emulator.py b/test/metal/target/build/test_app_benchmarks_emulator.py deleted file mode 100644 index 44bf8af57..000000000 --- a/test/metal/target/build/test_app_benchmarks_emulator.py +++ /dev/null @@ -1,131 +0,0 @@ -#------------------------------------------------------------------------------- -# Name: test_app_benchmarks_emulator.py -# Purpose: -# -# Author: Christopher Kormanyos -# -# Created: 02/04/2021 -# -# Copyright: Copyright Christopher Kormanyos 2020 - 2023 -# -# Licence: Distributed under the Boost Software License, -# Version 1.0. (See accompanying file LICENSE_1_0.txt -# or copy at http://www.boost.org/LICENSE_1_0.txt) -#------------------------------------------------------------------------------- - -#!/usr/bin/env python2 - -# import python packages -import gdb -import time -import logging -import sys - -#------------------------------------------------------------------------------- -# --- class: qemu_emulator -#------------------------------------------------------------------------------- -class qemu_emulator: - def __init__(self, tcp_port, iterations): - self.tcp_port = tcp_port - self.iterations = iterations - - # qemu initialization - def initialize(self): - self.connect_to_server(self.tcp_port) - self.create_log_file() - self.load_elf() - - # Excute gdb commands - def execute(self, command, from_tty = False, to_string = False): - gdb.execute('{}'.format(command), from_tty, to_string) - - # Create log file - def create_log_file(self): - logging.basicConfig(filename='emu-target.log',level=logging.DEBUG, filemode='w') - logging.info('------- Running GDB Test -----') - - # Connect to server - def connect_to_server(self, tcp_port): - self.execute('target remote localhost:{}'.format(tcp_port)) - self.execute('monitor reset') - self.execute('set confirm off') - - # Load object data base - def load_elf(self): - self.execute('load') - - # Run the benchmark - def run(self): - self.execute('continue') - - def next(self): - self.execute('next') - - # Set gdb Bp - def set_gdb_break_point(self): - my_bp = gdb.Breakpoint('app_benchmark_get_standalone_result') - return my_bp - - # Delete gdb Bp - def delete_gdb_break_point(self, bp): - bp.delete() - - # Get gdb result - def get_gdb_result(self): - my_result = gdb.parse_and_eval("app_benchmark_standalone_result") - return my_result - - # Convert from gdb type to hex - def convert_to_hex(self, gdb_value): - val_as_str = str(gdb_value) - val_as_hex = hex(int(val_as_str)) - return val_as_hex - - # Check the gdb return value - def check_gdb_result(self, result_as_hex): - if result_as_hex == "0xf00dcafe": - return True - else: - return False - -#------------------------------------------------------------------------------- -# --- GDB Script starts here -# See also https://embeddedartistry.com/blog/2020/11/09/metal-gdb-controlling-gdb-through-python-scripts-with-the-gdb-python-api/ -#------------------------------------------------------------------------------- - -# Script Config -tcp_port = 9999 -iterations = 64 - -# Create a qemu object -obj = qemu_emulator(tcp_port, iterations) - -# Initialize -obj.initialize() - -# Set break point -bp1 = obj.set_gdb_break_point() - -# Run the benchmark -obj.run() - -# Get gdb result -my_value = obj.get_gdb_result() -time.sleep(0.5) - -# Delete break point -obj.delete_gdb_break_point(bp1) - -# Convert gdb result to hex -value_as_hex = obj.convert_to_hex(my_value) - -# Print the return value -print("Result value as hex: " + value_as_hex) - -# Check the gdb result and quit -result_is_ok = obj.check_gdb_result(value_as_hex) - -if result_is_ok == True: - sys.exit(0) -else: - sys.exit(-1)