diff --git a/.github/workflows/real-time-cpp-benchmarks.yml b/.github/workflows/real-time-cpp-benchmarks.yml index 49dd20809..065f2b29f 100644 --- a/.github/workflows/real-time-cpp-benchmarks.yml +++ b/.github/workflows/real-time-cpp-benchmarks.yml @@ -198,45 +198,8 @@ jobs: ls -la ./bin/app_benchmark_cnl_scaled_integer.exe ./bin/app_benchmark_cnl_scaled_integer.exe working-directory: ./ref_app/ - benchmark_single-stm32f429-qemu-cnl: - runs-on: ubuntu-22.04 - defaults: - run: - shell: bash - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: '0' - - name: update-tools - run: | - sudo apt install libncurses5 libpython2.7 - 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 - working-directory: ./ref_app/ - - name: benchmark_single-stm32f429-qemu-cnl - run: | - git clone -b main --depth 1 https://github.com/johnmcfarlane/cnl.git ../cnl-root - mkdir -p bin - ./emu_env/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-g++ -std=c++20 -Wall -Wextra -pedantic -O2 -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./src/mcal/stm32f429 -I./src -I../cnl-root/include -DAPP_BENCHMARK_TYPE=APP_BENCHMARK_TYPE_CNL_SCALED_INTEGER -DAPP_BENCHMARK_STANDALONE_MAIN ./src/app/benchmark/app_benchmark_cnl_scaled_integer.cpp ./target/micros/stm32f429/make/single/crt.cpp -nostartfiles -Wl,--gc-sections -Wl,-Map,./bin/app_benchmark_cnl_scaled_integer.map -T ./target/micros/stm32f429/make/stm32f429.ld -o ./bin/app_benchmark_cnl_scaled_integer.elf - ./emu_env/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-objcopy ./bin/app_benchmark_cnl_scaled_integer.elf -O ihex ./bin/app_benchmark_cnl_scaled_integer.hex - ls -la ./bin/app_benchmark_cnl_scaled_integer.elf ./bin/app_benchmark_cnl_scaled_integer.hex ./bin/app_benchmark_cnl_scaled_integer.map - working-directory: ./ref_app/ - - 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 & - working-directory: ./ref_app/ - - 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_cnl_scaled_integer.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' - working-directory: ./ref_app/ benchmark_single-stm32f429-qemu: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest defaults: run: shell: bash @@ -246,28 +209,40 @@ jobs: fetch-depth: '0' - name: update-tools run: | - sudo apt install libncurses5 libpython2.7 + sudo apt install libncursesw5 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: ./ref_app/ - name: build benchmark_single-stm32f429 run: | + PATH="${{ runner.workspace }}/qemu_arm_sample/ref_app/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++20 -Wall -Wextra -pedantic -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=32 -mcpu=cortex-m4 -mtune=cortex-m4 -mthumb -mfloat-abi=soft -mno-unaligned-access -mno-long-calls -I./src/mcal/stm32f429 -I./src -DAPP_BENCHMARK_TYPE=APP_BENCHMARK_TYPE_CRC -DAPP_BENCHMARK_STANDALONE_MAIN ./src/app/benchmark/app_benchmark_crc.cpp ./target/micros/stm32f429/make/single/crt.cpp -nostartfiles -Wl,--gc-sections -Wl,-Map,./bin/app_benchmark_crc.map -T ./target/micros/stm32f429/make/stm32f429.ld --specs=nano.specs --specs=nosys.specs -o ./bin/app_benchmark_crc.elf - emu_env/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-objcopy ./bin/app_benchmark_crc.elf -O ihex ./bin/app_benchmark_crc.hex + arm-none-eabi-g++ -std=c++20 -Werror -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -O2 -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=32 -mcpu=cortex-m4 -mtune=cortex-m4 -mthumb -mfloat-abi=soft -mno-unaligned-access -mno-long-calls -I./src/mcal/stm32f429 -I./src -DAPP_BENCHMARK_TYPE=APP_BENCHMARK_TYPE_CRC -DAPP_BENCHMARK_STANDALONE_MAIN ./src/app/benchmark/app_benchmark_crc.cpp ./target/micros/stm32f429/make/single/crt.cpp -nostartfiles -nostdlib -Wl,--gc-sections -Wl,-Map,./bin/app_benchmark_crc.map -T ./target/micros/stm32f429/make/stm32f429.ld --specs=nano.specs --specs=nosys.specs -o ./bin/app_benchmark_crc.elf + arm-none-eabi-objcopy ./bin/app_benchmark_crc.elf -O ihex ./bin/app_benchmark_crc.hex ls -la ./bin/app_benchmark_crc.elf ./bin/app_benchmark_crc.hex ./bin/app_benchmark_crc.map working-directory: ./ref_app/ - 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 }}/qemu_arm_sample/ref_app/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: ./ref_app/ - 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_crc.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 }}/qemu_arm_sample/ref_app/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_crc.elf -x ./target/build/test_app_benchmarks_emulator.gdb > ./app_benchmark_crc.txt + cat ./app_benchmark_crc.txt + echo + echo 'We will now grep for the right answer...' + grep 'value 0xF00DCAFE' ./app_benchmark_crc.txt working-directory: ./ref_app/ diff --git a/ref_app/target.vcxproj b/ref_app/target.vcxproj index 7ba2783f8..24695c649 100644 --- a/ref_app/target.vcxproj +++ b/ref_app/target.vcxproj @@ -866,7 +866,7 @@ - + diff --git a/ref_app/target.vcxproj.filters b/ref_app/target.vcxproj.filters index 3392b22bb..a80e342fc 100644 --- a/ref_app/target.vcxproj.filters +++ b/ref_app/target.vcxproj.filters @@ -516,9 +516,6 @@ micros\v850es_fx2\startup - - build - micros\stm32h7a3\make @@ -612,6 +609,9 @@ micros\rpi_pico2_rp2350\startup + + build + diff --git a/ref_app/target/build/test_app_benchmarks_emulator.gdb b/ref_app/target/build/test_app_benchmarks_emulator.gdb new file mode 100644 index 000000000..c85858ba3 --- /dev/null +++ b/ref_app/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/ref_app/target/build/test_app_benchmarks_emulator.py b/ref_app/target/build/test_app_benchmarks_emulator.py deleted file mode 100755 index e6f76c23b..000000000 --- a/ref_app/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 - 2024 -# -# 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) diff --git a/ref_app/target/micros/stm32f429/make/single/crt.cpp b/ref_app/target/micros/stm32f429/make/single/crt.cpp index 84a9cb684..86a9a78c6 100644 --- a/ref_app/target/micros/stm32f429/make/single/crt.cpp +++ b/ref_app/target/micros/stm32f429/make/single/crt.cpp @@ -1,10 +1,17 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2018 - 2019. +// Copyright Christopher Kormanyos 2018 - 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) // +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow=" +#endif + #include #include #include @@ -36,7 +43,8 @@ void __my_startup(void) // the base position of the interrupt vector table. // So we do nothing here. - // TBD: Chip init: Watchdog, port, and oscillator, if any needed. + // Note: Not needed: + // Chip init: Watchdog, port, and oscillator, if any needed. // Initialize statics from ROM to RAM. // Zero-clear default-initialized static RAM. @@ -49,9 +57,7 @@ void __my_startup(void) asm volatile("ldr r3, =main"); asm volatile("blx r3"); - exit(EXIT_SUCCESS); - - // TBD: Nothing on return from main. + // Do nothing on return from main. } extern "C" void _exit (int); @@ -113,31 +119,31 @@ void crt::init_ctors() extern "C" void __initial_stack_pointer(); extern "C" void __my_startup () __attribute__((used, noinline)); -extern "C" void __vector_unused_irq (void) __attribute__((used, noinline)); -extern "C" void __nmi_handler (void) __attribute__((used, noinline)); -extern "C" void __hard_fault_handler (void) __attribute__((used, noinline)); -extern "C" void __mem_manage_handler (void) __attribute__((used, noinline)); -extern "C" void __bus_fault_handler (void) __attribute__((used, noinline)); -extern "C" void __usage_fault_handler(void) __attribute__((used, noinline)); -extern "C" void __svc_handler (void) __attribute__((used, noinline)); -extern "C" void __debug_mon_handler (void) __attribute__((used, noinline)); -extern "C" void __pend_sv_handler (void) __attribute__((used, noinline)); -extern "C" void __sys_tick_handler (void) __attribute__((used, noinline)); +extern "C" void __vector_unused_irq () __attribute__((used, noinline)); +extern "C" void __nmi_handler () __attribute__((used, noinline)); +extern "C" void __hard_fault_handler () __attribute__((used, noinline)); +extern "C" void __mem_manage_handler () __attribute__((used, noinline)); +extern "C" void __bus_fault_handler () __attribute__((used, noinline)); +extern "C" void __usage_fault_handler() __attribute__((used, noinline)); +extern "C" void __svc_handler () __attribute__((used, noinline)); +extern "C" void __debug_mon_handler () __attribute__((used, noinline)); +extern "C" void __pend_sv_handler () __attribute__((used, noinline)); +extern "C" void __sys_tick_handler () __attribute__((used, noinline)); -extern "C" void __vector_unused_irq (void) { for(;;) { ; } } -extern "C" void __nmi_handler (void) { for(;;) { ; } } -extern "C" void __hard_fault_handler (void) { for(;;) { ; } } -extern "C" void __mem_manage_handler (void) { for(;;) { ; } } -extern "C" void __bus_fault_handler (void) { for(;;) { ; } } -extern "C" void __usage_fault_handler(void) { for(;;) { ; } } -extern "C" void __svc_handler (void) { for(;;) { ; } } -extern "C" void __debug_mon_handler (void) { for(;;) { ; } } -extern "C" void __pend_sv_handler (void) { for(;;) { ; } } -extern "C" void __sys_tick_handler (void) { for(;;) { ; } } +extern "C" void __vector_unused_irq () { for(;;) { ; } } +extern "C" void __nmi_handler () { for(;;) { ; } } +extern "C" void __hard_fault_handler () { for(;;) { ; } } +extern "C" void __mem_manage_handler () { for(;;) { ; } } +extern "C" void __bus_fault_handler () { for(;;) { ; } } +extern "C" void __usage_fault_handler() { for(;;) { ; } } +extern "C" void __svc_handler () { for(;;) { ; } } +extern "C" void __debug_mon_handler () { for(;;) { ; } } +extern "C" void __pend_sv_handler () { for(;;) { ; } } +extern "C" void __sys_tick_handler () { for(;;) { ; } } namespace { - typedef void(*isr_type)(void); + typedef void(*isr_type)(); constexpr std::size_t number_of_interrupts = 128U; } @@ -278,3 +284,7 @@ const volatile std::array __isr_vector = nullptr // 0x01FC, dummy }}; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#pragma GCC diagnostic pop +#endif