Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Platform support for Raspberry Pi Pico #233

Merged
merged 17 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,11 @@ endif()

# Link with thread library
if(DEFINED LF_THREADED OR DEFINED LF_TRACE)
find_package(Threads REQUIRED)
target_link_libraries(core PUBLIC Threads::Threads)
# FIXME make this more general for other platforms
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040")
find_package(Threads REQUIRED)
target_link_libraries(core PUBLIC Threads::Threads)
endif()
endif()

# Macro for translating a command-line argument into compile definition for
Expand Down
3 changes: 3 additions & 0 deletions core/platform/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ lf_macos_support.c
lf_windows_support.c
lf_nrf52_support.c
lf_zephyr_support.c
lf_rp2040_support.c
)

if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
Expand All @@ -18,6 +19,8 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Nrf52")
target_compile_definitions(core PUBLIC PLATFORM_NRF52)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr")
target_compile_definitions(core PUBLIC PLATFORM_ZEPHYR)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040")
target_compile_definitions(core PUBLIC PLATFORM_RP2040)
endif()

# Add sources to the list for debug info
Expand Down
3 changes: 3 additions & 0 deletions core/platform/Platform.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
message("Using Windows SDK version ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr")
set(LF_PLATFORM_FILE lf_zephyr_support.c)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040")
message("Using pico-sdk for RP2040 target")
set(LF_PLATFORM_FILE lf_rp2040_support.c)
else()
message(FATAL_ERROR "Your platform is not supported! The C target supports Linux, MacOS and Windows.")
endif()
87 changes: 87 additions & 0 deletions core/platform/lf_freertos_threads_support.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#if defined(LF_THREADED)
// FIXME: build system with pico-support
#include "platform.h"
#include "lf_freertos_threads_support.h"

#include <pthread.h>
#include <errno.h>
#include <stdint.h> // For fixed-width integral types

int lf_thread_create(lf_thread_t* thread, void *(*lf_thread) (void *), void* arguments) {
return pthread_create((pthread_t*)thread, NULL, lf_thread, arguments);
}

int lf_thread_join(lf_thread_t thread, void** thread_return) {
return pthread_join((pthread_t)thread, thread_return);
}

int lf_mutex_init(lf_mutex_t* mutex) {
// Set up a recursive mutex
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
// Initialize the mutex to be recursive, meaning that it is OK
// for the same thread to lock and unlock the mutex even if it already holds
// the lock.
// FIXME: This is dangerous. The docs say this: "It is advised that an
// application should not use a PTHREAD_MUTEX_RECURSIVE mutex with
// condition variables because the implicit unlock performed for a
// pthread_cond_wait() or pthread_cond_timedwait() may not actually
// release the mutex (if it had been locked multiple times).
// If this happens, no other thread can satisfy the condition
// of the predicate.” This seems like a bug in the implementation of
// pthreads. Maybe it has been fixed?
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
return pthread_mutex_init((pthread_mutex_t*)mutex, &attr);
}

int lf_mutex_lock(lf_mutex_t* mutex) {
return pthread_mutex_lock((pthread_mutex_t*)mutex);
}

int lf_mutex_unlock(lf_mutex_t* mutex) {
return pthread_mutex_unlock((pthread_mutex_t*)mutex);
}

int lf_cond_init(lf_cond_t* cond, lf_mutex_t* mutex) {
cond->mutex = mutex;
pthread_condattr_t cond_attr;
pthread_condattr_init(&cond_attr);
// Limit the scope of the condition variable to this process (default)
pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_PRIVATE);
return pthread_cond_init(&cond->condition, &cond_attr);
}

int lf_cond_broadcast(lf_cond_t* cond) {
return pthread_cond_broadcast((pthread_cond_t*)&cond->condition);
}

int lf_cond_signal(lf_cond_t* cond) {
return pthread_cond_signal((pthread_cond_t*)&cond->condition);
}

int lf_cond_wait(lf_cond_t* cond) {
return pthread_cond_wait((pthread_cond_t*)&cond->condition, (pthread_mutex_t*)cond->mutex);
}

int lf_cond_timedwait(lf_cond_t* cond, int64_t absolute_time_ns) {
// Convert the absolute time to a timespec.
// timespec is seconds and nanoseconds.
struct timespec timespec_absolute_time
= {(time_t)absolute_time_ns / 1000000000LL, (long)absolute_time_ns % 1000000000LL};
int return_value = 0;
return_value = pthread_cond_timedwait(
(pthread_cond_t*)&cond->condition,
(pthread_mutex_t*)cond->mutex,
&timespec_absolute_time
);
switch (return_value) {
case ETIMEDOUT:
return_value = LF_TIMEOUT;
break;

default:
break;
}
return return_value;
}
#endif
Loading