Commit 29d124d0 by Michael Schmid

added FreeRTOS implementation

parent dd88ea03
......@@ -26,6 +26,20 @@
#
function(SetGNUCompilerFlags compiler_libs)
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
if(DEFINED CMAKE_SYSTEM_PROCESSOR)
set(compiler_libs PARENT_SCOPE)
set(common_flags "-fno-common -Os")
set(warning_flags "-W -Wall -Wextra -Wdiv-by-zero -Warray-bounds -Wcast-align -Wignored-qualifiers -Wformat -Wformat-security")
set(target_flags "-DAPPKIT_TC277TFT -fshort-double -mcpu=tc27xx -mversion-info")
if (WARNINGS_ARE_ERRORS STREQUAL ON)
set(warning_flags "${warning_flags} -Werror")
endif()
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${common_flags} ${warning_flags} ${target_flags}"
PARENT_SCOPE)
endif()
else()
set(compiler_libs pthread rt PARENT_SCOPE)
# -Wall -> All warnings
# -Wextra -> Even more warnings
......@@ -57,6 +71,7 @@ function(SetGNUCompilerFlags compiler_libs)
PARENT_SCOPE)
endif()
endif()
endif()
endfunction()
function(SetVisualStudioCompilerFlags)
......
......@@ -76,7 +76,7 @@ endif()
# The set option will be converted to uppercase letters by cmake!! --> ON/OFF
# Note that the help string (second argument) cannot be printed by cmake.
#
option(BUILD_TESTS "Specify whether tests should be built" ON)
option(BUILD_TESTS "Specify whether tests should be built" OFF)
option(BUILD_EXAMPLES "Specify whether examples should be built" OFF)
option(USE_EXCEPTIONS "Specify whether exceptions should be activated in C++" ON)
option(INSTALL_DOCS "Specify whether Doxygen docs should be installed" ON)
......@@ -104,6 +104,12 @@ else()
endif()
message(" (set with command line option -DUSE_AUTOMATIC_INITIALIZATION=ON/OFF)")
set(CMAKE_CXX_STANDARD_LIBRARIES ${FREE_RTOS_LIB_PATH}/iRom/libFreeRTOS_Lib.a)
set(CMAKE_C_STANDARD_LIBRARIES ${FREE_RTOS_LIB_PATH}/iRom/libFreeRTOS_Lib.a)
set(CMAKE_INSTALL_RPATH FREE_RTOS_LIB_PATH)
set(__TriCore__ 1)
include(CMakeCommon/SetCompilerFlags.cmake)
SetGNUCompilerFlags(compiler_libs compiler_flags)
SetVisualStudioCompilerFlags(compiler_libs compiler_flags)
......
......@@ -2,7 +2,8 @@
SET(CMAKE_SYSTEM_NAME Generic)
#this one not so much
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_SYSTEM_PROCESSOR TriCore)
SET(CMAKE_SYSTEM_PROCESSOR __TriCore__)
SET(__TriCore__ 1)
# specify the cross compiler
SET(CMAKE_C_COMPILER C:/HighTec/toolchains/tricore/v4.6.6.0-infineon-1.1/bin/tricore-gcc.exe)
......@@ -11,6 +12,9 @@ SET(CMAKE_CXX_COMPILER C:/HighTec/toolchains/tricore/v4.6.6.0-infineon-1.1/bin/t
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH C:/HighTec/toolchains/tricore/v4.6.6.0-infineon-1.1)
SET(FREE_RTOS_LIB_PATH C:/data/projekte/freeRTOS_lib/)
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
# for libraries and headers in the target directories
......
......@@ -46,6 +46,8 @@
*/
#if defined(_M_IA64) || defined(_IA64)
#define EMBB_PLATFORM_CACHE_LINE_SIZE 128
#elif defined(__TriCore__)
#define EMBB_PLATFORM_CACHE_LINE_SIZE 32
#else
#define EMBB_PLATFORM_CACHE_LINE_SIZE 64
#endif
......@@ -86,6 +88,8 @@
#define EMBB_PLATFORM_ARCH_X86
#elif defined(__arm__)
#define EMBB_PLATFORM_ARCH_ARM
#elif defined(__TriCore__)
#define EMBB_PLATFORM_ARCH_TC
#else
#define EMBB_PLATFORM_ARCH_UNKNOWN
#endif
......@@ -93,7 +97,11 @@
#if defined(EMBB_PLATFORM_COMPILER_MSVC)
#define EMBB_PLATFORM_THREADING_WINTHREADS
#elif defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_PLATFORM_THREADING_POSIXTHREADS
#if defined(EMBB_PLATFORM_ARCH_TC)
#define EMBB_PLATFORM_THREADING_RTOSTASKS
#else
#define EMBB_PLATFORM_THREADING_POSIXTHREADS
#endif
#else
#error "No thread implementation could be determined"
#endif
......
......@@ -71,6 +71,7 @@ typedef CONDITION_VARIABLE embb_condition_t;
#define EMBB_THREAD_SPECIFIC static __declspec(thread)
/* EMBB_PLATFORM_THREADING_WINTHREADS */
#elif defined EMBB_PLATFORM_THREADING_POSIXTHREADS
#include <pthread.h>
......@@ -95,7 +96,31 @@ typedef pthread_cond_t embb_condition_t;
#define EMBB_THREAD_SPECIFIC __thread
#else /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
/* EMBB_PLATFORM_THREADING_POSIXTHREADS */
#elif defined EMBB_PLATFORM_THREADING_RTOSTASKS
#include <FreeRTOS/task.h>
#include <FreeRTOS/semphr.h>
struct embb_internal_thread_arg_t;
/**
* Opaque handle for a thread.
*/
typedef struct embb_thread_t {
TaskHandle_t embb_internal_handle;
struct embb_internal_thread_arg_t* embb_internal_arg;
} embb_thread_t;
typedef TaskStatus_t embb_thread_id_t;
typedef SemaphoreHandle_t embb_mutex_t;
typedef SemaphoreHandle_t embb_condition_t; // scm34681: implement FreeRTOS condition variable
#define EMBB_DURATION_MIN_NANOSECONDS 1000
#define EMBB_THREAD_SPECIFIC
#else /* EMBB_PLATFORM_THREADING_RTOSTASKS */
#error "No threading platform defined!"
......
......@@ -185,3 +185,7 @@ int embb_condition_destroy(embb_condition_t* condition_var) {
}
#endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
#ifdef EMBB_PLATFORM_THREADING_RTOSTASKS
#endif /* EMBB_PLATFORM_THREADING_RTOSTASKS */
......@@ -125,6 +125,32 @@ void embb_core_set_init(embb_core_set_t* core_set, int initializer) {
#endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
#ifdef EMBB_PLATFORM_THREADING_RTOSTASKS
#ifdef __TriCore__
#define CORE_COUNT 3
#endif
unsigned int embb_core_count_available() {
return CORE_COUNT;
}
void embb_core_set_init(embb_core_set_t* core_set, int initializer) { // scm34681: rework
assert(core_set != NULL);
assert(embb_core_count_available() < 64 &&
"Core sets are only supported up to 64 processors!");
if (initializer == 0) {
embb_bitset_clear_all(&core_set->rep);
} else {
embb_bitset_set_n(&core_set->rep, embb_core_count_available());
}
}
#endif EMBB_PLATFORM_THREADING_RTOSTASKS
void embb_core_set_add(embb_core_set_t* core_set, unsigned int core_number) {
assert(core_set != NULL);
assert(core_number < embb_core_count_available());
......
......@@ -178,6 +178,14 @@ void *embb_alloc_aligned(size_t alignment, size_t size) {
*/
malloc_addr = _aligned_malloc(size, alignment);
#elif defined EMBB_PLATFORM_COMPILER_GNUC
#ifdef __TRICORE__
/*
* The TriCore Toolchain uses obsolete function memalign() for
* aligned memory allocation.
*/
#include <malloc.h> // scm3681: rework
malloc_addr = memalign(alignment, size);
#else /* __TRICORE__ */
/*
* From the Documentation:
* The posix_memalign() function shall allocate size bytes aligned on a
......@@ -190,6 +198,7 @@ void *embb_alloc_aligned(size_t alignment, size_t size) {
int status = posix_memalign(&malloc_addr, alignment, size);
EMBB_UNUSED(status);
#endif
#endif
return malloc_addr;
}
......
/*
* Copyright (c) 2014-2016, Siemens AG. All rights reserved.
*
* 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.
*/
* Copyright (c) 2014-2016, Siemens AG. All rights reserved.
*
* 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.
*/
#include <embb/base/c/mutex.h>
#include <embb/base/c/thread.h>
......@@ -143,6 +143,78 @@ void embb_mutex_destroy(embb_mutex_t* mutex) {
#endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
#ifdef EMBB_PLATFORM_THREADING_RTOSTASKS
#include <FreeRTOS/semphr.h>
#include <FreeRTOS/portmacro.h>
int embb_mutex_init(embb_mutex_t* mutex, int type) {
if (NULL == mutex) {
return EMBB_ERROR;
}
/*
* scm34681:
* Type of mutex cannot be determined from SemaphoreHandle_t,
* but mutex gets locked with two different functions.
* ==> only recursive mutexes are used.
* Check Queue_t for type checking. Queue_t not defined in queue.h
* but queue.c...
*/
/*if(type == EMBB_MUTEX_PLAIN) {
mutex = xSemaphoreCreateMutex();
}
else {
assert(type == EMBB_MUTEX_RECURSIVE);*/
mutex = xSemaphoreCreateRecursiveMutex();
/*}*/
EMBB_UNUSED(type);
if(mutex == NULL) {
return EMBB_ERROR;
}
return EMBB_SUCCESS;
}
int embb_mutex_lock(embb_mutex_t* mutex) {
if (NULL == mutex) {
return EMBB_ERROR;
}
int result = xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
if (result != 1) return EMBB_ERROR;
return EMBB_SUCCESS;
}
int embb_mutex_try_lock(embb_mutex_t* mutex) {
if (NULL == mutex) {
return EMBB_ERROR;
}
int result = xSemaphoreTakeRecursive(mutex, 0);
if (result != 1) return EMBB_ERROR;
return EMBB_SUCCESS;
}
int embb_mutex_unlock(embb_mutex_t* mutex) {
if (NULL == mutex) {
return EMBB_ERROR;
}
int result = xSemaphoreGiveRecursive(mutex);
if(result != 1) return EMBB_ERROR;
return EMBB_SUCCESS;
}
void embb_mutex_destroy(embb_mutex_t* mutex) {
assert(NULL != mutex);
vSemaphoreDelete(mutex);
}
#endif /* EMBB_PLATFORM_THREADING_RTOSTASKS */
int embb_spin_init(embb_spinlock_t* spinlock) {
if (NULL == spinlock) {
return EMBB_ERROR;
......@@ -174,7 +246,7 @@ int embb_spin_lock(embb_spinlock_t* spinlock) {
}
int embb_spin_try_lock(embb_spinlock_t* spinlock,
unsigned int max_number_spins) {
unsigned int max_number_spins) {
if (NULL == spinlock) {
return EMBB_ERROR;
}
......
/*
* Copyright (c) 2014-2016, Siemens AG. All rights reserved.
*
* 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.
*/
* Copyright (c) 2014-2016, Siemens AG. All rights reserved.
*
* 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.
*/
#include <embb/base/c/thread.h>
#include <embb/base/c/internal/thread_index.h>
......@@ -43,20 +43,20 @@ void embb_thread_set_max_count(unsigned int max) {
#ifdef EMBB_PLATFORM_THREADING_WINTHREADS
/**
* Used to wrap client thread start function and argument when calling internal
* thread start function embb_internal_thread_start.
*/
* Used to wrap client thread start function and argument when calling internal
* thread start function embb_internal_thread_start.
*/
typedef struct embb_internal_thread_arg_t {
embb_thread_start_t func;
void* arg;
} embb_internal_thread_arg_t;
/**
* Used to offer a consistent thread start function signature. Windows threads
* have a different signature than Pthreads and C11. This internal start
* function for Windows threads just calls the client start function with the
* given argument.
*/
* Used to offer a consistent thread start function signature. Windows threads
* have a different signature than Pthreads and C11. This internal start
* function for Windows threads just calls the client start function with the
* given argument.
*/
DWORD WINAPI embb_internal_thread_start(LPVOID internalArg) {
int result = ((embb_internal_thread_arg_t*)internalArg)->func(
((embb_internal_thread_arg_t*)internalArg)->arg);
......@@ -79,7 +79,7 @@ void embb_thread_yield() {
}
int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set,
embb_thread_start_t func, void *arg) {
embb_thread_start_t func, void *arg) {
if (thread == NULL) {
return EMBB_ERROR;
}
......@@ -181,9 +181,9 @@ int embb_thread_equal(const embb_thread_t* lhs, const embb_thread_t* rhs) {
#endif /* EMBB_PLATFORM_HAS_HEADER_SYSINFO */
/**
* Used to wrap client thread start function and argument when calling internal
* thread start function embb_internal_thread_start.
*/
* Used to wrap client thread start function and argument when calling internal
* thread start function embb_internal_thread_start.
*/
typedef struct embb_internal_thread_arg_t {
embb_thread_start_t func;
void* arg;
......@@ -191,11 +191,11 @@ typedef struct embb_internal_thread_arg_t {
} embb_internal_thread_arg_t;
/**
* Used to offer a consistent thread start function signature. POSIX threads
* have a different signature than C11 threads. This internal start function
* for POSIX threads just calls the client start function with the given
* argument.
*/
* Used to offer a consistent thread start function signature. POSIX threads
* have a different signature than C11 threads. This internal start function
* for POSIX threads just calls the client start function with the given
* argument.
*/
void* embb_internal_thread_start(void* internalArg) {
((embb_internal_thread_arg_t*)internalArg)->result =
((embb_internal_thread_arg_t*)internalArg)->func(
......@@ -215,7 +215,7 @@ void embb_thread_yield() {
}
int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set,
embb_thread_start_t func, void* arg) {
embb_thread_start_t func, void* arg) {
if (thread == NULL) {
return EMBB_ERROR;
}
......@@ -300,3 +300,128 @@ int embb_thread_equal(const embb_thread_t* lhs, const embb_thread_t* rhs) {
}
#endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
#ifdef EMBB_PLATFORM_THREADING_RTOSTASKS
#include <FreeRTOS/task.h>
/**
* Used to wrap client thread start function and argument when calling internal
* thread start function embb_internal_thread_start.
*/
typedef struct embb_internal_thread_arg_t {
embb_thread_start_t func;
void* arg;
int result;
} embb_internal_thread_arg_t;
/**
* Used to offer a consistent thread start function signature. POSIX threads
* have a different signature than C11 threads. This internal start function
* for POSIX threads just calls the client start function with the given
* argument.
*/
void* embb_internal_thread_start(void* internalArg) {
for(;;) {
((embb_internal_thread_arg_t*)internalArg)->result =
((embb_internal_thread_arg_t*)internalArg)->func(
((struct embb_internal_thread_arg_t*)internalArg)->arg);
vTaskDelete(NULL);
}
}
embb_thread_t embb_thread_current() {
embb_thread_t thread;
thread.embb_internal_handle = xTaskGetCurrentTaskHandle();
thread.embb_internal_arg = NULL;
return thread;
}
void embb_thread_yield() {
taskYIELD();
}
int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set,
embb_thread_start_t func, void *arg) {
int status;
if (thread == NULL) {
return EMBB_ERROR;
}
thread->embb_internal_arg = (embb_internal_thread_arg_t*)
embb_alloc(sizeof(embb_internal_thread_arg_t));
if (thread->embb_internal_arg == NULL) {
thread->embb_internal_handle = NULL;
return EMBB_NOMEM;
}
thread->embb_internal_arg->func = func;
thread->embb_internal_arg->arg = arg;
status = xTaskCreate( embb_internal_thread_start, // entry function
0, // task name (not needed)
128, // stack size
thread->embb_internal_arg, // parameters
1, // priority
thread->embb_internal_handle); // thread handle
if (status != 1) {
embb_free(thread->embb_internal_arg);
thread->embb_internal_arg = NULL;
return EMBB_ERROR;
}
/*if (core_set != NULL) { // scm34681: implement core affinity
DWORD_PTR core_mask = 0;
DWORD bit_mask = 1;
assert(embb_core_count_available() < 64);
for (unsigned int i = 0; i < embb_core_count_available(); i++) {
if (embb_core_set_contains(core_set, i)) {
core_mask |= bit_mask;
}
bit_mask <<= 1;
}
if (SetThreadAffinityMask(thread->embb_internal_handle, core_mask)
== (DWORD_PTR)NULL) {
return EMBB_ERROR;
}
}*/
return EMBB_SUCCESS;
}
int embb_thread_join(embb_thread_t* thread, int *result_code) {
if (thread == NULL) {
return EMBB_ERROR;
}
int status = 0;
while(thread->embb_internal_handle != NULL && status++ < 10000); // scm34681: rework
if (thread->embb_internal_arg != NULL) {
if (result_code != NULL) {
*result_code = thread->embb_internal_arg->result;
}
embb_free(thread->embb_internal_arg);
}
return EMBB_SUCCESS;
}
int embb_thread_equal(const embb_thread_t* lhs, const embb_thread_t* rhs) {
if (lhs == NULL || rhs == NULL) {
return 0;
}
TaskStatus_t lhs_info;
TaskStatus_t rhs_info;
vTaskGetInfo(lhs->embb_internal_handle, &lhs_info, 0, 0);
vTaskGetInfo(lhs->embb_internal_handle, &rhs_info, 0, 0);
return lhs_info.xTaskNumber == rhs_info.xTaskNumber;
}
#endif /* EMBB_PLATFORM_THREADING_RTOSTASKS */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment