From 1acedd70ed105b8e23d17c15d02f9ae51d50bcc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sun, 21 Apr 2024 17:18:13 +0200 Subject: [PATCH 01/34] Add support for FlexPRET --- low_level_platform/api/CMakeLists.txt | 2 + low_level_platform/api/low_level_platform.h | 2 + .../api/platform/lf_flexpret_support.h | 125 +++++++++++ low_level_platform/impl/CMakeLists.txt | 8 + low_level_platform/impl/src/lf_atomic_irq.c | 6 +- .../impl/src/lf_flexpret_support.c | 201 ++++++++++++++++++ platform/impl/CMakeLists.txt | 4 + 7 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 low_level_platform/api/platform/lf_flexpret_support.h create mode 100644 low_level_platform/impl/src/lf_flexpret_support.c diff --git a/low_level_platform/api/CMakeLists.txt b/low_level_platform/api/CMakeLists.txt index b4598ed9c..3f3a50936 100644 --- a/low_level_platform/api/CMakeLists.txt +++ b/low_level_platform/api/CMakeLists.txt @@ -9,4 +9,6 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_ZEPHYR) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_RP2040) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") + target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_FLEXPRET) endif() diff --git a/low_level_platform/api/low_level_platform.h b/low_level_platform/api/low_level_platform.h index 2867aa0f4..2ef93f24a 100644 --- a/low_level_platform/api/low_level_platform.h +++ b/low_level_platform/api/low_level_platform.h @@ -50,6 +50,8 @@ int lf_critical_section_exit(environment_t* env); #include "platform/lf_nrf52_support.h" #elif defined(PLATFORM_RP2040) #include "platform/lf_rp2040_support.h" +#elif defined(PLATFORM_FLEXPRET) +#include "platform/lf_flexpret_support.h" #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) // Windows platforms #include "platform/lf_windows_support.h" diff --git a/low_level_platform/api/platform/lf_flexpret_support.h b/low_level_platform/api/platform/lf_flexpret_support.h new file mode 100644 index 000000000..058607669 --- /dev/null +++ b/low_level_platform/api/platform/lf_flexpret_support.h @@ -0,0 +1,125 @@ +/* FlexPRET API support for the C target of Lingua Franca. */ + +/************* +Copyright (c) 2021, The University of California at Berkeley. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***************/ + +/** + * FlexPRET API support for the C target of Lingua Franca. + * + * This is based on lf_nrf_support.h in icyphy/lf-buckler. + * + * @author{Soroush Bateni } + * @author{Abhi Gundrala } + * @author{Shaokai Lin } + */ + +#ifndef LF_FLEXPRET_SUPPORT_H +#define LF_FLEXPRET_SUPPORT_H + +#include // For fixed-width integral types +#include // For CLOCK_MONOTONIC +#include +#include // Defines va_list +#include // Defines FILE +#include // Defines strlen + +#include + + +/** + * printf.h does not include definitions of vfprintf, so to avoid linking + * newlib's vfprintf we replace all occurrances of it with just printf + * + */ +#define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD 0 +#define vfprintf(fp, fmt, args) vprintf(fmt, args) + +/** + * Like nRF52, for FlexPRET, each mutex will control an interrupt. + * + * The mutex holds the interrupt number. + * For example, a mutex might be defined for the GPIOTE peripheral interrupt number + * + * When initialized, the interrupt is inserted into a global linked list + * for disabling and enabling all interrupts during sleep functions. + * - All interrupts are disabled by default after initialization + * - Priority levels are restricted between (0-7) + * + */ + +// Define PRINTF_TIME and PRINTF_MICROSTEP, which are the printf +// codes (like the d in %d to print an int) for time and microsteps. +// To use these, specify the printf as follows: +// printf("%" PRINTF_TIME "\n", time_value); +// On most platforms, time is an signed 64-bit number (int64_t) and +// the microstep is an unsigned 32-bit number (uint32_t). +// Sadly, in C, there is no portable to print such numbers using +// printf without getting a warning on some platforms. +// On each platform, the code for printf if given by the macros +// PRId64 and PRIu32 defined in inttypes.h. Hence, here, we import +// inttypes.h, then define PRINTF_TIME and PRINTF_MICROSTEP. +// If you are targeting a platform that uses some other type +// for time and microsteps, you can simply define +// PRINTF_TIME and PRINTF_MICROSTEP directly in the same file that +// defines the types _instant_t, _interval_t, and _microstep_t. +#include // Needed to define PRId64 and PRIu32 +#define PRINTF_TIME "%" PRId64 +#define PRINTF_MICROSTEP "%" PRIu32 + +// For convenience, the following string can be inserted in a printf +// format for printing both time and microstep as follows: +// printf("Tag is " PRINTF_TAG "\n", time_value, microstep); +#define PRINTF_TAG "(%" PRId64 ", %" PRIu32 ")" + +/** + * Time instant. Both physical and logical times are represented + * using this typedef. + * WARNING: If this code is used after about the year 2262, + * then representing time as a 64-bit long long will be insufficient. + */ +typedef int64_t _instant_t; + +/** + * Interval of time. + */ +typedef int64_t _interval_t; + +/** + * Microstep instant. + */ +typedef uint32_t _microstep_t; + +#include +#define _LF_TIMEOUT ETIMEDOUT + +// The underlying physical clock for Linux +#define _LF_CLOCK CLOCK_MONOTONIC + +#if !defined(LF_SINGLE_THREADED) +typedef fp_lock_t lf_mutex_t; +typedef fp_thread_t lf_thread_t; +typedef fp_cond_t lf_cond_t; +#endif + +#endif // LF_FLEXPRET_SUPPORT_H diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index 5f6244664..a1c6a402f 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -39,6 +39,11 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") ${CMAKE_CURRENT_LIST_DIR}/src/lf_rp2040_support.c ${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_irq.c ) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") + set(LF_LOW_LEVEL_PLATFORM_FILES + ${CMAKE_CURRENT_LIST_DIR}/src/lf_flexpret_support.c + ${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_irq.c + ) else() message(FATAL_ERROR "Your platform is not supported! The C target supports Linux, MacOS, Windows, Zephyr, Nrf52 and RP2040.") endif() @@ -54,6 +59,9 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") zephyr_library_named(lf-low-level-platform-impl) zephyr_library_sources(${LF_LOW_LEVEL_PLATFORM_FILES}) zephyr_library_link_libraries(kernel) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") + add_library(lf-low-level-platform-impl STATIC ${LF_LOW_LEVEL_PLATFORM_FILES}) + target_link_libraries(lf-low-level-platform-impl PRIVATE fp-sdk-if) else() add_library(lf-low-level-platform-impl STATIC ${LF_LOW_LEVEL_PLATFORM_FILES}) # Link the platform to a threading library diff --git a/low_level_platform/impl/src/lf_atomic_irq.c b/low_level_platform/impl/src/lf_atomic_irq.c index 7be9aff34..9224fa615 100644 --- a/low_level_platform/impl/src/lf_atomic_irq.c +++ b/low_level_platform/impl/src/lf_atomic_irq.c @@ -1,4 +1,8 @@ -#if defined(PLATFORM_ARDUINO) || defined(PLATFORM_NRF52) || defined(PLATFORM_ZEPHYR) || defined(PLATFORM_RP2040) +#if defined(PLATFORM_ARDUINO) || \ + defined(PLATFORM_NRF52) || \ + defined(PLATFORM_ZEPHYR) || \ + defined(PLATFORM_RP2040) || \ + defined(PLATFORM_FLEXPRET) /** * @author Erling Rennemo Jellum * @copyright (c) 2023 diff --git a/low_level_platform/impl/src/lf_flexpret_support.c b/low_level_platform/impl/src/lf_flexpret_support.c new file mode 100644 index 000000000..f8f02f1c6 --- /dev/null +++ b/low_level_platform/impl/src/lf_flexpret_support.c @@ -0,0 +1,201 @@ +/************* +Copyright (c) 2021, The University of California at Berkeley. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***************/ + +/** Support file for Bare-metal FlexPRET platform. + * + * @author{Shaokai Lin } + */ + +#include +#include +#include +#include "low_level_platform.h" + +/** + * Used to keep track of the number of nested critical sections. + * + * We should only disable interrupts when this is zero and we enter a critical section + * We should only enable interrupts when we exit a critical section and this is zero + */ +static int critical_section_num_nested[FP_THREADS] = + THREAD_ARRAY_INITIALIZER(0); + +/** + * @return 0 for success, or -1 for failure + */ + +static volatile uint32_t last_time = 0; +static volatile uint64_t epoch = 0; +#define EPOCH_DURATION_NS (1ULL << 32) +int _lf_clock_gettime(instant_t* t) { + uint32_t now = rdtime(); + if (now < last_time) { + epoch += EPOCH_DURATION_NS; + } + *t = now + epoch; + last_time = now; + return 0; +} + +int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { + int ret = 0; + if (wakeup_time < 0) { + return ret; + } + + // Enable interrupts and execute wait until instruction + lf_critical_section_exit(env); + + // Wait until will stop sleep if interrupt occurs + fp_wait_until(wakeup_time); + + if ((instant_t) rdtime64() < wakeup_time) { + // Interrupt occurred because we did not wait full wakeup_time + ret = -1; + } + + lf_critical_section_enter(env); + return ret; +} + +int lf_sleep(interval_t sleep_duration) { + // FIXME: Handle sleep durations exceeding 32bit + fp_delay_for(sleep_duration); + return 0; +} + +/** + * Initialize the LF clock. + */ +void _lf_initialize_clock() { + // FlexPRET does not require any initialization +} + +int lf_disable_interrupts_nested() { + // In the special case where this function is called during an interrupt + // subroutine (isr) it should have no effect + if ((read_csr(CSR_STATUS) & 0x04) == 0x04) return 0; + + uint32_t hartid = read_hartid(); + + fp_assert(critical_section_num_nested[hartid] >= 0, "Number of nested critical sections less than zero."); + if (critical_section_num_nested[hartid]++ == 0) { + fp_interrupt_disable(); + } + return 0; +} + +int lf_enable_interrupts_nested() { + // In the special case where this function is called during an interrupt + // subroutine (isr) it should have no effect + if ((read_csr(CSR_STATUS) & 0x04) == 0x04) return 0; + + uint32_t hartid = read_hartid(); + + if (--critical_section_num_nested[hartid] == 0) { + fp_interrupt_enable(); + } + fp_assert(critical_section_num_nested[hartid] >= 0, "Number of nested critical sections less than zero."); + return 0; +} + +/** + * Pause execution for a number of nanoseconds. + * + * @return 0 for success, or -1 for failure. In case of failure, errno will be + * set appropriately (see `man 2 clock_nanosleep`). + */ +int lf_nanosleep(interval_t requested_time) { + instant_t t; + _lf_clock_gettime(&t); + instant_t expire_time = t + requested_time; + while (t < expire_time) { + _lf_clock_gettime(&t); + } + return 0; +} + +#if defined(LF_SINGLE_THREADED) + +int _lf_single_threaded_notify_of_event() { + // No need to do anything, because an interrupt will cancel wait until + // This is specific to FlexPRET + return 0; +} + +#else // Multi threaded + +int lf_available_cores() { + return FP_THREADS; // Return the number of Flexpret HW threads +} + +int lf_thread_create(lf_thread_t* thread, void *(*lf_thread) (void *), void* arguments) { + // TODO: Decide between HRTT or SRTT + return fp_thread_create(HRTT, thread, lf_thread, arguments); +} + +int lf_thread_join(lf_thread_t thread, void** thread_return) { + return fp_thread_join(thread, thread_return); +} + +int lf_mutex_init(lf_mutex_t* mutex) { + *mutex = (lf_mutex_t) FP_LOCK_INITIALIZER; + return 0; +} + +int lf_mutex_lock(lf_mutex_t* mutex) { + fp_lock_acquire(mutex); + return 0; +} + +int lf_mutex_unlock(lf_mutex_t* mutex) { + fp_lock_release(mutex); + return 0; +} + +int lf_cond_init(lf_cond_t* cond, lf_mutex_t* mutex) { + *cond = (lf_cond_t) FP_COND_INITIALIZER(mutex); + return 0; +} + +int lf_cond_broadcast(lf_cond_t* cond) { + return fp_cond_broadcast(cond); +} + +int lf_cond_signal(lf_cond_t* cond) { + return fp_cond_signal(cond); +} + +int lf_cond_wait(lf_cond_t* cond) { + return fp_cond_wait(cond); +} + +int _lf_cond_timedwait(lf_cond_t* cond, instant_t absolute_time_ns) { + return fp_cond_timed_wait(cond, absolute_time_ns); +} + +int lf_thread_id() { + return read_hartid(); +} + +void initialize_lf_thread_id() { + // TODO: Verify: Don't think anything is necessary here for FlexPRET +} +#endif diff --git a/platform/impl/CMakeLists.txt b/platform/impl/CMakeLists.txt index cef66b5ef..096b99e8d 100644 --- a/platform/impl/CMakeLists.txt +++ b/platform/impl/CMakeLists.txt @@ -5,6 +5,10 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") zephyr_library_named(lf-platform-impl) zephyr_library_sources(${LF_PLATFORM_FILES}) zephyr_library_link_libraries(kernel) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") + add_library(lf-platform-impl STATIC) + target_sources(lf-platform-impl PUBLIC ${LF_PLATFORM_FILES}) + target_link_libraries(lf-platform-impl PUBLIC fp-sdk-if) else() add_library(lf-platform-impl STATIC) target_sources(lf-platform-impl PUBLIC ${LF_PLATFORM_FILES}) From eb797206c781d956a2b7fcb8d06a1327e66996b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Mon, 22 Apr 2024 20:10:48 +0200 Subject: [PATCH 02/34] Add FlexPRET to error message --- low_level_platform/impl/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index a1c6a402f..1825cf98d 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -45,7 +45,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") ${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_irq.c ) else() - message(FATAL_ERROR "Your platform is not supported! The C target supports Linux, MacOS, Windows, Zephyr, Nrf52 and RP2040.") + message(FATAL_ERROR "Your platform is not supported! The C target supports Linux, MacOS, Windows, Zephyr, Nrf52, RP2040 and FlexPRET.") endif() list(APPEND LF_LOW_LEVEL_PLATFORM_FILES ${CMAKE_CURRENT_LIST_DIR}/src/lf_platform_util.c) From cacaff12b0ce5b387df062bae6769b8677127693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Wed, 24 Apr 2024 00:55:21 +0200 Subject: [PATCH 03/34] Add check on number of threads available in FlexPRET's hardware. --- low_level_platform/impl/CMakeLists.txt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index 1825cf98d..c4e94c913 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -61,7 +61,23 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") zephyr_library_link_libraries(kernel) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") add_library(lf-low-level-platform-impl STATIC ${LF_LOW_LEVEL_PLATFORM_FILES}) - target_link_libraries(lf-low-level-platform-impl PRIVATE fp-sdk-if) + target_link_libraries(lf-low-level-platform-impl PUBLIC fp-sdk) + + if (DEFINED NUMBER_OF_WORKERS) + # Verify that FlexPRET has the number of requested workers + # That information is available in the SDK's hwconfig + include($ENV{FP_SDK_PATH}/flexpret/hwconfig.cmake) + math(EXPR FLEXPRET_AVAILABLE_WORKERS "${THREADS} - 1") + + if (${NUMBER_OF_WORKERS} GREATER ${THREADS}) + message(FATAL_ERROR + "Number of requested workers (${NUMBER_OF_WORKERS}) is higher \ + than FlexPRET's number of available workers \ + (${FLEXPET_AVAILABLE_WORKERS}). Note that FlexPRET uses \ + hardware threads, not the usual software threads" + ) + endif() + endif() else() add_library(lf-low-level-platform-impl STATIC ${LF_LOW_LEVEL_PLATFORM_FILES}) # Link the platform to a threading library From 74fc6015d7dc6d1274ee041d1c8935bd42c5febc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Thu, 25 Apr 2024 03:10:08 +0200 Subject: [PATCH 04/34] Fixes to CMakeLists --- low_level_platform/api/CMakeLists.txt | 1 + low_level_platform/impl/CMakeLists.txt | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/low_level_platform/api/CMakeLists.txt b/low_level_platform/api/CMakeLists.txt index 3f3a50936..47817b59a 100644 --- a/low_level_platform/api/CMakeLists.txt +++ b/low_level_platform/api/CMakeLists.txt @@ -10,5 +10,6 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_RP2040) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") + target_link_libraries(lf-low-level-platform-api INTERFACE fp-sdk-if) target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_FLEXPRET) endif() diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index c4e94c913..28ae68c9e 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -61,12 +61,18 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") zephyr_library_link_libraries(kernel) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") add_library(lf-low-level-platform-impl STATIC ${LF_LOW_LEVEL_PLATFORM_FILES}) - target_link_libraries(lf-low-level-platform-impl PUBLIC fp-sdk) if (DEFINED NUMBER_OF_WORKERS) # Verify that FlexPRET has the number of requested workers # That information is available in the SDK's hwconfig include($ENV{FP_SDK_PATH}/flexpret/hwconfig.cmake) + if (NOT DEFINED THREADS) + message(FATAL_ERROR + "Missing FlexPRET hardware configuration; check that FlexPRET has \ + been installed to the SDK." + ) + endif() + math(EXPR FLEXPRET_AVAILABLE_WORKERS "${THREADS} - 1") if (${NUMBER_OF_WORKERS} GREATER ${THREADS}) From 14ed735138d41599d17c88a3bc13530380d6b5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Wed, 1 May 2024 23:06:23 +0200 Subject: [PATCH 05/34] Fix bug: lf_available_cores() needs to return 1 less than FP_THREADS. --- low_level_platform/impl/src/lf_flexpret_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/low_level_platform/impl/src/lf_flexpret_support.c b/low_level_platform/impl/src/lf_flexpret_support.c index f8f02f1c6..178b4948a 100644 --- a/low_level_platform/impl/src/lf_flexpret_support.c +++ b/low_level_platform/impl/src/lf_flexpret_support.c @@ -143,7 +143,7 @@ int _lf_single_threaded_notify_of_event() { #else // Multi threaded int lf_available_cores() { - return FP_THREADS; // Return the number of Flexpret HW threads + return FP_THREADS-1; // Return the number of Flexpret HW threads } int lf_thread_create(lf_thread_t* thread, void *(*lf_thread) (void *), void* arguments) { From 3bd8a108d078c58e881744d95ab42251116e334b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Thu, 2 May 2024 02:16:34 +0200 Subject: [PATCH 06/34] Fix typo --- low_level_platform/impl/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index 28ae68c9e..80c90de5d 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -79,7 +79,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") message(FATAL_ERROR "Number of requested workers (${NUMBER_OF_WORKERS}) is higher \ than FlexPRET's number of available workers \ - (${FLEXPET_AVAILABLE_WORKERS}). Note that FlexPRET uses \ + (${FLEXPRET_AVAILABLE_WORKERS}). Note that FlexPRET uses \ hardware threads, not the usual software threads" ) endif() From 1afab5654c7f9690ae914bd2c813a5e5f7f8410d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Fri, 3 May 2024 02:26:42 +0200 Subject: [PATCH 07/34] Add hacky solution to code size for FlexPRET. --- low_level_platform/api/CMakeLists.txt | 26 ++++++++++++++ .../impl/src/lf_flexpret_stubs.c | 36 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 low_level_platform/impl/src/lf_flexpret_stubs.c diff --git a/low_level_platform/api/CMakeLists.txt b/low_level_platform/api/CMakeLists.txt index 47817b59a..5e590e87f 100644 --- a/low_level_platform/api/CMakeLists.txt +++ b/low_level_platform/api/CMakeLists.txt @@ -12,4 +12,30 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") target_link_libraries(lf-low-level-platform-api INTERFACE fp-sdk-if) target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_FLEXPRET) + + # This is explained in issue https://github.com/lf-lang/reactor-c/issues/418 + # The stubs are found in `../impl/src/lf_flexpret_stubs.c`. + target_link_options(lf-low-level-platform-api INTERFACE + "-Wl,--wrap=_vfprintf_r" "-Wl,--wrap=__ssvfiscanf_r" "-Wl,--wrap=_svfiprintf_r" + ) + + # This is related to issue https://github.com/lf-lang/reactor-c/issues/418 + # + # The ordering of libraries passed to `gcc` matters + # (https://stackoverflow.com/a/2487723/16358883) + # Since we want `newlib` to link into our wrapper functions, our library + # needs to come after `newlib` on the command line. But we cannot choose + # where `newlib` is placed on the command line - and it is most likely at + # the very end (because everything is expected to link into it). + # + # Therefore, just adding these three functions normally into the library + # will yield `undefined reference` errors. + # + # The solution is to instead link in our three functions as an object file. + # The ordering of object files does not matter. To do this, we add the source + # as an interface, which means it will be passed onto the main target and + # compiled as an object file there. + target_sources(lf-low-level-platform-api INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/../impl/src/lf_flexpret_stubs.c + ) endif() diff --git a/low_level_platform/impl/src/lf_flexpret_stubs.c b/low_level_platform/impl/src/lf_flexpret_stubs.c new file mode 100644 index 000000000..c36201597 --- /dev/null +++ b/low_level_platform/impl/src/lf_flexpret_stubs.c @@ -0,0 +1,36 @@ +/** + * @file lf_flexpret_stubs.c + * @author Magnus Mæhlum (magnmaeh@stud.ntnu.no) + * @brief Contains stubs for large `newlib` functions to drastically reduce + * code size for the FlexPRET target. This is necessary for FlexPRET + * because it has a very limited amount of instruction memory space. + * + * See issue https://github.com/lf-lang/reactor-c/issues/418 + * for a complete description of the problem. + * + * Passing `-Wl,--wrap=function` causes linker to rename `function` + * to `__real_function`. It also calls `__wrap_function` where `function` + * used to be called. In this way, the user can implement wrapper functions + * for already compiled functions like so: + * + * void __wrap_function() { + * printf("Wrapper code before function call\n"); + * __real_function(); // The actual function call + * printf("Wrapper code after function call\n"); + * } + * + * We instead use it to remove all references to `__real_function`, + * which drastically reduces code size. If we do this, the function + * signature of the original function does not matter either, so we can + * just write `void __wrap_function(void)`. + * + * https://linux.die.net/man/1/ld (search for `--wrap=symbol`) + * + * @date 2024-05-03 + * + */ + +// This reduces FlexPRET's code size by approximately 50%. +void __wrap__vfprintf_r(void) {} +void __wrap___ssvfiscanf_r(void) {} +void __wrap__svfiprintf_r(void) {} From bd54f002c307c6dd230260e14370131f1a2dd45c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Fri, 3 May 2024 13:26:27 +0200 Subject: [PATCH 08/34] Remove wrap hack and instead filter out newlib functions that cause large code size. --- core/threaded/reactor_threaded.c | 5 +++ low_level_platform/api/CMakeLists.txt | 26 -------------- .../api/platform/lf_flexpret_support.h | 7 ++++ .../impl/src/lf_flexpret_stubs.c | 36 ------------------- 4 files changed, 12 insertions(+), 62 deletions(-) delete mode 100644 low_level_platform/impl/src/lf_flexpret_stubs.c diff --git a/core/threaded/reactor_threaded.c b/core/threaded/reactor_threaded.c index 57f888fc2..1d7598723 100644 --- a/core/threaded/reactor_threaded.c +++ b/core/threaded/reactor_threaded.c @@ -1072,8 +1072,13 @@ int lf_reactor_c_main(int argc, const char* argv[]) { LF_PRINT_DEBUG("Start time: " PRINTF_TIME "ns", start_time); struct timespec physical_time_timespec = {start_time / BILLION, start_time % BILLION}; + +#ifdef NO_TTY + lf_print("---- Start execution ----"); +#else lf_print("---- Start execution at time %s---- plus %ld nanoseconds", ctime(&physical_time_timespec.tv_sec), physical_time_timespec.tv_nsec); +#endif // NO_TTY // Create and initialize the environments for each enclave lf_create_environments(); diff --git a/low_level_platform/api/CMakeLists.txt b/low_level_platform/api/CMakeLists.txt index 5e590e87f..47817b59a 100644 --- a/low_level_platform/api/CMakeLists.txt +++ b/low_level_platform/api/CMakeLists.txt @@ -12,30 +12,4 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") target_link_libraries(lf-low-level-platform-api INTERFACE fp-sdk-if) target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_FLEXPRET) - - # This is explained in issue https://github.com/lf-lang/reactor-c/issues/418 - # The stubs are found in `../impl/src/lf_flexpret_stubs.c`. - target_link_options(lf-low-level-platform-api INTERFACE - "-Wl,--wrap=_vfprintf_r" "-Wl,--wrap=__ssvfiscanf_r" "-Wl,--wrap=_svfiprintf_r" - ) - - # This is related to issue https://github.com/lf-lang/reactor-c/issues/418 - # - # The ordering of libraries passed to `gcc` matters - # (https://stackoverflow.com/a/2487723/16358883) - # Since we want `newlib` to link into our wrapper functions, our library - # needs to come after `newlib` on the command line. But we cannot choose - # where `newlib` is placed on the command line - and it is most likely at - # the very end (because everything is expected to link into it). - # - # Therefore, just adding these three functions normally into the library - # will yield `undefined reference` errors. - # - # The solution is to instead link in our three functions as an object file. - # The ordering of object files does not matter. To do this, we add the source - # as an interface, which means it will be passed onto the main target and - # compiled as an object file there. - target_sources(lf-low-level-platform-api INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/../impl/src/lf_flexpret_stubs.c - ) endif() diff --git a/low_level_platform/api/platform/lf_flexpret_support.h b/low_level_platform/api/platform/lf_flexpret_support.h index 058607669..0971846ae 100644 --- a/low_level_platform/api/platform/lf_flexpret_support.h +++ b/low_level_platform/api/platform/lf_flexpret_support.h @@ -122,4 +122,11 @@ typedef fp_thread_t lf_thread_t; typedef fp_cond_t lf_cond_t; #endif +// FlexPRET has no tty +#define NO_TTY + +// Likewise, fprintf is used to print to `stderr`, but FlexPRET has no `stderr` +// We instead redirect its output to normal printf +#define fprintf(stream, fmt, ...) printf(fmt, ##__VA_ARGS__) + #endif // LF_FLEXPRET_SUPPORT_H diff --git a/low_level_platform/impl/src/lf_flexpret_stubs.c b/low_level_platform/impl/src/lf_flexpret_stubs.c deleted file mode 100644 index c36201597..000000000 --- a/low_level_platform/impl/src/lf_flexpret_stubs.c +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file lf_flexpret_stubs.c - * @author Magnus Mæhlum (magnmaeh@stud.ntnu.no) - * @brief Contains stubs for large `newlib` functions to drastically reduce - * code size for the FlexPRET target. This is necessary for FlexPRET - * because it has a very limited amount of instruction memory space. - * - * See issue https://github.com/lf-lang/reactor-c/issues/418 - * for a complete description of the problem. - * - * Passing `-Wl,--wrap=function` causes linker to rename `function` - * to `__real_function`. It also calls `__wrap_function` where `function` - * used to be called. In this way, the user can implement wrapper functions - * for already compiled functions like so: - * - * void __wrap_function() { - * printf("Wrapper code before function call\n"); - * __real_function(); // The actual function call - * printf("Wrapper code after function call\n"); - * } - * - * We instead use it to remove all references to `__real_function`, - * which drastically reduces code size. If we do this, the function - * signature of the original function does not matter either, so we can - * just write `void __wrap_function(void)`. - * - * https://linux.die.net/man/1/ld (search for `--wrap=symbol`) - * - * @date 2024-05-03 - * - */ - -// This reduces FlexPRET's code size by approximately 50%. -void __wrap__vfprintf_r(void) {} -void __wrap___ssvfiscanf_r(void) {} -void __wrap__svfiprintf_r(void) {} From cc6163ed0b22b3a30bc8978afac44a93d1741913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Fri, 3 May 2024 15:15:52 +0200 Subject: [PATCH 09/34] Fix small bug --- low_level_platform/impl/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index 80c90de5d..c7c5e1b13 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -75,7 +75,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") math(EXPR FLEXPRET_AVAILABLE_WORKERS "${THREADS} - 1") - if (${NUMBER_OF_WORKERS} GREATER ${THREADS}) + if (${NUMBER_OF_WORKERS} GREATER ${FLEXPRET_AVAILABLE_WORKERS}) message(FATAL_ERROR "Number of requested workers (${NUMBER_OF_WORKERS}) is higher \ than FlexPRET's number of available workers \ From b1b9a91a617d001017ceebfef4d8cde5733b1ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Fri, 3 May 2024 15:19:50 +0200 Subject: [PATCH 10/34] Minor fixes --- low_level_platform/impl/src/lf_flexpret_support.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/low_level_platform/impl/src/lf_flexpret_support.c b/low_level_platform/impl/src/lf_flexpret_support.c index 178b4948a..d7f910345 100644 --- a/low_level_platform/impl/src/lf_flexpret_support.c +++ b/low_level_platform/impl/src/lf_flexpret_support.c @@ -21,6 +21,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** Support file for Bare-metal FlexPRET platform. * * @author{Shaokai Lin } + * @author{Magnus Mæhlum } */ #include @@ -85,7 +86,7 @@ int lf_sleep(interval_t sleep_duration) { * Initialize the LF clock. */ void _lf_initialize_clock() { - // FlexPRET does not require any initialization + // FlexPRET clock does not require any initialization } int lf_disable_interrupts_nested() { @@ -196,6 +197,7 @@ int lf_thread_id() { } void initialize_lf_thread_id() { - // TODO: Verify: Don't think anything is necessary here for FlexPRET + // Nothing needed here; thread ID's are already available in harware registers + // which can be fetched with `read_hartid`. } #endif From 50af7d4d00474136b72911f86252721423df1e38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Fri, 3 May 2024 15:28:10 +0200 Subject: [PATCH 11/34] Remove unecessary link in platform impl CMakeLists.txt --- platform/impl/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/impl/CMakeLists.txt b/platform/impl/CMakeLists.txt index 096b99e8d..e98c1a8d5 100644 --- a/platform/impl/CMakeLists.txt +++ b/platform/impl/CMakeLists.txt @@ -8,7 +8,6 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") add_library(lf-platform-impl STATIC) target_sources(lf-platform-impl PUBLIC ${LF_PLATFORM_FILES}) - target_link_libraries(lf-platform-impl PUBLIC fp-sdk-if) else() add_library(lf-platform-impl STATIC) target_sources(lf-platform-impl PUBLIC ${LF_PLATFORM_FILES}) From 596a344b3f94d701e2664ecba2de8b544e4f4ed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Fri, 3 May 2024 16:16:39 +0200 Subject: [PATCH 12/34] Propagate low-level-platform interface to platform interface --- low_level_platform/api/platform/lf_flexpret_support.h | 10 +--------- platform/api/CMakeLists.txt | 1 + platform/api/platform.h | 2 ++ 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/low_level_platform/api/platform/lf_flexpret_support.h b/low_level_platform/api/platform/lf_flexpret_support.h index 0971846ae..07f059f10 100644 --- a/low_level_platform/api/platform/lf_flexpret_support.h +++ b/low_level_platform/api/platform/lf_flexpret_support.h @@ -46,15 +46,6 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include - -/** - * printf.h does not include definitions of vfprintf, so to avoid linking - * newlib's vfprintf we replace all occurrances of it with just printf - * - */ -#define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD 0 -#define vfprintf(fp, fmt, args) vprintf(fmt, args) - /** * Like nRF52, for FlexPRET, each mutex will control an interrupt. * @@ -128,5 +119,6 @@ typedef fp_cond_t lf_cond_t; // Likewise, fprintf is used to print to `stderr`, but FlexPRET has no `stderr` // We instead redirect its output to normal printf #define fprintf(stream, fmt, ...) printf(fmt, ##__VA_ARGS__) +#define vfprintf(fp, fmt, args) vprintf(fmt, args) #endif // LF_FLEXPRET_SUPPORT_H diff --git a/platform/api/CMakeLists.txt b/platform/api/CMakeLists.txt index 88b8de512..e81bcdaf1 100644 --- a/platform/api/CMakeLists.txt +++ b/platform/api/CMakeLists.txt @@ -1,3 +1,4 @@ add_library(lf-platform-api INTERFACE) add_library(lf::platform-api ALIAS lf-platform-api) +target_link_libraries(lf-platform-api INTERFACE lf-low-level-platform-api) target_include_directories(lf-platform-api INTERFACE ${CMAKE_CURRENT_LIST_DIR}) diff --git a/platform/api/platform.h b/platform/api/platform.h index 1b1950e8e..3e2f7d43c 100644 --- a/platform/api/platform.h +++ b/platform/api/platform.h @@ -9,6 +9,8 @@ * @copyright Copyright (c) 2024 */ +#include "low_level_platform.h" + /** * @brief Pointer to the platform-specific implementation of a mutex. */ From 0366a731cdbd5bb3cdadbf8d031de4f89b756b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 4 May 2024 14:10:30 +0200 Subject: [PATCH 13/34] Apply formatter --- .../api/platform/lf_flexpret_support.h | 20 +- low_level_platform/impl/src/lf_atomic_irq.c | 5 +- .../impl/src/lf_flexpret_support.c | 171 +++++++++--------- 3 files changed, 92 insertions(+), 104 deletions(-) diff --git a/low_level_platform/api/platform/lf_flexpret_support.h b/low_level_platform/api/platform/lf_flexpret_support.h index 07f059f10..c614905f1 100644 --- a/low_level_platform/api/platform/lf_flexpret_support.h +++ b/low_level_platform/api/platform/lf_flexpret_support.h @@ -28,21 +28,21 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * FlexPRET API support for the C target of Lingua Franca. * * This is based on lf_nrf_support.h in icyphy/lf-buckler. - * + * * @author{Soroush Bateni } * @author{Abhi Gundrala } - * @author{Shaokai Lin } + * @author{Shaokai Lin } */ #ifndef LF_FLEXPRET_SUPPORT_H #define LF_FLEXPRET_SUPPORT_H -#include // For fixed-width integral types -#include // For CLOCK_MONOTONIC +#include // For fixed-width integral types +#include // For CLOCK_MONOTONIC #include -#include // Defines va_list -#include // Defines FILE -#include // Defines strlen +#include // Defines va_list +#include // Defines FILE +#include // Defines strlen #include @@ -51,12 +51,12 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The mutex holds the interrupt number. * For example, a mutex might be defined for the GPIOTE peripheral interrupt number - * + * * When initialized, the interrupt is inserted into a global linked list * for disabling and enabling all interrupts during sleep functions. * - All interrupts are disabled by default after initialization * - Priority levels are restricted between (0-7) - * + * */ // Define PRINTF_TIME and PRINTF_MICROSTEP, which are the printf @@ -74,7 +74,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // for time and microsteps, you can simply define // PRINTF_TIME and PRINTF_MICROSTEP directly in the same file that // defines the types _instant_t, _interval_t, and _microstep_t. -#include // Needed to define PRId64 and PRIu32 +#include // Needed to define PRId64 and PRIu32 #define PRINTF_TIME "%" PRId64 #define PRINTF_MICROSTEP "%" PRIu32 diff --git a/low_level_platform/impl/src/lf_atomic_irq.c b/low_level_platform/impl/src/lf_atomic_irq.c index 9224fa615..2854a6f11 100644 --- a/low_level_platform/impl/src/lf_atomic_irq.c +++ b/low_level_platform/impl/src/lf_atomic_irq.c @@ -1,7 +1,4 @@ -#if defined(PLATFORM_ARDUINO) || \ - defined(PLATFORM_NRF52) || \ - defined(PLATFORM_ZEPHYR) || \ - defined(PLATFORM_RP2040) || \ +#if defined(PLATFORM_ARDUINO) || defined(PLATFORM_NRF52) || defined(PLATFORM_ZEPHYR) || defined(PLATFORM_RP2040) || \ defined(PLATFORM_FLEXPRET) /** * @author Erling Rennemo Jellum diff --git a/low_level_platform/impl/src/lf_flexpret_support.c b/low_level_platform/impl/src/lf_flexpret_support.c index d7f910345..1da2350ba 100644 --- a/low_level_platform/impl/src/lf_flexpret_support.c +++ b/low_level_platform/impl/src/lf_flexpret_support.c @@ -19,7 +19,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***************/ /** Support file for Bare-metal FlexPRET platform. - * + * * @author{Shaokai Lin } * @author{Magnus Mæhlum } */ @@ -30,13 +30,12 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "low_level_platform.h" /** - * Used to keep track of the number of nested critical sections. - * + * Used to keep track of the number of nested critical sections. + * * We should only disable interrupts when this is zero and we enter a critical section * We should only enable interrupts when we exit a critical section and this is zero */ -static int critical_section_num_nested[FP_THREADS] = - THREAD_ARRAY_INITIALIZER(0); +static int critical_section_num_nested[FP_THREADS] = THREAD_ARRAY_INITIALIZER(0); /** * @return 0 for success, or -1 for failure @@ -46,75 +45,77 @@ static volatile uint32_t last_time = 0; static volatile uint64_t epoch = 0; #define EPOCH_DURATION_NS (1ULL << 32) int _lf_clock_gettime(instant_t* t) { - uint32_t now = rdtime(); - if (now < last_time) { - epoch += EPOCH_DURATION_NS; - } - *t = now + epoch; - last_time = now; - return 0; -} - -int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { - int ret = 0; - if (wakeup_time < 0) { - return ret; - } + uint32_t now = rdtime(); + if (now < last_time) { + epoch += EPOCH_DURATION_NS; + } + *t = now + epoch; + last_time = now; + return 0; +} + +int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_time) { + int ret = 0; + if (wakeup_time < 0) { + return ret; + } - // Enable interrupts and execute wait until instruction - lf_critical_section_exit(env); + // Enable interrupts and execute wait until instruction + lf_critical_section_exit(env); - // Wait until will stop sleep if interrupt occurs - fp_wait_until(wakeup_time); + // Wait until will stop sleep if interrupt occurs + fp_wait_until(wakeup_time); - if ((instant_t) rdtime64() < wakeup_time) { - // Interrupt occurred because we did not wait full wakeup_time - ret = -1; - } + if ((instant_t)rdtime64() < wakeup_time) { + // Interrupt occurred because we did not wait full wakeup_time + ret = -1; + } - lf_critical_section_enter(env); - return ret; + lf_critical_section_enter(env); + return ret; } int lf_sleep(interval_t sleep_duration) { - // FIXME: Handle sleep durations exceeding 32bit - fp_delay_for(sleep_duration); - return 0; + // FIXME: Handle sleep durations exceeding 32bit + fp_delay_for(sleep_duration); + return 0; } /** * Initialize the LF clock. */ void _lf_initialize_clock() { - // FlexPRET clock does not require any initialization + // FlexPRET clock does not require any initialization } int lf_disable_interrupts_nested() { - // In the special case where this function is called during an interrupt - // subroutine (isr) it should have no effect - if ((read_csr(CSR_STATUS) & 0x04) == 0x04) return 0; + // In the special case where this function is called during an interrupt + // subroutine (isr) it should have no effect + if ((read_csr(CSR_STATUS) & 0x04) == 0x04) + return 0; - uint32_t hartid = read_hartid(); + uint32_t hartid = read_hartid(); - fp_assert(critical_section_num_nested[hartid] >= 0, "Number of nested critical sections less than zero."); - if (critical_section_num_nested[hartid]++ == 0) { - fp_interrupt_disable(); - } - return 0; + fp_assert(critical_section_num_nested[hartid] >= 0, "Number of nested critical sections less than zero."); + if (critical_section_num_nested[hartid]++ == 0) { + fp_interrupt_disable(); + } + return 0; } int lf_enable_interrupts_nested() { - // In the special case where this function is called during an interrupt - // subroutine (isr) it should have no effect - if ((read_csr(CSR_STATUS) & 0x04) == 0x04) return 0; + // In the special case where this function is called during an interrupt + // subroutine (isr) it should have no effect + if ((read_csr(CSR_STATUS) & 0x04) == 0x04) + return 0; - uint32_t hartid = read_hartid(); + uint32_t hartid = read_hartid(); - if (--critical_section_num_nested[hartid] == 0) { - fp_interrupt_enable(); - } - fp_assert(critical_section_num_nested[hartid] >= 0, "Number of nested critical sections less than zero."); - return 0; + if (--critical_section_num_nested[hartid] == 0) { + fp_interrupt_enable(); + } + fp_assert(critical_section_num_nested[hartid] >= 0, "Number of nested critical sections less than zero."); + return 0; } /** @@ -124,80 +125,70 @@ int lf_enable_interrupts_nested() { * set appropriately (see `man 2 clock_nanosleep`). */ int lf_nanosleep(interval_t requested_time) { - instant_t t; + instant_t t; + _lf_clock_gettime(&t); + instant_t expire_time = t + requested_time; + while (t < expire_time) { _lf_clock_gettime(&t); - instant_t expire_time = t + requested_time; - while (t < expire_time) { - _lf_clock_gettime(&t); - } - return 0; + } + return 0; } #if defined(LF_SINGLE_THREADED) int _lf_single_threaded_notify_of_event() { - // No need to do anything, because an interrupt will cancel wait until - // This is specific to FlexPRET - return 0; + // No need to do anything, because an interrupt will cancel wait until + // This is specific to FlexPRET + return 0; } #else // Multi threaded int lf_available_cores() { - return FP_THREADS-1; // Return the number of Flexpret HW threads + return FP_THREADS - 1; // Return the number of Flexpret HW threads } -int lf_thread_create(lf_thread_t* thread, void *(*lf_thread) (void *), void* arguments) { - // TODO: Decide between HRTT or SRTT - return fp_thread_create(HRTT, thread, lf_thread, arguments); +int lf_thread_create(lf_thread_t* thread, void* (*lf_thread)(void*), void* arguments) { + // TODO: Decide between HRTT or SRTT + return fp_thread_create(HRTT, thread, lf_thread, arguments); } -int lf_thread_join(lf_thread_t thread, void** thread_return) { - return fp_thread_join(thread, thread_return); -} +int lf_thread_join(lf_thread_t thread, void** thread_return) { return fp_thread_join(thread, thread_return); } int lf_mutex_init(lf_mutex_t* mutex) { - *mutex = (lf_mutex_t) FP_LOCK_INITIALIZER; - return 0; + *mutex = (lf_mutex_t)FP_LOCK_INITIALIZER; + return 0; } int lf_mutex_lock(lf_mutex_t* mutex) { - fp_lock_acquire(mutex); - return 0; + fp_lock_acquire(mutex); + return 0; } int lf_mutex_unlock(lf_mutex_t* mutex) { - fp_lock_release(mutex); - return 0; + fp_lock_release(mutex); + return 0; } int lf_cond_init(lf_cond_t* cond, lf_mutex_t* mutex) { - *cond = (lf_cond_t) FP_COND_INITIALIZER(mutex); - return 0; + *cond = (lf_cond_t)FP_COND_INITIALIZER(mutex); + return 0; } -int lf_cond_broadcast(lf_cond_t* cond) { - return fp_cond_broadcast(cond); -} +int lf_cond_broadcast(lf_cond_t* cond) { return fp_cond_broadcast(cond); } -int lf_cond_signal(lf_cond_t* cond) { - return fp_cond_signal(cond); -} +int lf_cond_signal(lf_cond_t* cond) { return fp_cond_signal(cond); } -int lf_cond_wait(lf_cond_t* cond) { - return fp_cond_wait(cond); -} +int lf_cond_wait(lf_cond_t* cond) { return fp_cond_wait(cond); } int _lf_cond_timedwait(lf_cond_t* cond, instant_t absolute_time_ns) { - return fp_cond_timed_wait(cond, absolute_time_ns); + return fp_cond_timed_wait(cond, absolute_time_ns); } -int lf_thread_id() { - return read_hartid(); -} +int lf_thread_id() { return read_hartid(); } void initialize_lf_thread_id() { - // Nothing needed here; thread ID's are already available in harware registers - // which can be fetched with `read_hartid`. + // Nothing needed here; thread ID's are already available in harware registers + // which can be fetched with `read_hartid`. } #endif From 4764f1fd7a4db6fa44fdf3bb26d6f2027209296c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 4 May 2024 15:36:16 +0200 Subject: [PATCH 14/34] Add guard to flexpret_support.c which solves build errors for Ardunio tests. --- low_level_platform/impl/src/lf_flexpret_support.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/low_level_platform/impl/src/lf_flexpret_support.c b/low_level_platform/impl/src/lf_flexpret_support.c index 1da2350ba..ccfcc611c 100644 --- a/low_level_platform/impl/src/lf_flexpret_support.c +++ b/low_level_platform/impl/src/lf_flexpret_support.c @@ -1,3 +1,4 @@ +#if defined(PLATFORM_FLEXPRET) /************* Copyright (c) 2021, The University of California at Berkeley. Redistribution and use in source and binary forms, with or without modification, @@ -192,3 +193,5 @@ void initialize_lf_thread_id() { // which can be fetched with `read_hartid`. } #endif + +#endif // PLATFORM_FLEXPRET From 9c5baecb72cbbfed00c534a8b746f68ff5f7d6b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sun, 5 May 2024 08:10:55 +0200 Subject: [PATCH 15/34] Revert changes to propagating low-level-platform interface --- core/utils/util.c | 1 + platform/api/CMakeLists.txt | 1 - platform/api/platform.h | 2 -- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/core/utils/util.c b/core/utils/util.c index 881b6dc05..27bfef871 100644 --- a/core/utils/util.c +++ b/core/utils/util.c @@ -32,6 +32,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "util.h" +#include "low_level_platform.h" #ifndef STANDALONE_RTI #include "environment.h" diff --git a/platform/api/CMakeLists.txt b/platform/api/CMakeLists.txt index e81bcdaf1..88b8de512 100644 --- a/platform/api/CMakeLists.txt +++ b/platform/api/CMakeLists.txt @@ -1,4 +1,3 @@ add_library(lf-platform-api INTERFACE) add_library(lf::platform-api ALIAS lf-platform-api) -target_link_libraries(lf-platform-api INTERFACE lf-low-level-platform-api) target_include_directories(lf-platform-api INTERFACE ${CMAKE_CURRENT_LIST_DIR}) diff --git a/platform/api/platform.h b/platform/api/platform.h index 3e2f7d43c..1b1950e8e 100644 --- a/platform/api/platform.h +++ b/platform/api/platform.h @@ -9,8 +9,6 @@ * @copyright Copyright (c) 2024 */ -#include "low_level_platform.h" - /** * @brief Pointer to the platform-specific implementation of a mutex. */ From 9fdd18986f7cbb9f2f2860889a3b8c0c35160b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sun, 5 May 2024 14:40:35 +0200 Subject: [PATCH 16/34] Move a single CMake line for more consistency --- low_level_platform/api/CMakeLists.txt | 1 - low_level_platform/impl/CMakeLists.txt | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/low_level_platform/api/CMakeLists.txt b/low_level_platform/api/CMakeLists.txt index 47817b59a..3f3a50936 100644 --- a/low_level_platform/api/CMakeLists.txt +++ b/low_level_platform/api/CMakeLists.txt @@ -10,6 +10,5 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_RP2040) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") - target_link_libraries(lf-low-level-platform-api INTERFACE fp-sdk-if) target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_FLEXPRET) endif() diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index c7c5e1b13..2266b67d1 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -60,6 +60,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") zephyr_library_sources(${LF_LOW_LEVEL_PLATFORM_FILES}) zephyr_library_link_libraries(kernel) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") + target_link_libraries(lf-low-level-platform-api INTERFACE fp-sdk-if) add_library(lf-low-level-platform-impl STATIC ${LF_LOW_LEVEL_PLATFORM_FILES}) if (DEFINED NUMBER_OF_WORKERS) From e5216b61d956eb5a51d2ea61baf432ca26967e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Fri, 10 May 2024 14:15:02 +0200 Subject: [PATCH 17/34] Add explanation of #include platform in util.c --- core/utils/util.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/utils/util.c b/core/utils/util.c index 27bfef871..4c14f406c 100644 --- a/core/utils/util.c +++ b/core/utils/util.c @@ -32,7 +32,15 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "util.h" + +#if defined(PLATFORM_FLEXPRET) +/** + * For FlexPRET specifically, the header file contains macro overrides for + * `fprintf` and `vfprintf`, which reduces code size. Those are not applied + * unless the header file is included. + */ #include "low_level_platform.h" +#endif // defined(PLATFORM_FLEXPRET) #ifndef STANDALONE_RTI #include "environment.h" From 2041aff7ee24ebab1fc756a927087dce51e97252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Fri, 10 May 2024 14:17:46 +0200 Subject: [PATCH 18/34] Fix author in lf_flexpret_support.h --- low_level_platform/api/platform/lf_flexpret_support.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/low_level_platform/api/platform/lf_flexpret_support.h b/low_level_platform/api/platform/lf_flexpret_support.h index c614905f1..27fe35104 100644 --- a/low_level_platform/api/platform/lf_flexpret_support.h +++ b/low_level_platform/api/platform/lf_flexpret_support.h @@ -27,11 +27,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** * FlexPRET API support for the C target of Lingua Franca. * - * This is based on lf_nrf_support.h in icyphy/lf-buckler. - * - * @author{Soroush Bateni } - * @author{Abhi Gundrala } - * @author{Shaokai Lin } + * @author{Magnus Mæhlum } */ #ifndef LF_FLEXPRET_SUPPORT_H From c518fd442dc1fb9fd8e24f30a8e119b894326bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Fri, 10 May 2024 14:19:27 +0200 Subject: [PATCH 19/34] Alphabetical order on targets supported --- low_level_platform/impl/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index 2266b67d1..657254f70 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -45,7 +45,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") ${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_irq.c ) else() - message(FATAL_ERROR "Your platform is not supported! The C target supports Linux, MacOS, Windows, Zephyr, Nrf52, RP2040 and FlexPRET.") + message(FATAL_ERROR "Your platform is not supported! The C target supports FlexPRET, Linux, MacOS, Nrf52, RP2040, Windows, and Zephyr.") endif() list(APPEND LF_LOW_LEVEL_PLATFORM_FILES ${CMAKE_CURRENT_LIST_DIR}/src/lf_platform_util.c) From d388cac7d7d46927d25f455b6c6965b4b914d69c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Fri, 10 May 2024 14:32:29 +0200 Subject: [PATCH 20/34] Add link to issue of decide between HRTT and SRTT in lf_thread_create. --- low_level_platform/impl/src/lf_flexpret_support.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/low_level_platform/impl/src/lf_flexpret_support.c b/low_level_platform/impl/src/lf_flexpret_support.c index ccfcc611c..6a90f6fc1 100644 --- a/low_level_platform/impl/src/lf_flexpret_support.c +++ b/low_level_platform/impl/src/lf_flexpret_support.c @@ -150,7 +150,10 @@ int lf_available_cores() { } int lf_thread_create(lf_thread_t* thread, void* (*lf_thread)(void*), void* arguments) { - // TODO: Decide between HRTT or SRTT + /** + * Need to select between HRTT or SRTT; see + * https://github.com/lf-lang/reactor-c/issues/421 + */ return fp_thread_create(HRTT, thread, lf_thread, arguments); } From 7aecb2aa24619ec3f23c5a485f9dd80c14da8302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 11 May 2024 13:36:42 +0200 Subject: [PATCH 21/34] Fix 64-bit sleep and fix issues addressed in PR --- .../api/platform/lf_flexpret_support.h | 34 ------- .../impl/src/lf_flexpret_support.c | 94 ++++++++++++------- 2 files changed, 60 insertions(+), 68 deletions(-) diff --git a/low_level_platform/api/platform/lf_flexpret_support.h b/low_level_platform/api/platform/lf_flexpret_support.h index 27fe35104..44835687b 100644 --- a/low_level_platform/api/platform/lf_flexpret_support.h +++ b/low_level_platform/api/platform/lf_flexpret_support.h @@ -55,21 +55,6 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -// Define PRINTF_TIME and PRINTF_MICROSTEP, which are the printf -// codes (like the d in %d to print an int) for time and microsteps. -// To use these, specify the printf as follows: -// printf("%" PRINTF_TIME "\n", time_value); -// On most platforms, time is an signed 64-bit number (int64_t) and -// the microstep is an unsigned 32-bit number (uint32_t). -// Sadly, in C, there is no portable to print such numbers using -// printf without getting a warning on some platforms. -// On each platform, the code for printf if given by the macros -// PRId64 and PRIu32 defined in inttypes.h. Hence, here, we import -// inttypes.h, then define PRINTF_TIME and PRINTF_MICROSTEP. -// If you are targeting a platform that uses some other type -// for time and microsteps, you can simply define -// PRINTF_TIME and PRINTF_MICROSTEP directly in the same file that -// defines the types _instant_t, _interval_t, and _microstep_t. #include // Needed to define PRId64 and PRIu32 #define PRINTF_TIME "%" PRId64 #define PRINTF_MICROSTEP "%" PRIu32 @@ -79,26 +64,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // printf("Tag is " PRINTF_TAG "\n", time_value, microstep); #define PRINTF_TAG "(%" PRId64 ", %" PRIu32 ")" -/** - * Time instant. Both physical and logical times are represented - * using this typedef. - * WARNING: If this code is used after about the year 2262, - * then representing time as a 64-bit long long will be insufficient. - */ -typedef int64_t _instant_t; - -/** - * Interval of time. - */ -typedef int64_t _interval_t; - -/** - * Microstep instant. - */ -typedef uint32_t _microstep_t; - #include -#define _LF_TIMEOUT ETIMEDOUT // The underlying physical clock for Linux #define _LF_CLOCK CLOCK_MONOTONIC diff --git a/low_level_platform/impl/src/lf_flexpret_support.c b/low_level_platform/impl/src/lf_flexpret_support.c index 6a90f6fc1..78fd4580b 100644 --- a/low_level_platform/impl/src/lf_flexpret_support.c +++ b/low_level_platform/impl/src/lf_flexpret_support.c @@ -38,48 +38,81 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ static int critical_section_num_nested[FP_THREADS] = THREAD_ARRAY_INITIALIZER(0); -/** - * @return 0 for success, or -1 for failure - */ +static volatile bool _lf_async_event_occurred = false; -static volatile uint32_t last_time = 0; -static volatile uint64_t epoch = 0; #define EPOCH_DURATION_NS (1ULL << 32) + int _lf_clock_gettime(instant_t* t) { - uint32_t now = rdtime(); - if (now < last_time) { - epoch += EPOCH_DURATION_NS; - } - *t = now + epoch; - last_time = now; + *t = (instant_t) rdtime64(); return 0; } -int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_time) { - int ret = 0; - if (wakeup_time < 0) { - return ret; +int _lf_sleep_common(instant_t wakeup_time, bool interruptable) { + // Store the number of epochs; i.e., how many times the 32-bit timer + // will overflow + uint32_t wakeup_time_epochs = 0; + uint32_t wakeup_time_after_epochs = 0; + uint32_t sleep_start = rdtime(); + + if (wakeup_time > (instant_t) EPOCH_DURATION_NS) { + wakeup_time_epochs = wakeup_time / EPOCH_DURATION_NS; + wakeup_time_after_epochs = wakeup_time % EPOCH_DURATION_NS; + + if (wakeup_time < sleep_start) { + // This means we need to do another epoch + wakeup_time_epochs++; + } + } else { + wakeup_time_epochs = 0; + wakeup_time_after_epochs = wakeup_time; + if (wakeup_time < sleep_start) { + // Nothing to do; should not happen + //LF_PRINT_DEBUG("FlexPRET: _lf_sleep_common called with wakeup_time < current time\n"); + return 0; + } + } + + const uint32_t max_uint32_value = 0xFFFFFFFF; + _lf_async_event_occurred = false; + + for (uint32_t i = 0; i < wakeup_time_epochs; i++) { + // The first sleep until will only be partial + if (interruptable) { + // Can be interrupted + fp_wait_until(max_uint32_value); + if (_lf_async_event_occurred) break; + } else { + // Cannot be interrupted + fp_delay_until(max_uint32_value); + } + } + + if (interruptable) { + if (!_lf_async_event_occurred) { + fp_wait_until(wakeup_time_after_epochs); + } + } else { + // Cannot be interrupted + fp_delay_until(wakeup_time_after_epochs); } + return _lf_async_event_occurred; +} + +int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_time) { // Enable interrupts and execute wait until instruction lf_critical_section_exit(env); // Wait until will stop sleep if interrupt occurs - fp_wait_until(wakeup_time); - - if ((instant_t)rdtime64() < wakeup_time) { - // Interrupt occurred because we did not wait full wakeup_time - ret = -1; - } + int ret = _lf_sleep_common(wakeup_time, true); lf_critical_section_enter(env); return ret; } int lf_sleep(interval_t sleep_duration) { - // FIXME: Handle sleep durations exceeding 32bit - fp_delay_for(sleep_duration); - return 0; + interval_t sleep_until = rdtime64() + sleep_duration; + return _lf_sleep_common(sleep_until, false); } /** @@ -126,20 +159,13 @@ int lf_enable_interrupts_nested() { * set appropriately (see `man 2 clock_nanosleep`). */ int lf_nanosleep(interval_t requested_time) { - instant_t t; - _lf_clock_gettime(&t); - instant_t expire_time = t + requested_time; - while (t < expire_time) { - _lf_clock_gettime(&t); - } - return 0; + return lf_sleep(requested_time); } #if defined(LF_SINGLE_THREADED) int _lf_single_threaded_notify_of_event() { - // No need to do anything, because an interrupt will cancel wait until - // This is specific to FlexPRET + _lf_async_event_occurred = true; return 0; } @@ -186,7 +212,7 @@ int lf_cond_signal(lf_cond_t* cond) { return fp_cond_signal(cond); } int lf_cond_wait(lf_cond_t* cond) { return fp_cond_wait(cond); } int _lf_cond_timedwait(lf_cond_t* cond, instant_t absolute_time_ns) { - return fp_cond_timed_wait(cond, absolute_time_ns); + return (fp_cond_timed_wait(cond, absolute_time_ns) == FP_TIMEOUT) ? LF_TIMEOUT : 0; } int lf_thread_id() { return read_hartid(); } From 91102507ead45e8cb288628e50ffc4cc0342e854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 11 May 2024 13:40:32 +0200 Subject: [PATCH 22/34] Remove more redundant code --- low_level_platform/api/platform/lf_flexpret_support.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/low_level_platform/api/platform/lf_flexpret_support.h b/low_level_platform/api/platform/lf_flexpret_support.h index 44835687b..9e426d86d 100644 --- a/low_level_platform/api/platform/lf_flexpret_support.h +++ b/low_level_platform/api/platform/lf_flexpret_support.h @@ -64,11 +64,6 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // printf("Tag is " PRINTF_TAG "\n", time_value, microstep); #define PRINTF_TAG "(%" PRId64 ", %" PRIu32 ")" -#include - -// The underlying physical clock for Linux -#define _LF_CLOCK CLOCK_MONOTONIC - #if !defined(LF_SINGLE_THREADED) typedef fp_lock_t lf_mutex_t; typedef fp_thread_t lf_thread_t; From 64f9339017c026c0bdbf0b9b66433d75a1953557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 11 May 2024 13:40:46 +0200 Subject: [PATCH 23/34] Add workflow --- .github/workflows/ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 39267f34f..b43725b47 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,6 +55,14 @@ jobs: compiler-ref: ${{ needs.fetch-lf.outputs.ref }} if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'zephyr') }} + lf-default-flexpret: + needs: [fetch-lf] + uses: lf-lang/lingua-franca/.github/workflows/c-flexpret-tests.yml@master + with: + runtime-ref: ${{ github.ref }} + compiler-ref: ${{ needs.fetch-lf.outputs.ref }} + if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'flexpret') }} + lf-default: needs: [fetch-lf] uses: lf-lang/lingua-franca/.github/workflows/c-tests.yml@master From 81aa4629066465e41125e69c9100632dde30da32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 11 May 2024 13:42:53 +0200 Subject: [PATCH 24/34] Formatting --- low_level_platform/impl/src/lf_flexpret_support.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/low_level_platform/impl/src/lf_flexpret_support.c b/low_level_platform/impl/src/lf_flexpret_support.c index 78fd4580b..1003ab4ec 100644 --- a/low_level_platform/impl/src/lf_flexpret_support.c +++ b/low_level_platform/impl/src/lf_flexpret_support.c @@ -43,7 +43,7 @@ static volatile bool _lf_async_event_occurred = false; #define EPOCH_DURATION_NS (1ULL << 32) int _lf_clock_gettime(instant_t* t) { - *t = (instant_t) rdtime64(); + *t = (instant_t)rdtime64(); return 0; } @@ -54,10 +54,10 @@ int _lf_sleep_common(instant_t wakeup_time, bool interruptable) { uint32_t wakeup_time_after_epochs = 0; uint32_t sleep_start = rdtime(); - if (wakeup_time > (instant_t) EPOCH_DURATION_NS) { + if (wakeup_time > (instant_t)EPOCH_DURATION_NS) { wakeup_time_epochs = wakeup_time / EPOCH_DURATION_NS; wakeup_time_after_epochs = wakeup_time % EPOCH_DURATION_NS; - + if (wakeup_time < sleep_start) { // This means we need to do another epoch wakeup_time_epochs++; @@ -67,7 +67,7 @@ int _lf_sleep_common(instant_t wakeup_time, bool interruptable) { wakeup_time_after_epochs = wakeup_time; if (wakeup_time < sleep_start) { // Nothing to do; should not happen - //LF_PRINT_DEBUG("FlexPRET: _lf_sleep_common called with wakeup_time < current time\n"); + // LF_PRINT_DEBUG("FlexPRET: _lf_sleep_common called with wakeup_time < current time\n"); return 0; } } @@ -80,7 +80,8 @@ int _lf_sleep_common(instant_t wakeup_time, bool interruptable) { if (interruptable) { // Can be interrupted fp_wait_until(max_uint32_value); - if (_lf_async_event_occurred) break; + if (_lf_async_event_occurred) + break; } else { // Cannot be interrupted fp_delay_until(max_uint32_value); @@ -158,9 +159,7 @@ int lf_enable_interrupts_nested() { * @return 0 for success, or -1 for failure. In case of failure, errno will be * set appropriately (see `man 2 clock_nanosleep`). */ -int lf_nanosleep(interval_t requested_time) { - return lf_sleep(requested_time); -} +int lf_nanosleep(interval_t requested_time) { return lf_sleep(requested_time); } #if defined(LF_SINGLE_THREADED) From 414cbba0e4e3cfdd8ecf61d47e008cc0c7408f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Tue, 14 May 2024 15:59:16 +0200 Subject: [PATCH 25/34] Fix issues that came from cmake changes in fp SDK --- core/utils/util.c | 19 ++++++++++++------- include/core/tracepoint.h | 2 ++ low_level_platform/api/CMakeLists.txt | 1 + .../api/platform/lf_flexpret_support.h | 7 ------- low_level_platform/impl/CMakeLists.txt | 2 +- platform/impl/CMakeLists.txt | 1 + 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/core/utils/util.c b/core/utils/util.c index 4c14f406c..e131b1810 100644 --- a/core/utils/util.c +++ b/core/utils/util.c @@ -33,21 +33,26 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "util.h" -#if defined(PLATFORM_FLEXPRET) +#if !defined(PLATFORM_FLEXPRET) +#include +#else /** - * For FlexPRET specifically, the header file contains macro overrides for - * `fprintf` and `vfprintf`, which reduces code size. Those are not applied - * unless the header file is included. + * For FlexPRET specifically, a small footprint version of printf is used */ -#include "low_level_platform.h" -#endif // defined(PLATFORM_FLEXPRET) +#include +/** + * Also, fflush and stdout are not provided so we just implement stubs + * + */ +#define stdout (void *)(1) +int fflush(void *stream) { (void) stream; return 0; } +#endif // PLATFORM_FLEXPRET #ifndef STANDALONE_RTI #include "environment.h" #endif #include -#include #include #include #include // Defines memcpy() diff --git a/include/core/tracepoint.h b/include/core/tracepoint.h index c43763a07..db8b26f57 100644 --- a/include/core/tracepoint.h +++ b/include/core/tracepoint.h @@ -31,7 +31,9 @@ #define TRACEPOINT_H #include "lf_types.h" +#if !defined(PLATFORM_FLEXPRET) #include +#endif #ifdef FEDERATED #include "net_common.h" diff --git a/low_level_platform/api/CMakeLists.txt b/low_level_platform/api/CMakeLists.txt index 3f3a50936..6993dfa52 100644 --- a/low_level_platform/api/CMakeLists.txt +++ b/low_level_platform/api/CMakeLists.txt @@ -11,4 +11,5 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_RP2040) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_FLEXPRET) + target_link_libraries(lf-low-level-platform-api INTERFACE fp-sdk) endif() diff --git a/low_level_platform/api/platform/lf_flexpret_support.h b/low_level_platform/api/platform/lf_flexpret_support.h index 9e426d86d..17992a8bb 100644 --- a/low_level_platform/api/platform/lf_flexpret_support.h +++ b/low_level_platform/api/platform/lf_flexpret_support.h @@ -33,13 +33,6 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef LF_FLEXPRET_SUPPORT_H #define LF_FLEXPRET_SUPPORT_H -#include // For fixed-width integral types -#include // For CLOCK_MONOTONIC -#include -#include // Defines va_list -#include // Defines FILE -#include // Defines strlen - #include /** diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index 657254f70..8773f1e99 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -60,8 +60,8 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") zephyr_library_sources(${LF_LOW_LEVEL_PLATFORM_FILES}) zephyr_library_link_libraries(kernel) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") - target_link_libraries(lf-low-level-platform-api INTERFACE fp-sdk-if) add_library(lf-low-level-platform-impl STATIC ${LF_LOW_LEVEL_PLATFORM_FILES}) + target_link_libraries(lf-low-level-platform-impl PRIVATE fp-sdk) if (DEFINED NUMBER_OF_WORKERS) # Verify that FlexPRET has the number of requested workers diff --git a/platform/impl/CMakeLists.txt b/platform/impl/CMakeLists.txt index e98c1a8d5..bc12ff11c 100644 --- a/platform/impl/CMakeLists.txt +++ b/platform/impl/CMakeLists.txt @@ -8,6 +8,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") add_library(lf-platform-impl STATIC) target_sources(lf-platform-impl PUBLIC ${LF_PLATFORM_FILES}) + target_link_libraries(lf-platform-impl PRIVATE fp-sdk) else() add_library(lf-platform-impl STATIC) target_sources(lf-platform-impl PUBLIC ${LF_PLATFORM_FILES}) From bb0a90bb47e845f40aaa7066d6c32839f9928db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 18 May 2024 11:51:38 +0200 Subject: [PATCH 26/34] Format fix --- core/utils/util.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/utils/util.c b/core/utils/util.c index e131b1810..a20899fb0 100644 --- a/core/utils/util.c +++ b/core/utils/util.c @@ -42,10 +42,13 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include /** * Also, fflush and stdout are not provided so we just implement stubs - * + * */ -#define stdout (void *)(1) -int fflush(void *stream) { (void) stream; return 0; } +#define stdout (void*)(1) +int fflush(void* stream) { + (void)stream; + return 0; +} #endif // PLATFORM_FLEXPRET #ifndef STANDALONE_RTI From 9a28f5eb6ca4aa20ff89dad86e6831d3e5e6b505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 18 May 2024 16:50:03 +0200 Subject: [PATCH 27/34] Rename NO_TTY -> NO_CLI and fix comments related to this. --- core/reactor.c | 8 ++++---- core/reactor_common.c | 4 ++-- core/threaded/reactor_threaded.c | 4 ++-- core/utils/util.c | 9 ++++++--- low_level_platform/api/platform/lf_arduino_support.h | 4 ++-- low_level_platform/api/platform/lf_flexpret_support.h | 6 ++++-- low_level_platform/api/platform/lf_nrf52_support.h | 5 +++-- low_level_platform/api/platform/lf_rp2040_support.h | 3 ++- low_level_platform/api/platform/lf_zephyr_support.h | 3 ++- 9 files changed, 27 insertions(+), 19 deletions(-) diff --git a/core/reactor.c b/core/reactor.c index 00df9e07f..a3bc64260 100644 --- a/core/reactor.c +++ b/core/reactor.c @@ -18,8 +18,8 @@ #include "reactor_common.h" #include "environment.h" -// Embedded platforms with no TTY shouldnt have signals -#if !defined(NO_TTY) +// Embedded platforms with no command line interface shouldnt have signals +#if !defined(NO_CLI) #include // To trap ctrl-c and invoke termination(). #endif @@ -319,8 +319,8 @@ int lf_reactor_c_main(int argc, const char* argv[]) { // The above handles only "normal" termination (via a call to exit). // As a consequence, we need to also trap Ctrl-C, which issues a SIGINT, // and cause it to call exit. - // Embedded platforms with NO_TTY have no concept of a signal; for those, we exclude this call. -#ifndef NO_TTY + // Embedded platforms with NO_CLI have no concept of a signal; for those, we exclude this call. +#ifndef NO_CLI signal(SIGINT, exit); #endif // Create and initialize the environment diff --git a/core/reactor_common.c b/core/reactor_common.c index b3f1d7b4d..6863e7bc2 100644 --- a/core/reactor_common.c +++ b/core/reactor_common.c @@ -852,7 +852,7 @@ void schedule_output_reactions(environment_t* env, reaction_t* reaction, int wor /** * Print a usage message. - * TODO: This is not necessary for NO_TTY + * TODO: This is not necessary for NO_CLI */ void usage(int argc, const char* argv[]) { printf("\nCommand-line arguments: \n\n"); @@ -890,7 +890,7 @@ const char** default_argv = NULL; * Process the command-line arguments. If the command line arguments are not * understood, then print a usage message and return 0. Otherwise, return 1. * @return 1 if the arguments processed successfully, 0 otherwise. - * TODO: Not necessary for NO_TTY + * TODO: Not necessary for NO_CLI */ int process_args(int argc, const char* argv[]) { int i = 1; diff --git a/core/threaded/reactor_threaded.c b/core/threaded/reactor_threaded.c index 1d7598723..d4fe5c498 100644 --- a/core/threaded/reactor_threaded.c +++ b/core/threaded/reactor_threaded.c @@ -1073,12 +1073,12 @@ int lf_reactor_c_main(int argc, const char* argv[]) { LF_PRINT_DEBUG("Start time: " PRINTF_TIME "ns", start_time); struct timespec physical_time_timespec = {start_time / BILLION, start_time % BILLION}; -#ifdef NO_TTY +#ifdef MINIMAL_STDLIB lf_print("---- Start execution ----"); #else lf_print("---- Start execution at time %s---- plus %ld nanoseconds", ctime(&physical_time_timespec.tv_sec), physical_time_timespec.tv_nsec); -#endif // NO_TTY +#endif // MINIMAL_STDLIB // Create and initialize the environments for each enclave lf_create_environments(); diff --git a/core/utils/util.c b/core/utils/util.c index e131b1810..a20899fb0 100644 --- a/core/utils/util.c +++ b/core/utils/util.c @@ -42,10 +42,13 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include /** * Also, fflush and stdout are not provided so we just implement stubs - * + * */ -#define stdout (void *)(1) -int fflush(void *stream) { (void) stream; return 0; } +#define stdout (void*)(1) +int fflush(void* stream) { + (void)stream; + return 0; +} #endif // PLATFORM_FLEXPRET #ifndef STANDALONE_RTI diff --git a/low_level_platform/api/platform/lf_arduino_support.h b/low_level_platform/api/platform/lf_arduino_support.h index 94c5d4933..aa76af8e3 100644 --- a/low_level_platform/api/platform/lf_arduino_support.h +++ b/low_level_platform/api/platform/lf_arduino_support.h @@ -129,7 +129,7 @@ typedef void* lf_thread_t; #define LLONG_MIN (-LLONG_MAX - 1LL) #define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) -// Arduinos are embedded platforms with no tty -#define NO_TTY +// Arduinos are embedded platforms with no command line interface +#define NO_CLI #endif // LF_ARDUINO_SUPPORT_H diff --git a/low_level_platform/api/platform/lf_flexpret_support.h b/low_level_platform/api/platform/lf_flexpret_support.h index 17992a8bb..2031bb0ac 100644 --- a/low_level_platform/api/platform/lf_flexpret_support.h +++ b/low_level_platform/api/platform/lf_flexpret_support.h @@ -63,8 +63,10 @@ typedef fp_thread_t lf_thread_t; typedef fp_cond_t lf_cond_t; #endif -// FlexPRET has no tty -#define NO_TTY +// This will filter out some unecessary calls to standard library functions +// and save code space +#define NO_CLI +#define MINIMAL_STDLIB // Likewise, fprintf is used to print to `stderr`, but FlexPRET has no `stderr` // We instead redirect its output to normal printf diff --git a/low_level_platform/api/platform/lf_nrf52_support.h b/low_level_platform/api/platform/lf_nrf52_support.h index 18613b2e0..8f9b46620 100644 --- a/low_level_platform/api/platform/lf_nrf52_support.h +++ b/low_level_platform/api/platform/lf_nrf52_support.h @@ -34,8 +34,9 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef LF_NRF52_SUPPORT_H #define LF_NRF52_SUPPORT_H -// This embedded platform has no TTY suport -#define NO_TTY +// This embedded platform has no command line interface +#define NO_CLI +#define MINIMAL_STDLIB #include // For fixed-width integral types #include diff --git a/low_level_platform/api/platform/lf_rp2040_support.h b/low_level_platform/api/platform/lf_rp2040_support.h index 1b23e3a2e..670f7afb4 100644 --- a/low_level_platform/api/platform/lf_rp2040_support.h +++ b/low_level_platform/api/platform/lf_rp2040_support.h @@ -10,7 +10,8 @@ #include #include -#define NO_TTY +#define NO_CLI +#define MINIMAL_STDLIB // Defines for formatting time in printf for pico #define PRINTF_TAG "(" PRINTF_TIME ", " PRINTF_MICROSTEP ")" diff --git a/low_level_platform/api/platform/lf_zephyr_support.h b/low_level_platform/api/platform/lf_zephyr_support.h index 0f7ab6b4d..724bbe4e5 100644 --- a/low_level_platform/api/platform/lf_zephyr_support.h +++ b/low_level_platform/api/platform/lf_zephyr_support.h @@ -39,7 +39,8 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#define NO_TTY +#define NO_CLI +#define MINIMAL_STDLIB #if !defined(LF_SINGLE_THREADED) typedef struct k_mutex lf_mutex_t; From 9962705e4ef17773a66419c2459a8702673cc7f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 18 May 2024 17:49:11 +0200 Subject: [PATCH 28/34] Fix issue with vfprintf getting wrong declaration for FlexPRET. --- core/utils/util.c | 16 -------------- include/core/tracepoint.h | 2 -- .../api/platform/lf_flexpret_support.h | 22 +++++++++++++++++++ 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/core/utils/util.c b/core/utils/util.c index a20899fb0..62de9fd27 100644 --- a/core/utils/util.c +++ b/core/utils/util.c @@ -33,23 +33,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "util.h" -#if !defined(PLATFORM_FLEXPRET) #include -#else -/** - * For FlexPRET specifically, a small footprint version of printf is used - */ -#include -/** - * Also, fflush and stdout are not provided so we just implement stubs - * - */ -#define stdout (void*)(1) -int fflush(void* stream) { - (void)stream; - return 0; -} -#endif // PLATFORM_FLEXPRET #ifndef STANDALONE_RTI #include "environment.h" diff --git a/include/core/tracepoint.h b/include/core/tracepoint.h index 3d356bae5..cfa1fb956 100644 --- a/include/core/tracepoint.h +++ b/include/core/tracepoint.h @@ -31,9 +31,7 @@ #define TRACEPOINT_H #include "lf_types.h" -#if !defined(PLATFORM_FLEXPRET) #include -#endif #ifdef FEDERATED #include "net_common.h" diff --git a/low_level_platform/api/platform/lf_flexpret_support.h b/low_level_platform/api/platform/lf_flexpret_support.h index 2031bb0ac..8a6296ee7 100644 --- a/low_level_platform/api/platform/lf_flexpret_support.h +++ b/low_level_platform/api/platform/lf_flexpret_support.h @@ -68,8 +68,30 @@ typedef fp_cond_t lf_cond_t; #define NO_CLI #define MINIMAL_STDLIB +/** + * Need to include `stdio` here, because we #define `fprintf` and `vfprintf` below. + * Since stdio.h contains declarations for these functions, including it + * after will result in the following: + * + * #define fprintf(s, f, ...) printf(f, ##__VA_ARGS__) + * + * int fprintf (FILE *__restrict, const char *__restrict, ...) + * _ATTRIBUTE ((__format__ (__printf__, 2, 3))); + * + * Which the preprocessor will replace with: + * + * int printf (FILE *__restrict, const char *__restrict, ...) + * _ATTRIBUTE ((__format__ (__printf__, 2, 3))); + * + * Which will yield an error. + * + */ +#include + // Likewise, fprintf is used to print to `stderr`, but FlexPRET has no `stderr` // We instead redirect its output to normal printf +// Note: Most compilers do not support passing this on the command line, so CMake +// will drop it if you try... But that would be the better option. #define fprintf(stream, fmt, ...) printf(fmt, ##__VA_ARGS__) #define vfprintf(fp, fmt, args) vprintf(fmt, args) From 3015a0de0519c296427cad6cc039d53c50726b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 18 May 2024 17:57:08 +0200 Subject: [PATCH 29/34] Uncomment reference to FlexPRET workflow file that does not exist in main repo yet. --- .github/workflows/ci.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b43725b47..a36beae7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,13 +55,15 @@ jobs: compiler-ref: ${{ needs.fetch-lf.outputs.ref }} if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'zephyr') }} - lf-default-flexpret: - needs: [fetch-lf] - uses: lf-lang/lingua-franca/.github/workflows/c-flexpret-tests.yml@master - with: - runtime-ref: ${{ github.ref }} - compiler-ref: ${{ needs.fetch-lf.outputs.ref }} - if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'flexpret') }} + # TODO: Comment in when FlexPRET tests are added to main LF repo: + # https://github.com/lf-lang/lingua-franca/pull/2262 + #lf-default-flexpret: + # needs: [fetch-lf] + # uses: lf-lang/lingua-franca/.github/workflows/c-flexpret-tests.yml@master + # with: + # runtime-ref: ${{ github.ref }} + # compiler-ref: ${{ needs.fetch-lf.outputs.ref }} + # if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'flexpret') }} lf-default: needs: [fetch-lf] From 3bd912178b472488c84b05e770f5c0963e6c09ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 18 May 2024 19:58:40 +0200 Subject: [PATCH 30/34] Try to run FlexPRET tests in CI --- .github/workflows/ci.yml | 14 +++++++------- lingua-franca-ref.txt | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a36beae7b..92ffaa209 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,13 +57,13 @@ jobs: # TODO: Comment in when FlexPRET tests are added to main LF repo: # https://github.com/lf-lang/lingua-franca/pull/2262 - #lf-default-flexpret: - # needs: [fetch-lf] - # uses: lf-lang/lingua-franca/.github/workflows/c-flexpret-tests.yml@master - # with: - # runtime-ref: ${{ github.ref }} - # compiler-ref: ${{ needs.fetch-lf.outputs.ref }} - # if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'flexpret') }} + lf-default-flexpret: + needs: [fetch-lf] + uses: lf-lang/lingua-franca/.github/workflows/c-flexpret-tests.yml@add-flexpret-support + with: + runtime-ref: ${{ github.ref }} + compiler-ref: ${{ needs.fetch-lf.outputs.ref }} + if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'flexpret') }} lf-default: needs: [fetch-lf] diff --git a/lingua-franca-ref.txt b/lingua-franca-ref.txt index 1f7391f92..1f07782fc 100644 --- a/lingua-franca-ref.txt +++ b/lingua-franca-ref.txt @@ -1 +1 @@ -master +add-flexpret-support From 35ffd7b996bac4ec8c33803ba6eae1223caa2dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 18 May 2024 20:02:17 +0200 Subject: [PATCH 31/34] Fix url to point at fork --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92ffaa209..7a79671ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: # https://github.com/lf-lang/lingua-franca/pull/2262 lf-default-flexpret: needs: [fetch-lf] - uses: lf-lang/lingua-franca/.github/workflows/c-flexpret-tests.yml@add-flexpret-support + uses: magnmaeh/lingua-franca/.github/workflows/c-flexpret-tests.yml@add-flexpret-support with: runtime-ref: ${{ github.ref }} compiler-ref: ${{ needs.fetch-lf.outputs.ref }} From b230677a09d20585b070f7d9ebb0ac6ee3f8658e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 18 May 2024 20:03:56 +0200 Subject: [PATCH 32/34] Revert ref to master --- lingua-franca-ref.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lingua-franca-ref.txt b/lingua-franca-ref.txt index 1f07782fc..1f7391f92 100644 --- a/lingua-franca-ref.txt +++ b/lingua-franca-ref.txt @@ -1 +1 @@ -add-flexpret-support +master From 869d7865e50549aa312178d3cd0f0991b3f5b839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20M=C3=A6hlum?= Date: Sat, 18 May 2024 20:16:06 +0200 Subject: [PATCH 33/34] Revert changes to CI and add warning about FlexPRET issue in lf_flexpret_support.c --- .github/workflows/ci.yml | 14 +++++++------- low_level_platform/impl/src/lf_flexpret_support.c | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a79671ad..a36beae7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,13 +57,13 @@ jobs: # TODO: Comment in when FlexPRET tests are added to main LF repo: # https://github.com/lf-lang/lingua-franca/pull/2262 - lf-default-flexpret: - needs: [fetch-lf] - uses: magnmaeh/lingua-franca/.github/workflows/c-flexpret-tests.yml@add-flexpret-support - with: - runtime-ref: ${{ github.ref }} - compiler-ref: ${{ needs.fetch-lf.outputs.ref }} - if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'flexpret') }} + #lf-default-flexpret: + # needs: [fetch-lf] + # uses: lf-lang/lingua-franca/.github/workflows/c-flexpret-tests.yml@master + # with: + # runtime-ref: ${{ github.ref }} + # compiler-ref: ${{ needs.fetch-lf.outputs.ref }} + # if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'flexpret') }} lf-default: needs: [fetch-lf] diff --git a/low_level_platform/impl/src/lf_flexpret_support.c b/low_level_platform/impl/src/lf_flexpret_support.c index 1003ab4ec..9d83283c5 100644 --- a/low_level_platform/impl/src/lf_flexpret_support.c +++ b/low_level_platform/impl/src/lf_flexpret_support.c @@ -79,11 +79,15 @@ int _lf_sleep_common(instant_t wakeup_time, bool interruptable) { // The first sleep until will only be partial if (interruptable) { // Can be interrupted + // NOTE: Does not work until this issue is resolved: + // https://github.com/pretis/flexpret/issues/93 fp_wait_until(max_uint32_value); if (_lf_async_event_occurred) break; } else { // Cannot be interrupted + // NOTE: Does not work until this issue is resolved: + // https://github.com/pretis/flexpret/issues/93 fp_delay_until(max_uint32_value); } } From 5b3a0933ae8687169c9ce9fab41ce51619692636 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Wed, 22 May 2024 09:38:47 +0200 Subject: [PATCH 34/34] Add back flexpret CI --- .github/workflows/ci.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a36beae7b..4ba3c90c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,15 +55,13 @@ jobs: compiler-ref: ${{ needs.fetch-lf.outputs.ref }} if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'zephyr') }} - # TODO: Comment in when FlexPRET tests are added to main LF repo: - # https://github.com/lf-lang/lingua-franca/pull/2262 - #lf-default-flexpret: - # needs: [fetch-lf] - # uses: lf-lang/lingua-franca/.github/workflows/c-flexpret-tests.yml@master - # with: - # runtime-ref: ${{ github.ref }} - # compiler-ref: ${{ needs.fetch-lf.outputs.ref }} - # if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'flexpret') }} + lf-default-flexpret: + needs: [fetch-lf] + uses: lf-lang/lingua-franca/.github/workflows/c-flexpret-tests.yml@master + with: + runtime-ref: ${{ github.ref }} + compiler-ref: ${{ needs.fetch-lf.outputs.ref }} + if: ${{ !github.event.pull_request.draft ||contains( github.event.pull_request.labels.*.name, 'flexpret') }} lf-default: needs: [fetch-lf]