diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 39267f34f..4ba3c90c3 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 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 3f337ea6a..26a489bec 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 57f888fc2..d4fe5c498 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 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 // 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 881b6dc05..62de9fd27 100644 --- a/core/utils/util.c +++ b/core/utils/util.c @@ -33,12 +33,13 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "util.h" +#include + #ifndef STANDALONE_RTI #include "environment.h" #endif #include -#include #include #include #include // Defines memcpy() diff --git a/low_level_platform/api/CMakeLists.txt b/low_level_platform/api/CMakeLists.txt index b4598ed9c..6993dfa52 100644 --- a/low_level_platform/api/CMakeLists.txt +++ b/low_level_platform/api/CMakeLists.txt @@ -9,4 +9,7 @@ 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) + target_link_libraries(lf-low-level-platform-api INTERFACE fp-sdk) endif() diff --git a/low_level_platform/api/low_level_platform.h b/low_level_platform/api/low_level_platform.h index 8494a4d85..63b2d1c77 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_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 new file mode 100644 index 000000000..8a6296ee7 --- /dev/null +++ b/low_level_platform/api/platform/lf_flexpret_support.h @@ -0,0 +1,98 @@ +/* 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. + * + * @author{Magnus Mæhlum } + */ + +#ifndef LF_FLEXPRET_SUPPORT_H +#define LF_FLEXPRET_SUPPORT_H + +#include + +/** + * 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) + * + */ + +#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 ")" + +#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 + +// This will filter out some unecessary calls to standard library functions +// and save code space +#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) + +#endif // LF_FLEXPRET_SUPPORT_H 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; diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index 5f6244664..8773f1e99 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -39,8 +39,13 @@ 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.") + 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) @@ -54,6 +59,32 @@ 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 (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 ${FLEXPRET_AVAILABLE_WORKERS}) + message(FATAL_ERROR + "Number of requested workers (${NUMBER_OF_WORKERS}) is higher \ + than FlexPRET's number of available workers \ + (${FLEXPRET_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 diff --git a/low_level_platform/impl/src/lf_atomic_irq.c b/low_level_platform/impl/src/lf_atomic_irq.c index 7be9aff34..2854a6f11 100644 --- a/low_level_platform/impl/src/lf_atomic_irq.c +++ b/low_level_platform/impl/src/lf_atomic_irq.c @@ -1,4 +1,5 @@ -#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..9d83283c5 --- /dev/null +++ b/low_level_platform/impl/src/lf_flexpret_support.c @@ -0,0 +1,229 @@ +#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, +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 } + * @author{Magnus Mæhlum } + */ + +#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); + +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(); + return 0; +} + +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 + // 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); + } + } + + 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 + int ret = _lf_sleep_common(wakeup_time, true); + + lf_critical_section_enter(env); + return ret; +} + +int lf_sleep(interval_t sleep_duration) { + interval_t sleep_until = rdtime64() + sleep_duration; + return _lf_sleep_common(sleep_until, false); +} + +/** + * Initialize the LF clock. + */ +void _lf_initialize_clock() { + // 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; + + 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) { return lf_sleep(requested_time); } + +#if defined(LF_SINGLE_THREADED) + +int _lf_single_threaded_notify_of_event() { + _lf_async_event_occurred = true; + return 0; +} + +#else // Multi threaded + +int lf_available_cores() { + 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) { + /** + * 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); +} + +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) == FP_TIMEOUT) ? LF_TIMEOUT : 0; +} + +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`. +} +#endif + +#endif // PLATFORM_FLEXPRET diff --git a/platform/impl/CMakeLists.txt b/platform/impl/CMakeLists.txt index cef66b5ef..bc12ff11c 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 PRIVATE fp-sdk) else() add_library(lf-platform-impl STATIC) target_sources(lf-platform-impl PUBLIC ${LF_PLATFORM_FILES})