diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/include/COMPONENT_RTX/cyabs_rtos_impl.h b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/include/COMPONENT_RTX/cyabs_rtos_impl.h index bb0f4767ec..8bf4b25dfd 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/include/COMPONENT_RTX/cyabs_rtos_impl.h +++ b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/include/COMPONENT_RTX/cyabs_rtos_impl.h @@ -6,7 +6,7 @@ * ******************************************************************************** * \copyright -* Copyright 2019 Cypress Semiconductor Corporation +* Copyright 2019-2020 Cypress Semiconductor Corporation * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,9 +37,9 @@ extern "C" /****************************************************** * Constants ******************************************************/ -#define CY_RTOS_MIN_STACK_SIZE 300 /** Minimum stack size */ +#define CY_RTOS_MIN_STACK_SIZE 300 /** Minimum stack size in bytes */ #define CY_RTOS_ALIGNMENT 0x00000008UL /** Minimum alignment for RTOS objects */ -#define CY_RTOS_ALIGNMENT_MASK 0x00000007UL /** Mask for checking the alignement of crated RTOS objects */ +#define CY_RTOS_ALIGNMENT_MASK 0x00000007UL /** Mask for checking the alignment of created RTOS objects */ /****************************************************** diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/include/cy_worker_thread.h b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/include/cy_worker_thread.h new file mode 100644 index 0000000000..68c6afe127 --- /dev/null +++ b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/include/cy_worker_thread.h @@ -0,0 +1,140 @@ +/***************************************************************************//** +* \file cy_worker_thread.h +* +* \brief +* Defines the interface for the worker thread utility. Provides prototypes for +* functions that allow creating/deleting worker threads and queueing work to +* a worker thread. +******************************************************************************** +* \copyright +* Copyright 2018-2020 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef CY_WORKER_THREAD_H +#define CY_WORKER_THREAD_H + +#ifdef __cplusplus +extern "C"{ +#endif + +#include + +#include "cy_result.h" +#include "cyabs_rtos.h" + +/** + * \addtogroup group_worker_thread_util Worker Thread Utility + * \{ + * Worker thread utility that allows functions to be run a different thread context. + * This utility can be used to delegate work that is not timing critical. For example, + * scheduling work in interrupt handlers to keep handler execution times low or if some + * work needs to be done at a different priority. + */ + +/**< Default worker thread name */ +#define CY_WORKER_THREAD_DEFAULT_NAME "CYWorker" +/** Default number of work items in the queue */ +#define CY_WORKER_DEFAULT_ENTRIES (16) + +/** Additional work cannot be enqueued because the worker thread has been terminated. + * This can occur if \ref cy_worker_thread_create was not called or \ref cy_worker_thread_delete was called before calling + * \ref cy_worker_thread_enqueue + */ +#define CY_WORKER_THREAD_ERR_THREAD_INVALID CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 32) + +/** Worker thread function call prototype */ +typedef void (cy_worker_thread_func_t)(void *arg); + +/** Thread state enumeration */ +typedef enum +{ + CY_WORKER_THREAD_INVALID, /**< Worker Thread is in invalid state */ + CY_WORKER_THREAD_VALID, /**< Worker Thread is in valid state */ + CY_WORKER_THREAD_TERMINATING, /**< Worker Thread is starting to terminate */ + CY_WORKER_THREAD_JOIN_COMPLETE /**< Worker Thread join is complete */ +} cy_worker_thread_state_t; + +/** Worker Thread Parameters. */ +typedef struct +{ + cy_thread_priority_t priority; /**< Requested thread priority. */ + uint32_t stack_size; /**< Size of stack for new thread. + Note that this must be atleast CY_RTOS_MIN_STACK_SIZE */ + uint8_t *stack; /**< Pointer to stack. If this is NULL a stack of + size \ref stack_size will be allocated. */ + const char *name; /**< Thread name. If set to NULL, \ref CY_WORKER_THREAD_DEFAULT_NAME + will be used. */ + uint32_t num_entries; /**< Maximum number of enteries the worker thread can queue. + If set to 0, \ref CY_WORKER_DEFAULT_ENTRIES will be used. */ +} cy_worker_thread_params_t; + +/** Worker Thread Information. */ +typedef struct +{ + cy_queue_t event_queue; /**< Event Queue for this thread */ + cy_thread_t thread; /**< Thread object */ + cy_worker_thread_state_t state; /**< State of the worker thread */ +} cy_worker_thread_info_t; + +/** Create worker thread to handle running callbacks in a separate thread. + * + * @note Calling this function twice on the same thread object ( \ref cy_worker_thread_info_t) without + * calling \ref cy_worker_thread_delete will cause memory leakage. + * + * @param[out] new_worker pointer to cy_worker_thread_info_t structure to be filled when created. + * @param[in] params pointer to requested parameters for starting worker thread. + * + * @return The status of the worker thread creation request. + */ + cy_rslt_t cy_worker_thread_create(cy_worker_thread_info_t *new_worker, const cy_worker_thread_params_t *params); + +/** Delete worker thread. + * + * @note This function will wait for the thread to complete all pending work in the + * queue and exit before returning. + * + * @param[in] old_worker pointer to cy_worker_thread_info_t structure to be deleted. + * + * @return The status of the deletion of the worker thread. + */ + cy_rslt_t cy_worker_thread_delete(cy_worker_thread_info_t *old_worker); + +/** Queue work on a worker thread. + * + * Call the given function in the worker thread context. + * + * @note If the thread priority is below that of the current thread, you must yield to allow + * the worker thread to run. This can be done by calling \ref cy_rtos_delay_milliseconds or + * by waiting on an RTOS object in all higher priority threads. + * + * @param[in] worker_info pointer to worker_thread used to run function + * @param[in] work_func function to run + * @param[in] arg opaque arg to be used in function call + * + * @return The status of the queueing of work. + */ + cy_rslt_t cy_worker_thread_enqueue(cy_worker_thread_info_t *worker_info, cy_worker_thread_func_t *work_func, void *arg); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* CY_WORKER_THREAD_H */ + +/** \} group_abstraction_resource */ + diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/include/cyabs_rtos.h b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/include/cyabs_rtos.h index b92a800dfd..d2d10dc7f4 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/include/cyabs_rtos.h +++ b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/include/cyabs_rtos.h @@ -9,7 +9,7 @@ * ******************************************************************************** * \copyright -* Copyright 2018-2019 Cypress Semiconductor Corporation +* Copyright 2018-2020 Cypress Semiconductor Corporation * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,15 +32,23 @@ #include "cy_result.h" #include #include +#include /** -* \defgroup group_abstraction_rtos_common Common +* \defgroup group_abstraction_rtos_common Common + * General types and defines for working with the RTOS abstraction layer. * \defgroup group_abstraction_rtos_mutex Mutex + * APIs for acquiring and working with Mutexes. * \defgroup group_abstraction_rtos_queue Queue + * APIs for creating and working with Queues. * \defgroup group_abstraction_rtos_semaphore Semaphore -* \defgroup group_abstraction_rtos_threads Threading + * APIs for acquiring and working with Semaphores. +* \defgroup group_abstraction_rtos_threads Threads + * APIs for creating and working with Threads. * \defgroup group_abstraction_rtos_time Time + * APIs for getting the current time and waiting. * \defgroup group_abstraction_rtos_timer Timer + * APIs for creating and working with Timers. */ #ifdef __cplusplus @@ -50,10 +58,17 @@ extern "C" /*********************************************** CONSTANTS **********************************************/ -/** - * \ingroup group_abstraction_rtos_common - * \{ - */ +/** + * \ingroup group_abstraction_rtos_common + * \{ + */ + +#if defined(DOXYGEN) +//#include "Template/cyabs_rtos_impl.h" + +/** Return value indicating success */ +#define CY_RSLT_SUCCESS ((cy_rslt_t)0x00000000U) +#endif /** Used with RTOS calls that require a timeout. This implies the call will never timeout. */ #define CY_RTOS_NEVER_TIMEOUT ( (uint32_t)0xffffffffUL ) @@ -61,8 +76,8 @@ extern "C" // // Note on error strategy. If the error is a normal part of operation (timeouts, full queues, empty // queues), the these errors are listed here and the abstraction layer implementation must map from the -// underlying errors to these. If the errors are special cases, the the error CY_RTOS_GENERAL_ERROR can be -// returns and cy_rtos_last_error() used to retrieve the RTOS specific error message. +// underlying errors to these. If the errors are special cases, the the error \ref CY_RTOS_GENERAL_ERROR +// will be returned and \ref cy_rtos_last_error() can be used to retrieve the RTOS specific error message. // /** Requested operation did not complete in the specified time */ #define CY_RTOS_TIMEOUT CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 0) @@ -72,15 +87,15 @@ extern "C" #define CY_RTOS_GENERAL_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 2) /** A bad argument was passed into the APIs */ #define CY_RTOS_BAD_PARAM CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 5) -/** A memory alignment issue was detected. Ensure memory provided is aligned per CY_RTOS_ALIGNMENT */ +/** A memory alignment issue was detected. Ensure memory provided is aligned per \ref CY_RTOS_ALIGNMENT_MASK */ #define CY_RTOS_ALIGNMENT_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 6) /** \} group_abstraction_rtos_common */ /** - * \ingroup group_abstraction_rtos_queue - * \{ - */ + * \ingroup group_abstraction_rtos_queue + * \{ + */ /** The Queue is already full and can't accept any more items at this time */ #define CY_RTOS_QUEUE_FULL CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 3) @@ -93,7 +108,7 @@ extern "C" /** * The state a thread can be in - * + * * \ingroup group_abstraction_rtos_threads */ typedef enum cy_thread_state @@ -108,29 +123,29 @@ typedef enum cy_thread_state /** * The type of timer - * + * * \ingroup group_abstraction_rtos_timer */ typedef enum cy_timer_trigger_type { CY_TIMER_TYPE_PERIODIC, /**< called periodically until stopped */ CY_TIMER_TYPE_ONCE, /**< called once only */ - cy_timer_type_periodic = CY_TIMER_TYPE_PERIODIC, /**< \deprecated replaced by CY_TIMER_TYPE_PERIODIC */ - cy_timer_type_once = CY_TIMER_TYPE_ONCE, /**< \deprecated replaced by CY_TIMER_TYPE_ONCE */ -} cy_timer_trigger_type_t ; + cy_timer_type_periodic = CY_TIMER_TYPE_PERIODIC, /**< \deprecated replaced by \ref CY_TIMER_TYPE_PERIODIC */ + cy_timer_type_once = CY_TIMER_TYPE_ONCE, /**< \deprecated replaced by \ref CY_TIMER_TYPE_ONCE */ +} cy_timer_trigger_type_t; /** * The type of a function that is the entry point for a thread * * @param[in] arg the argument passed from the thread create call to the entry function - * + * * \ingroup group_abstraction_rtos_threads */ -typedef void (*cy_thread_entry_fn_t)(cy_thread_arg_t arg) ; +typedef void (*cy_thread_entry_fn_t)(cy_thread_arg_t arg); /** * The callback function to be called by a timer - * + * * \ingroup group_abstraction_rtos_timer */ typedef void (*cy_timer_callback_t)(cy_timer_callback_arg_t arg); @@ -142,18 +157,17 @@ typedef void (*cy_timer_callback_t)(cy_timer_callback_arg_t arg); * results calling convention. The underlying RTOS implementations will not but rather * will have their own error code conventions. This function is provided as a service * to the developer, mostly for debugging, and returns the underlying RTOS error code - * from the last RTOS abstraction layer that returned CY_RTOS_GENERAL_ERROR. + * from the last RTOS abstraction layer that returned \ref CY_RTOS_GENERAL_ERROR. * * @return RTOS specific error code. - * + * * \ingroup group_abstraction_rtos_common */ cy_rtos_error_t cy_rtos_last_error(); /*********************************************** Threads **********************************************/ -/* - * +/** * \ingroup group_abstraction_rtos_threads * \{ */ @@ -161,7 +175,7 @@ cy_rtos_error_t cy_rtos_last_error(); /** Create a thread with specific thread argument. * * This function is called to startup a new thread. If the thread can exit, it must call - * cy_rtos_finish_thread() just before doing so. All created threds that can terminate, either + * \ref cy_rtos_exit_thread() just before doing so. All created threads that can terminate, either * by themselves or forcefully by another thread MUST be joined in order to cleanup any resources * that might have been allocated for them. * @@ -169,7 +183,7 @@ cy_rtos_error_t cy_rtos_last_error(); * @param[in] entry_function Function pointer which points to the main function for the new thread * @param[in] name String thread name used for a debugger * @param[in] stack The buffer to use for the thread stack. This must be aligned to - * CY_RTOS_ALIGNMENT with a size of at least CY_RTOS_MIN_STACK_SIZE. + * \ref CY_RTOS_ALIGNMENT_MASK with a size of at least \ref CY_RTOS_MIN_STACK_SIZE. * If stack is null, cy_rtos_create_thread will allocate a stack from the heap. * @param[in] stack_size The size of the thread stack in bytes * @param[in] priority The priority of the thread. Values are operating system specific, but some @@ -179,12 +193,11 @@ cy_rtos_error_t cy_rtos_last_error(); * CY_THREAD_PRIORITY_HIGH * @param[in] arg The argument to pass to the new thread * - * @return The status of thread create request. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * @return The status of thread create request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_create_thread(cy_thread_t *thread, cy_thread_entry_fn_t entry_function, const char *name, void *stack, uint32_t stack_size, cy_thread_priority_t priority, cy_thread_arg_t arg); - /** Exit the current thread. * * This function is called just before a thread exits. In some cases it is sufficient @@ -193,26 +206,26 @@ cy_rslt_t cy_rtos_create_thread(cy_thread_t *thread, cy_thread_entry_fn_t entry_ * where the RTOS must be signaled, this function should perform that In cases operation. * In code using RTOS services, this function should be placed at any at any location * where the main thread function will return, exiting the thread. Threads that can - * exit must still be joined (cy_rtos_join_thread) to ensure their resources are fully - * cleaned up. + * exit must still be joined (\ref cy_rtos_join_thread) to ensure their resources are + * fully cleaned up. * - * @return The status of thread exit request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of thread exit request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_exit_thread(); /** Terminates another thread. * - * This function is called to terminate another thread and reap the resoruces claimed - * by it thread. This should be called both when forcibly terminating another thread + * This function is called to terminate another thread and reap the resources claimed + * by the thread. This should be called both when forcibly terminating another thread * as well as any time a thread can exit on its own. For some RTOS implementations - * this is not required as the thread resoruces are claimed as soon as it exits. In + * this is not required as the thread resources are claimed as soon as it exits. In * other cases, this must be called to reclaim resources. Threads that are terminated - * must still be joined (cy_rtos_join_thread) to ensure their resources are fully + * must still be joined (\ref cy_rtos_join_thread) to ensure their resources are fully * cleaned up. * * @param[in] thread Handle of the thread to terminate * - * @returns The status of the thread terminate. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @returns The status of the thread terminate. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_terminate_thread(cy_thread_t *thread); @@ -223,19 +236,19 @@ cy_rslt_t cy_rtos_terminate_thread(cy_thread_t *thread); * * @param[in] thread Handle of the thread to wait for * - * @returns The status of thread join request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @returns The status of thread join request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_join_thread(cy_thread_t *thread); /** Checks if the thread is running * - * This function is called to determine if a thread is running or not. For information on - * the thread state, use the cy_rtos_get_thread_state() function. + * This function is called to determine if a thread is actively running or not. For information on + * the thread state, use the \ref cy_rtos_get_thread_state() function. * * @param[in] thread Handle of the terminated thread to delete * @param[out] running Returns true if the thread is running, otherwise false * - * @returns The status of the thread running check. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @returns The status of the thread running check. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_is_thread_running(cy_thread_t *thread, bool *running); @@ -246,7 +259,7 @@ cy_rslt_t cy_rtos_is_thread_running(cy_thread_t *thread, bool *running); * @param[in] thread Handle of the terminated thread to delete * @param[out] state Returns the state the thread is currently in * - * @returns The status of the thread state check. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @returns The status of the thread state check. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_get_thread_state(cy_thread_t *thread, cy_thread_state_t *state); @@ -256,7 +269,7 @@ cy_rslt_t cy_rtos_get_thread_state(cy_thread_t *thread, cy_thread_state_t *state * * @param[out] thread Handle of the current running thread * - * @returns The status of thread join request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @returns The status of thread join request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_get_thread_handle(cy_thread_t *thread); @@ -265,20 +278,38 @@ cy_rslt_t cy_rtos_get_thread_handle(cy_thread_t *thread); /*********************************************** Mutexes **********************************************/ /** - * \ingroup group_abstraction_rtos_mutex - * \{ - */ + * \ingroup group_abstraction_rtos_mutex + * \{ + */ -/** Create a mutex. +/** Create a recursive mutex. * - * This is basically a binary mutex which can be used to synchronize between threads - * and between threads and ISRs. + * Creates a binary mutex which can be used to synchronize between threads + * and between threads and ISRs. Created mutexes are recursive and support priority inheritance. + * + * This function has been replaced by \ref cy_rtos_init_mutex2 which allow for specifying + * whether or not the mutex supports recursion or not. * * @param[out] mutex Pointer to the mutex handle to be initialized * - * @return The status of mutex creation request. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * @return The status of mutex creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ -cy_rslt_t cy_rtos_init_mutex(cy_mutex_t *mutex); +#define cy_rtos_init_mutex(mutex) cy_rtos_init_mutex2(mutex, true) + +/** Create a mutex which can support recursion or not. + * + * Creates a binary mutex which can be used to synchronize between threads and between threads and + * ISRs. Created mutexes can support priority inheritance if recursive. + * + * \note Not all RTOS implementations support non-recursive mutexes. In this case a recursive + * mutex will be created. + * + * @param[out] mutex Pointer to the mutex handle to be initialized + * @param[in] recursive Should the created mutex support recursion or not + * + * @return The status of mutex creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] + */ +cy_rslt_t cy_rtos_init_mutex2(cy_mutex_t *mutex, bool recursive); /** Get a mutex. * @@ -290,22 +321,22 @@ cy_rslt_t cy_rtos_init_mutex(cy_mutex_t *mutex); * * @param[in] mutex Pointer to the mutex handle * @param[in] timeout_ms Maximum number of milliseconds to wait while attempting to get - * the mutex. Use the NEVER_TIMEOUT constant to wait forever. Must - * be zero is in_isr is true + * the mutex. Use the \ref CY_RTOS_NEVER_TIMEOUT constant to wait forever. + * Must be zero if in_isr is true. * * @return The status of the get mutex. Returns timeout if mutex was not acquired - * before timeout_ms period. [CY_RSLT_SUCCESS, CY_RTOS_TIMEOUT] + * before timeout_ms period. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_TIMEOUT, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_get_mutex(cy_mutex_t *mutex, cy_time_t timeout_ms); /** Set a mutex. * * The mutex is released allowing any other threads waiting on the mutex to - * obtain the sempahore. + * obtain the semaphore. * * @param[in] mutex Pointer to the mutex handle * - * @return The status of the set mutex request. [CY_RSLT_SUCCESS, CY_RTOS_TIMEOUT] + * @return The status of the set mutex request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] * */ cy_rslt_t cy_rtos_set_mutex(cy_mutex_t *mutex); @@ -316,7 +347,7 @@ cy_rslt_t cy_rtos_set_mutex(cy_mutex_t *mutex); * * @param[in] mutex Pointer to the mutex handle * - * @return The status to the delete request. [CY_RSLT_SUCCESS, CY_RTOS_TIMEOUT] + * @return The status to the delete request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_deinit_mutex(cy_mutex_t *mutex); @@ -325,9 +356,9 @@ cy_rslt_t cy_rtos_deinit_mutex(cy_mutex_t *mutex); /*********************************************** Semaphores **********************************************/ /** - * \ingroup group_abstraction_rtos_semaphore - * \{ - */ + * \ingroup group_abstraction_rtos_semaphore + * \{ + */ /** * Create a semaphore @@ -336,9 +367,9 @@ cy_rslt_t cy_rtos_deinit_mutex(cy_mutex_t *mutex); * * @param[in,out] semaphore Pointer to the semaphore handle to be initialized * @param[in] maxcount The maximum count for this semaphore - * @param[in] initcount The initial count for this sempahore + * @param[in] initcount The initial count for this semaphore * - * @return The status of the sempahore creation. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * @return The status of the semaphore creation. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, uint32_t initcount); @@ -351,10 +382,10 @@ cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, u * * @param[in] semaphore Pointer to the semaphore handle * @param[in] timeout_ms Maximum number of milliseconds to wait while attempting to get - * the semaphore. Use the NEVER_TIMEOUT constant to wait forever. Must + * the semaphore. Use the \ref CY_RTOS_NEVER_TIMEOUT constant to wait forever. Must * be zero is in_isr is true * @param[in] in_isr true if we are trying to get the semaphore from with an ISR - * @return The status of get semaphore operation [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * @return The status of get semaphore operation [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_TIMEOUT, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, bool in_isr); @@ -366,18 +397,29 @@ cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, * @param[in] semaphore Pointer to the semaphore handle * @param[in] in_isr Value of true indicates calling from interrupt context * Value of false indicates calling from normal thread context - * @return The status of set semaphore operation [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * @return The status of set semaphore operation [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr); /** - * Deletes a sempahore + * Get the count of a semaphore. * - * This function frees the resources associated with a sempahore. + * Gets the number of available tokens on the semaphore. * - * @param[in] semaphore Pointer to the sempahore handle + * @param[in] semaphore Pointer to the semaphore handle + * @param[out] count Pointer to the return count + * @return The status of get semaphore count operation [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] + */ +cy_rslt_t cy_rtos_get_count_semaphore(cy_semaphore_t *semaphore, size_t *count); + +/** + * Deletes a semaphore * - * @return The status of semaphore deletion [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * This function frees the resources associated with a semaphore. + * + * @param[in] semaphore Pointer to the semaphore handle + * + * @return The status of semaphore deletion [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore); @@ -385,10 +427,10 @@ cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore); /*********************************************** Events **********************************************/ -/** - * \ingroup group_abstraction_rtos_event - * \{ - */ +/** + * \ingroup group_abstraction_rtos_event + * \{ + */ /** Create an event. * @@ -398,7 +440,7 @@ cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore); * @param[in,out] event Pointer to the event handle to be initialized * * @return The status of the event initialization request. - * [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_init_event(cy_event_t *event); @@ -411,7 +453,7 @@ cy_rslt_t cy_rtos_init_event(cy_event_t *event); * @param[in] bits The value of the 32 bit flags * @param[in] in_isr If true, this is called from an ISR, otherwise from a thread * - * @return The status of the set request. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * @return The status of the set request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_setbits_event(cy_event_t *event, uint32_t bits, bool in_isr) ; @@ -424,7 +466,7 @@ cy_rslt_t cy_rtos_setbits_event(cy_event_t *event, uint32_t bits, bool in_isr) ; * @param[in] bits Any bits set in this value, will be cleared in the event. * @param[in] in_isr if true, this is called from an ISR, otherwise from a thread * - * @return The status of the clear flags request. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * @return The status of the clear flags request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_clearbits_event(cy_event_t *event, uint32_t bits, bool in_isr) ; @@ -435,13 +477,13 @@ cy_rslt_t cy_rtos_clearbits_event(cy_event_t *event, uint32_t bits, bool in_isr) * @param[in] event Pointer to the event handle * @param[out] bits pointer to receive the value of the event flags * - * @return The status of the get request. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * @return The status of the get request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_getbits_event(cy_event_t *event, uint32_t *bits); /** Wait for the event and return bits. * - * Waits for the event to be set and then returns the bits assocaited + * Waits for the event to be set and then returns the bits associated * with the event, or waits for the given timeout period. * @note This function returns if any bit in the set is set. * @@ -453,7 +495,7 @@ cy_rslt_t cy_rtos_getbits_event(cy_event_t *event, uint32_t *bits); * if false, any one bit in the initial bits value must be set to return * @param[in] timeout The amount of time to wait in milliseconds * - * @return The status of the wait for event request. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * @return The status of the wait for event request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_waitbits_event(cy_event_t *event, uint32_t *bits, bool clear, bool all, cy_time_t timeout); @@ -463,7 +505,7 @@ cy_rslt_t cy_rtos_waitbits_event(cy_event_t *event, uint32_t *bits, bool clear, * * @param[in] event Pointer to the event handle * - * @return The status of the deletion request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of the deletion request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_deinit_event(cy_event_t *event); @@ -471,10 +513,10 @@ cy_rslt_t cy_rtos_deinit_event(cy_event_t *event); /*********************************************** Queues **********************************************/ -/** - * \ingroup group_abstraction_rtos_queue - * \{ - */ +/** + * \ingroup group_abstraction_rtos_queue + * \{ + */ /** Create a queue. * @@ -485,7 +527,7 @@ cy_rslt_t cy_rtos_deinit_event(cy_event_t *event); * @param[in] length The maximum length of the queue in items * @param[in] itemsize The size of each item in the queue. * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_init_queue(cy_queue_t *queue, size_t length, size_t itemsize); @@ -502,24 +544,24 @@ cy_rslt_t cy_rtos_init_queue(cy_queue_t *queue, size_t length, size_t itemsize); * @param[in] timeout_ms The time to wait to place the item in the queue * @param[in] in_isr If true this is being called from within and ISR * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR, CY_RTOS_QUEUE_FULL] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR, \ref CY_RTOS_QUEUE_FULL] */ cy_rslt_t cy_rtos_put_queue(cy_queue_t *queue, const void *item_ptr, cy_time_t timeout_ms, bool in_isr); /** Gets an item in a queue. * - * This function gets an item fropm the queue. The item is copied + * This function gets an item from the queue. The item is copied * out of the queue into the memory provide by item_ptr. This space must be * large enough to hold a queue entry as defined when the queue was initialized. * * @note If in_isr is true, timeout_ms must be zero. * - * @param[in] queue Pointer to the queue handle - * @param[in] item_ptr Pointer to the memory for the item from the queue - * @param[in] timeout_ms The time to wait to place the item in the queue - * @param[in] in_isr If true this is being called from within and ISR + * @param[in] queue Pointer to the queue handle + * @param[in] item_ptr Pointer to the memory for the item from the queue + * @param[in] timeout_ms The time to wait to get an item from the queue + * @param[in] in_isr If true this is being called from within an ISR * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_NO_MEMORY, CY_RTOS_GENERAL_ERROR, CY_RTOS_QUEUE_EMPTY] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR, \ref CY_RTOS_QUEUE_EMPTY] */ cy_rslt_t cy_rtos_get_queue(cy_queue_t *queue, void *item_ptr, cy_time_t timeout_ms, bool in_isr); @@ -530,7 +572,7 @@ cy_rslt_t cy_rtos_get_queue(cy_queue_t *queue, void *item_ptr, cy_time_t timeout * @param[in] queue Pointer to the queue handle * @param[out] num_waiting Pointer to the return count * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_count_queue(cy_queue_t *queue, size_t *num_waiting); @@ -543,7 +585,7 @@ cy_rslt_t cy_rtos_count_queue(cy_queue_t *queue, size_t *num_waiting); * @param[in] queue Pointer to the queue handle * @param[out] num_spaces Pointer to the return count. * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_space_queue(cy_queue_t *queue, size_t *num_spaces); @@ -553,18 +595,18 @@ cy_rslt_t cy_rtos_space_queue(cy_queue_t *queue, size_t *num_spaces); * * @param[in] queue pointer to the queue handle * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_reset_queue(cy_queue_t *queue); /** Deinitialize the queue handle. * - * This function deinitializes the queue and returns all + * This function de-initializes the queue and returns all * resources used by the queue. * * @param[in] queue Pointer to the queue handle * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_deinit_queue(cy_queue_t *queue); @@ -573,33 +615,32 @@ cy_rslt_t cy_rtos_deinit_queue(cy_queue_t *queue); /*********************************************** Timers **********************************************/ /** - * \ingroup group_abstraction_rtos_timer - * \{ - */ + * \ingroup group_abstraction_rtos_timer + * \{ + */ /** Create a new timer. * - * This function intializes a timer object. @note The timer is - * not active until start is called. + * This function initializes a timer object. + * @note The timer is not active until start is called. + * @note The callback may be (likely will be) called from a different thread. * - * @param[out] timer Pointer to the timer handle to initalize + * @param[out] timer Pointer to the timer handle to initialize * @param[in] type Type of timer (periodic or once) - * @param[in] fun The functiuon + * @param[in] fun The function * @param[in] arg Argument to pass along to the callback function * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_init_timer(cy_timer_t *timer, cy_timer_trigger_type_t type, cy_timer_callback_t fun, cy_timer_callback_arg_t arg); /** Start a timer. - * - * @note The callback may be (likely will be) called from a different thread. * * @param[in] timer Pointer to the timer handle - * @param[in] num_ms The number of miliseconds to wait before the timer fires + * @param[in] num_ms The number of milliseconds to wait before the timer fires * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_start_timer(cy_timer_t *timer, cy_time_t num_ms); @@ -607,7 +648,7 @@ cy_rslt_t cy_rtos_start_timer(cy_timer_t *timer, cy_time_t num_ms); * * @param[in] timer Pointer to the timer handle * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_stop_timer(cy_timer_t *timer); @@ -616,18 +657,17 @@ cy_rslt_t cy_rtos_stop_timer(cy_timer_t *timer); * @param[in] timer Pointer to the timer handle * @param[out] state Return value for state, true if running, false otherwise * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_is_running_timer(cy_timer_t *timer, bool *state); /** Deinit the timer. * - * This function de initializes the timer and frees all consumed - * resources. + * This function deinitializes the timer and frees all consumed resources. * * @param[in] timer Pointer to the timer handle * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_deinit_timer(cy_timer_t *timer); @@ -636,9 +676,9 @@ cy_rslt_t cy_rtos_deinit_timer(cy_timer_t *timer); /*********************************************** Time **********************************************/ /** - * \ingroup group_abstraction_rtos_time - * \{ - */ + * \ingroup group_abstraction_rtos_time + * \{ + */ /** Gets time in milliseconds since RTOS start. * @@ -657,16 +697,15 @@ cy_rslt_t cy_rtos_get_time(cy_time_t *tval); * the longest period possible which is less than the delay required, * then makes up the difference with a tight loop. * - * @param[in] num_ms The number of miliseconds to delay for + * @param[in] num_ms The number of milliseconds to delay for * - * @return The status of the creation request. [CY_RSLT_SUCCESS, CY_RTOS_GENERAL_ERROR] + * @return The status of the creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] */ cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms); -/** \} group_abstraction_rtos_timer */ +/** \} group_abstraction_rtos_time */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* ifndef INCLUDED_CY_RTOS_INTERFACE_H_ */ - diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/source/COMPONENT_RTX/cyabs_rtos_rtxv5.c b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/source/COMPONENT_RTX/cyabs_rtos_rtxv5.c index 12727492ea..37c70fe5c7 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/source/COMPONENT_RTX/cyabs_rtos_rtxv5.c +++ b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/source/COMPONENT_RTX/cyabs_rtos_rtxv5.c @@ -6,7 +6,7 @@ * ******************************************************************************** * \copyright -* Copyright 2018-2019 Cypress Semiconductor Corporation +* Copyright 2018-2020 Cypress Semiconductor Corporation * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,8 +23,8 @@ *******************************************************************************/ #include -#include "cy_utils.h" -#include "cyabs_rtos.h" +#include +#include #if defined(__cplusplus) extern "C" { @@ -128,6 +128,10 @@ cy_rslt_t cy_rtos_create_thread(cy_thread_t *thread, cy_thread_entry_fn_t entry_ cy_rslt_t cy_rtos_exit_thread() { + /* This does not have a return statement because the osThreadExit() function + * does not return so the return statement would be unreachable and causes a + * warning for IAR compiler. + */ osThreadExit(); } @@ -236,7 +240,7 @@ cy_rslt_t cy_rtos_get_thread_handle(cy_thread_t *thread) * Mutexes ******************************************************/ -cy_rslt_t cy_rtos_init_mutex(cy_mutex_t *mutex) +cy_rslt_t cy_rtos_init_mutex2(cy_mutex_t *mutex, bool recursive) { cy_rslt_t status; osMutexAttr_t attr; @@ -246,7 +250,11 @@ cy_rslt_t cy_rtos_init_mutex(cy_mutex_t *mutex) else { attr.name = NULL; - attr.attr_bits = osMutexRecursive | osMutexPrioInherit; + attr.attr_bits = osMutexPrioInherit; + if (recursive) + { + attr.attr_bits |= osMutexRecursive; + } attr.cb_mem = malloc(osRtxMutexCbSize); attr.cb_size = osRtxMutexCbSize; @@ -389,6 +397,19 @@ cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr) return status; } +cy_rslt_t cy_rtos_get_count_semaphore(cy_semaphore_t *semaphore, size_t *count) +{ + cy_rslt_t status; + if (semaphore == NULL || count == NULL) + status = CY_RTOS_BAD_PARAM; + else + { + *count = osSemaphoreGetCount(*semaphore); + status = CY_RSLT_SUCCESS; + } + return status; +} + cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore) { cy_rslt_t status; diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/source/cy_worker_thread.c b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/source/cy_worker_thread.c new file mode 100644 index 0000000000..e6cc3f5d60 --- /dev/null +++ b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/source/cy_worker_thread.c @@ -0,0 +1,171 @@ +/***************************************************************************//** +* \file cy_worker_thread.c +* +* \brief +* Provides implementation for functions that allow creating/deleting worker +* threads and deferring work to a worker thread. +******************************************************************************** +* \copyright +* Copyright 2018-2020 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#include +#include + +#include "cy_worker_thread.h" +#include "cy_utils.h" +#include "cyhal_system.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* Info for dispatching a function call */ +typedef struct +{ + cy_worker_thread_func_t *work_func; + void *arg; +} cy_worker_dispatch_info_t; + +/* Worker Thread to dispatch the events that added to the event queue. + * It will wait indefinitely for a item to be queued and will terminate + * when the NULL work function is queued by delete. It will process all + * events before the terminating event. + * @param arg : pointer to @ref cy_worker_thread_info_t + */ +static void cy_worker_thread_func( cy_thread_arg_t arg ) +{ + cy_rslt_t result; + cy_worker_dispatch_info_t dispatch_info; + cy_worker_thread_info_t *worker = (cy_worker_thread_info_t*)arg; + + while(1) + { + result = cy_rtos_get_queue(&worker->event_queue, &dispatch_info, CY_RTOS_NEVER_TIMEOUT, false); + if(result == CY_RSLT_SUCCESS) + { + if(dispatch_info.work_func != NULL) + { + dispatch_info.work_func(dispatch_info.arg); + } + else + { + break; + } + } + } + cy_rtos_exit_thread(); +} + +cy_rslt_t cy_worker_thread_create(cy_worker_thread_info_t *new_worker, const cy_worker_thread_params_t *params) +{ + /* Param check */ + CY_ASSERT((params != NULL) && (new_worker != NULL)); + CY_ASSERT((params->stack == NULL) || (params->stack != NULL && params->stack_size != 0)); + + /* Start with a clean structure */ + memset(new_worker, 0, sizeof(cy_worker_thread_info_t)); + + cy_rslt_t result = cy_rtos_init_queue(&new_worker->event_queue, + (params->num_entries != 0) ? params->num_entries : CY_WORKER_DEFAULT_ENTRIES, + sizeof(cy_worker_dispatch_info_t)); + if(result == CY_RSLT_SUCCESS) + { + new_worker->state = CY_WORKER_THREAD_VALID; + result = cy_rtos_create_thread(&new_worker->thread, + cy_worker_thread_func, + (params->name != NULL) ? params->name : CY_WORKER_THREAD_DEFAULT_NAME, + params->stack, + params->stack_size, + params->priority, + (cy_thread_arg_t)new_worker); + + if(result != CY_RSLT_SUCCESS) + { + new_worker->state = CY_WORKER_THREAD_INVALID; + cy_rtos_deinit_queue(&new_worker->event_queue); + } + } + return result; +} + +cy_rslt_t cy_worker_thread_delete(cy_worker_thread_info_t *old_worker) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + if(old_worker->state != CY_WORKER_THREAD_INVALID) + { + if(old_worker->state == CY_WORKER_THREAD_VALID) + { + /* A terminating event is queued that will break the while loop + * Note that this is ok because thread enqueue function will not + * allow NULL as a valid value for the work function. + */ + cy_worker_dispatch_info_t dispatch_info = { NULL, NULL }; + result = cy_rtos_put_queue(&old_worker->event_queue, &dispatch_info, 0, false); + if(result != CY_RSLT_SUCCESS) + { + return result; + } + old_worker->state = CY_WORKER_THREAD_TERMINATING; + } + + if(old_worker->state != CY_WORKER_THREAD_JOIN_COMPLETE) + { + result = cy_rtos_join_thread(&old_worker->thread); + if(result != CY_RSLT_SUCCESS) + { + return result; + } + old_worker->state = CY_WORKER_THREAD_JOIN_COMPLETE; + } + + if(old_worker->state != CY_WORKER_THREAD_INVALID) + { + result = cy_rtos_deinit_queue(&old_worker->event_queue); + if(result != CY_RSLT_SUCCESS) + { + return result; + } + old_worker->state = CY_WORKER_THREAD_INVALID; + } + } + return result; +} + +cy_rslt_t cy_worker_thread_enqueue(cy_worker_thread_info_t *worker_info, cy_worker_thread_func_t *work_func, void *arg) +{ + CY_ASSERT(worker_info != NULL); + CY_ASSERT(work_func != NULL); + + uint32_t state = cyhal_system_critical_section_enter(); + if(worker_info->state != CY_WORKER_THREAD_VALID) + { + cyhal_system_critical_section_exit(state); + return CY_WORKER_THREAD_ERR_THREAD_INVALID; + } + cyhal_system_critical_section_exit(state); + + cy_worker_dispatch_info_t dispatch_info = { work_func, arg }; + /* Queue an event to be run by the worker thread */ + cy_rslt_t result = cy_rtos_put_queue(&worker_info->event_queue, &dispatch_info, 0, false); + + return result; +} + +#if defined(__cplusplus) +} +#endif diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/version.xml b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/version.xml new file mode 100644 index 0000000000..a71904cac7 --- /dev/null +++ b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/abstraction/rtos/version.xml @@ -0,0 +1 @@ +1.2.1.13635