Skip to content
10 changes: 10 additions & 0 deletions erpc_c/port/erpc_setup_extensions_freertos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ using namespace erpc;

static Semaphore *s_erpc_call_in_progress = NULL;
static TimerHandle_t s_erpc_call_timer_cb = NULL;
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
static StaticTimer_t s_static_erpc_call_timer_cb;
#endif

void erpc::erpc_pre_cb_default(void)
{
Expand Down Expand Up @@ -46,16 +49,23 @@ void erpc_init_call_progress_detection_default(
s_erpc_call_in_progress = new Semaphore(1);
assert(s_erpc_call_in_progress && "Creating eRPC semaphore failed.");

#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
s_erpc_call_timer_cb = xTimerCreateStatic("Erpc client call timer", waitTimeMs / portTICK_PERIOD_MS, pdFALSE, NULL,
erpc_call_timer_cb, &s_static_erpc_call_timer_cb);
#else
s_erpc_call_timer_cb =
xTimerCreate("Erpc client call timer", waitTimeMs / portTICK_PERIOD_MS, pdFALSE, NULL, erpc_call_timer_cb);
#endif
assert(s_erpc_call_timer_cb && "Creating eRPC timer failed.");
}

void erpc_deinit_call_progress_detection_default(void)
{
if (s_erpc_call_in_progress != NULL)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
delete s_erpc_call_in_progress;
#endif
s_erpc_call_in_progress = NULL;
}

Expand Down
53 changes: 34 additions & 19 deletions erpc_c/port/erpc_threading.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2014-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* Copyright 2021 ACRIOS Systems s.r.o.
* All rights reserved.
*
*
Expand Down Expand Up @@ -70,14 +71,19 @@ class Thread
public:
//! @brief Unique identifier for a thread.
typedef void *thread_id_t;
#if ERPC_THREADS_IS(FREERTOS)
typedef StackType_t *thread_stack_pointer;
#else
typedef void *thread_stack_pointer;
#endif

/*!
* @brief Default constructor for use with the init() method.
*
* If this constructor is used, the init() method must be called before the thread can be
* started.
*
* @param name Optional name for the thread.
* @param[in] name Optional name for the thread.
*/
Thread(const char *name = 0);

Expand All @@ -86,12 +92,14 @@ class Thread
*
* This constructor fully initializes the thread object.
*
* @param entry
* @param priority
* @param stackSize
* @param name Optional name for the thread.
* @param[in] entry
* @param[in] priority
* @param[in] stackSize
* @param[in] name Optional name for the thread.
* @param[in] stackPtr Mandatory task stack pointer for static api usage.
*/
Thread(thread_entry_t entry, uint32_t priority = 0, uint32_t stackSize = 0, const char *name = 0);
Thread(thread_entry_t entry, uint32_t priority = 0, uint32_t stackSize = 0, const char *name = 0,
thread_stack_pointer stackPtr = 0);

/*!
* @brief Destructor.
Expand All @@ -118,8 +126,9 @@ class Thread
* @param[in] entry Entry function.
* @param[in] priority Task priority.
* @param[in] stackSize Stack size.
* @param[in] stackPtr Mandatory task stack pointer for static api usage.
*/
void init(thread_entry_t entry, uint32_t priority = 0, uint32_t stackSize = 0);
void init(thread_entry_t entry, uint32_t priority = 0, uint32_t stackSize = 0, thread_stack_pointer stackPtr = 0);

/*!
* @brief This function starts thread execution.
Expand Down Expand Up @@ -152,7 +161,7 @@ class Thread
return reinterpret_cast<thread_id_t>(m_thread->get_id());
#elif ERPC_THREADS_IS(WIN32)
return reinterpret_cast<thread_id_t>(m_thread);
#elif ERPC_THREADS_IS(THREADX)
#elif ERPC_THREADS_IS(THREADX)
return reinterpret_cast<thread_id_t>(m_thread.tx_thread_id);
#endif
}
Expand Down Expand Up @@ -212,18 +221,22 @@ class Thread
virtual void threadEntryPoint(void);

private:
const char *m_name; /*!< Thread name. */
thread_entry_t m_entry; /*!< Thread entry function. */
void *m_arg; /*!< Entry parameter. */
uint32_t m_stackSize; /*!< Stack size. */
uint32_t m_priority; /*!< Task priority. */
const char *m_name; /*!< Thread name. */
thread_entry_t m_entry; /*!< Thread entry function. */
void *m_arg; /*!< Entry parameter. */
uint32_t m_stackSize; /*!< Stack size. */
uint32_t m_priority; /*!< Task priority. */
thread_stack_pointer m_stackPtr; /*!< Task pointer. */
#if ERPC_THREADS_IS(PTHREADS)
static pthread_key_t s_threadObjectKey; /*!< Thread key. */
pthread_t m_thread; /*!< Current thread. */
#elif ERPC_THREADS_IS(FREERTOS)
TaskHandle_t m_task; /*!< Current task. */
Thread *m_next; /*!< Pointer to next Thread. */
static Thread *s_first; /*!< Pointer to first Thread. */
TaskHandle_t m_task; /*!< Current task. */
Thread *m_next; /*!< Pointer to next Thread. */
static Thread *s_first; /*!< Pointer to first Thread. */
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
StaticTask_t m_staticTask; /*!< Hold static task data. */
#endif
#elif ERPC_THREADS_IS(ZEPHYR)
struct k_thread m_thread; /*!< Current thread. */
k_thread_stack_t *m_stack; /*!< Pointer to stack. */
Expand All @@ -238,7 +251,7 @@ class Thread
static Thread *s_first; /*!< Pointer to first Thread. */
static CRITICAL_SECTION m_critical_section;
static BOOL m_critical_section_inited;
#elif ERPC_THREADS_IS(THREADX)
#elif ERPC_THREADS_IS(THREADX)
TX_THREAD m_thread; /*!< Underlying Thread instance */
Thread *m_next; /*!< Pointer to next Thread. */
static Thread *s_first; /*!< Pointer to first Thread. */
Expand Down Expand Up @@ -397,7 +410,8 @@ class Mutex
#if ERPC_THREADS_IS(PTHREADS)
pthread_mutex_t m_mutex; /*!< Mutex.*/
#elif ERPC_THREADS_IS(FREERTOS)
SemaphoreHandle_t m_mutex; /*!< Mutex.*/
SemaphoreHandle_t m_mutex; /*!< Mutex.*/
StaticSemaphore_t m_staticQueue; /*!< Static queue. */
#elif ERPC_THREADS_IS(ZEPHYR)
struct k_mutex m_mutex; /*!< Mutex.*/
#elif ERPC_THREADS_IS(MBED)
Expand Down Expand Up @@ -484,7 +498,8 @@ class Semaphore
until some predicate on shared data is satisfied. */
Mutex m_mutex; /*!< Mutext. */
#elif ERPC_THREADS_IS(FREERTOS)
SemaphoreHandle_t m_sem; /*!< Semaphore. */
SemaphoreHandle_t m_sem; /*!< Semaphore. */
StaticSemaphore_t m_staticQueue; /*!< Static queue. */
#elif ERPC_THREADS_IS(ZEPHYR)
struct k_sem m_sem; /*!< Semaphore. */
#elif ERPC_THREADS_IS(MBED)
Expand Down
45 changes: 41 additions & 4 deletions erpc_c/port/erpc_threading_freertos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ Thread::Thread(const char *name)
{
}

Thread::Thread(thread_entry_t entry, uint32_t priority, uint32_t stackSize, const char *name)
Thread::Thread(thread_entry_t entry, uint32_t priority, uint32_t stackSize, const char *name,
thread_stack_pointer stackPtr)
: m_name(name)
, m_entry(entry)
, m_arg(0)
Expand All @@ -51,26 +52,50 @@ Thread::Thread(thread_entry_t entry, uint32_t priority, uint32_t stackSize, cons

Thread::~Thread(void) {}

void Thread::init(thread_entry_t entry, uint32_t priority, uint32_t stackSize)
void Thread::init(thread_entry_t entry, uint32_t priority, uint32_t stackSize, thread_stack_pointer stackPtr)
{
m_entry = entry;
m_stackSize = stackSize;
m_priority = priority;
m_stackPtr = stackPtr;
}

void Thread::start(void *arg)
{
m_arg = arg;
bool taskCreated = false;

// Enter a critical section to disable preemptive scheduling until we add the newly
// created thread to the linked list. This prevents a race condition if the new thread is
// higher priority than the current thread, and the new thread calls getCurrenThread(),
// which will scan the linked list.
taskENTER_CRITICAL();

if (pdPASS == xTaskCreate(threadEntryPointStub, (m_name ? m_name : "task"),
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
if (m_stackPtr != NULL)
{
m_task =
xTaskCreateStatic(threadEntryPointStub, (m_name ? m_name : "task"),
((m_stackSize + sizeof(uint32_t) - 1) / sizeof(uint32_t)), // Round up number of words.
this, m_priority, &m_task))
this, m_priority, m_stackPtr, &m_staticTask);
taskCreated = true;
}
#endif

#if configSUPPORT_DYNAMIC_ALLOCATION
if (m_stackPtr == NULL)
{
if (pdPASS ==
xTaskCreate(threadEntryPointStub, (m_name ? m_name : "task"),
((m_stackSize + sizeof(uint32_t) - 1) / sizeof(uint32_t)), // Round up number of words.
this, m_priority, &m_task))
{
taskCreated = true;
}
}
#endif

if (taskCreated)
{
// Link in this thread to the list.
if (NULL != s_first)
Expand Down Expand Up @@ -180,7 +205,13 @@ void Thread::threadEntryPointStub(void *arg)
Mutex::Mutex(void)
: m_mutex(0)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
m_mutex = xSemaphoreCreateRecursiveMutexStatic(&m_staticQueue);
#elif configSUPPORT_DYNAMIC_ALLOCATION
m_mutex = xSemaphoreCreateRecursiveMutex();
#else
#error "Allocation method didn't match"
#endif
}

Mutex::~Mutex(void)
Expand Down Expand Up @@ -208,7 +239,13 @@ Semaphore::Semaphore(int count)
: m_sem(0)
{
// Set max count to highest signed int.
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
m_sem = xSemaphoreCreateCountingStatic(0x7fffffff, count, &m_staticQueue);
#elif configSUPPORT_DYNAMIC_ALLOCATION
m_sem = xSemaphoreCreateCounting(0x7fffffff, count);
#else
#error "Allocation method didn't match"
#endif
}

Semaphore::~Semaphore(void)
Expand Down
16 changes: 16 additions & 0 deletions erpc_c/transports/erpc_rpmsg_lite_base_transport.h
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* Copyright 2021 ACRIOS Systems s.r.o.
* All rights reserved.
*
*
Expand All @@ -11,8 +12,17 @@
#define _EMBEDDED_RPC__RPMSG_LITE_BASE_TRANSPORT_H_

#include "erpc_transport.h"
#include "erpc_config_internal.h"

#include "rpmsg_lite.h"
#include "rpmsg_env_specific.h"

#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
#ifndef RL_USE_STATIC_API
#warning "RPMSG is not set to use static allocation"
#endif
#endif


/*!
* @addtogroup rpmsg_lite_transport
Expand Down Expand Up @@ -54,6 +64,12 @@ class RPMsgBaseTransport : public Transport
protected:
static struct rpmsg_lite_instance *s_rpmsg; /*!< Pointer to instance of RPMSG lite. */
static uint8_t s_initialized; /*!< Represent information if the rpmsg-lite was initialized. */
#if RL_USE_STATIC_API
struct rpmsg_lite_instance m_static_context;
struct rpmsg_lite_ept_static_context m_ept_context;
rpmsg_static_queue_ctxt m_queue_context;
uint8_t m_queue_stack[RL_ENV_QUEUE_STATIC_STORAGE_SIZE];
#endif
};

} // namespace erpc
Expand Down
24 changes: 24 additions & 0 deletions erpc_c/transports/erpc_rpmsg_lite_rtos_transport.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,23 @@ erpc_status_t RPMsgRTOSTransport::init(uint32_t src_addr, uint32_t dst_addr, voi

if (0U == s_initialized)
{
#if RL_USE_STATIC_API
s_rpmsg = rpmsg_lite_master_init(base_address, length, rpmsg_link_id, RL_NO_FLAGS, &m_static_context);
#else
s_rpmsg = rpmsg_lite_master_init(base_address, length, rpmsg_link_id, RL_NO_FLAGS);
#endif
if (s_rpmsg == RL_NULL)
{
status = kErpcStatus_InitFailed;
}

if (status == kErpcStatus_Success)
{
#if RL_USE_STATIC_API
m_rpmsg_queue = rpmsg_queue_create(s_rpmsg, m_queue_stack, &m_queue_context);
#else
m_rpmsg_queue = rpmsg_queue_create(s_rpmsg);
#endif
if (m_rpmsg_queue == RL_NULL)
{
status = kErpcStatus_InitFailed;
Expand All @@ -95,7 +103,11 @@ erpc_status_t RPMsgRTOSTransport::init(uint32_t src_addr, uint32_t dst_addr, voi

if (status == kErpcStatus_Success)
{
#if RL_USE_STATIC_API
m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_queue_rx_cb, m_rpmsg_queue, &m_ept_context);
#else
m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_queue_rx_cb, m_rpmsg_queue);
#endif
if (m_rpmsg_ept == RL_NULL)
{
status = kErpcStatus_InitFailed;
Expand Down Expand Up @@ -137,7 +149,11 @@ erpc_status_t RPMsgRTOSTransport::init(uint32_t src_addr, uint32_t dst_addr, voi

if (0U == s_initialized)
{
#if RL_USE_STATIC_API
s_rpmsg = rpmsg_lite_remote_init(base_address, rpmsg_link_id, RL_NO_FLAGS, &m_static_context);
#else
s_rpmsg = rpmsg_lite_remote_init(base_address, rpmsg_link_id, RL_NO_FLAGS);
#endif
if (s_rpmsg == RL_NULL)
{
status = kErpcStatus_InitFailed;
Expand All @@ -155,7 +171,11 @@ erpc_status_t RPMsgRTOSTransport::init(uint32_t src_addr, uint32_t dst_addr, voi
{
}

#if RL_USE_STATIC_API
m_rpmsg_queue = rpmsg_queue_create(s_rpmsg, m_queue_stack, &m_queue_context);
#else
m_rpmsg_queue = rpmsg_queue_create(s_rpmsg);
#endif
if (m_rpmsg_queue == RL_NULL)
{
status = kErpcStatus_InitFailed;
Expand All @@ -164,7 +184,11 @@ erpc_status_t RPMsgRTOSTransport::init(uint32_t src_addr, uint32_t dst_addr, voi

if (status == kErpcStatus_Success)
{
#if RL_USE_STATIC_API
m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_queue_rx_cb, m_rpmsg_queue, &m_ept_context);
#else
m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_queue_rx_cb, m_rpmsg_queue);
#endif
if (m_rpmsg_ept == RL_NULL)
{
status = kErpcStatus_InitFailed;
Expand Down
Loading