mirror of https://github.com/ARMmbed/mbed-os.git
CMake: Add support for rtos dir
parent
929adbe936
commit
5c453e5d46
|
@ -0,0 +1,22 @@
|
|||
# Copyright (c) 2020 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
target_sources(mbed-os
|
||||
PRIVATE
|
||||
source/ConditionVariable.cpp
|
||||
source/EventFlags.cpp
|
||||
source/Kernel.cpp
|
||||
source/Mutex.cpp
|
||||
source/Semaphore.cpp
|
||||
source/ThisThread.cpp
|
||||
source/Thread.cpp
|
||||
)
|
||||
|
||||
|
||||
add_subdirectory(source/TARGET_CORTEX)
|
||||
|
||||
target_include_directories(mbed-os
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
source
|
||||
)
|
|
@ -0,0 +1,550 @@
|
|||
/* Mbed Microcontroller Library
|
||||
* Copyright (c) 2017-2019 ARM Limited
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef CONDITIONVARIABLE_H
|
||||
#define CONDITIONVARIABLE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <utility>
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/Mutex.h"
|
||||
#include "rtos/Semaphore.h"
|
||||
#include "rtos/Kernel.h"
|
||||
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos-public-api */
|
||||
/** @{*/
|
||||
|
||||
enum class cv_status {
|
||||
no_timeout,
|
||||
timeout
|
||||
};
|
||||
|
||||
struct Waiter;
|
||||
/**
|
||||
* \defgroup rtos_ConditionVariable ConditionVariable class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** The ConditionVariable class is a synchronization primitive that allows
|
||||
* threads to wait until a particular condition occurs.
|
||||
*
|
||||
* Use the condition variable in conjunction with a mutex to safely wait for
|
||||
* or notify waiters of condition changes to a resource accessible by multiple
|
||||
* threads.
|
||||
*
|
||||
* The thread that intends to wait on a ConditionVariable must:
|
||||
* - Acquire a lock on a mutex.
|
||||
* - Execute `wait`, `wait_for` or `wait_until`. While the thread is waiting,
|
||||
* the mutex is unlocked.
|
||||
* - When the condition variable has been notified, or in the case of `wait_for`
|
||||
* and `wait_until` the timeout expires, the thread is awakened.
|
||||
*
|
||||
* The thread that intends to notify a ConditionVariable must:
|
||||
* - Acquire a lock on the mutex used to construct the condition variable.
|
||||
* - Execute `notify_one` or `notify_all` on the condition variable.
|
||||
*
|
||||
* All threads waiting on the condition variable wake when
|
||||
* `ConditionVariable::notify_all` is called.
|
||||
* At least one thread waiting on the condition variable wakes
|
||||
* when `ConditionVariable::notify_one` is called.
|
||||
*
|
||||
* While a thread is waiting for notification of a
|
||||
* ConditionVariable, it releases the lock held on the mutex.
|
||||
* The ConditionVariable reacquires the mutex lock before exiting the wait
|
||||
* function.
|
||||
*
|
||||
* #### Unspecified behavior
|
||||
* - The thread that is unblocked on `ConditionVariable::notify_one` is
|
||||
* unspecified if there are multiple waiters.
|
||||
* - When `ConditionVariable::notify_one` or `ConditionVariable::notify_all` is
|
||||
* called and there are one or more waiters, and one or more threads
|
||||
* attempting to acquire the condition variable's mutex, the order in which the mutex is
|
||||
* acquired is unspecified.
|
||||
* - Spurious notifications (not triggered by the application) can occur.
|
||||
*
|
||||
* #### Undefined behavior
|
||||
* - Calling wait if the mutex is not locked by the current thread is undefined
|
||||
* behavior.
|
||||
* - The order in which waiting threads acquire the condition variable's
|
||||
* mutex after `ConditionVariable::notify_all` is called is undefined.
|
||||
* - The behavior of `ConditionVariable::wait` and `ConditionVariable::wait_for`
|
||||
* is undefined if the condition variable's mutex is locked more than once by
|
||||
* the calling thread.
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
*
|
||||
* @note Bare metal profile: This class is not supported.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* @code
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* Mutex mutex;
|
||||
* ConditionVariable cv(mutex);
|
||||
*
|
||||
* // These variables are protected by locking the mutex.
|
||||
* uint32_t work_count = 0;
|
||||
* bool done = false;
|
||||
*
|
||||
* void worker_thread()
|
||||
* {
|
||||
* // Acquire lock on mutex before accessing protected variables and waiting.
|
||||
* mutex.lock();
|
||||
*
|
||||
* while (done == false) {
|
||||
* printf("Worker thread: Count: %lu\r\n", work_count);
|
||||
*
|
||||
* // Wait for main thread to notify the condition variable.
|
||||
* printf("Worker thread: Waiting\r\n");
|
||||
* cv.wait();
|
||||
* }
|
||||
*
|
||||
* printf("Worker: Exiting\r\n");
|
||||
*
|
||||
* // The condition variable acquires the lock when exiting the `wait` function.
|
||||
* // Unlock mutex when exiting the thread.
|
||||
* mutex.unlock();
|
||||
* }
|
||||
*
|
||||
* int main()
|
||||
* {
|
||||
* Thread thread;
|
||||
* thread.start(worker_thread);
|
||||
*
|
||||
* for (int i = 0; i < 5; i++) {
|
||||
* // Acquire lock on mutex before modifying variables and notifying.
|
||||
* mutex.lock();
|
||||
*
|
||||
* // Change count and notify waiters.
|
||||
* work_count++;
|
||||
* printf("Main thread: Set count to: %lu\r\n", work_count);
|
||||
* printf("Main thread: Notifying worker thread\r\n");
|
||||
* cv.notify_all();
|
||||
*
|
||||
* // Mutex must be unlocked before the worker thread can acquire it.
|
||||
* mutex.unlock();
|
||||
*
|
||||
* ThisThread::sleep_for(1000);
|
||||
* }
|
||||
*
|
||||
* // Change done and notify waiters of this.
|
||||
* mutex.lock();
|
||||
* done = true;
|
||||
* cv.notify_all();
|
||||
* mutex.unlock();
|
||||
*
|
||||
* thread.join();
|
||||
*
|
||||
* printf("Main: Exiting\r\n");
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
class ConditionVariable : private mbed::NonCopyable<ConditionVariable> {
|
||||
public:
|
||||
/** Create and initialize a ConditionVariable object.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
ConditionVariable(Mutex &mutex);
|
||||
|
||||
/** Wait for a notification.
|
||||
*
|
||||
* Wait causes the current thread to block until the condition variable
|
||||
* receives a notification from another thread.
|
||||
*
|
||||
* @note - The thread calling this function must be the owner of the
|
||||
* ConditionVariable's mutex, and it must be locked exactly once.
|
||||
*
|
||||
* @note - Spurious notifications can occur, so the caller of this API
|
||||
* should check to make sure the condition the caller is waiting on has
|
||||
* been met.
|
||||
*
|
||||
* @note - The current thread releases the mutex while inside the wait
|
||||
* function and reacquires it upon exiting the function.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* mutex.lock();
|
||||
*
|
||||
* while (!condition_met) {
|
||||
* cond.wait();
|
||||
* }
|
||||
*
|
||||
* function_to_handle_condition();
|
||||
*
|
||||
* mutex.unlock();
|
||||
* @endcode
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
void wait();
|
||||
|
||||
/** Wait for a predicate.
|
||||
*
|
||||
* Wait causes the current thread to block until the predicate is
|
||||
* true.
|
||||
*
|
||||
* @param pred A function-like object such that `pred()` is convertible to bool
|
||||
*
|
||||
* @note - The thread calling this function must be the owner of the
|
||||
* ConditionVariable's mutex, and it must be locked exactly once.
|
||||
*
|
||||
* @note - The current thread releases the mutex while inside the wait
|
||||
* function and reacquires it upon exiting the function.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* extern bool data_available();
|
||||
*
|
||||
* mutex.lock();
|
||||
*
|
||||
* cond.wait(data_available);
|
||||
*
|
||||
* function_to_handle_data();
|
||||
*
|
||||
* mutex.unlock();
|
||||
* @endcode
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
template <typename Predicate>
|
||||
void wait(Predicate pred)
|
||||
{
|
||||
while (!pred()) {
|
||||
wait();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Wait for a notification until the specified time.
|
||||
*
|
||||
* Wait until causes the current thread to block until the condition
|
||||
* variable is notified, or a specific time given by millisec parameter is
|
||||
* reached.
|
||||
*
|
||||
* @param millisec Absolute end time referenced to `Kernel::get_ms_count()`
|
||||
* @return `true` if a timeout occurred, `false` otherwise.
|
||||
*
|
||||
* @note - The thread calling this function must be the owner of the
|
||||
* ConditionVariable's mutex, and it must be locked exactly once.
|
||||
*
|
||||
* @note - Spurious notifications can occur, so the caller of this API
|
||||
* should check to make sure the condition the caller is waiting on has
|
||||
* been met.
|
||||
*
|
||||
* @note - The current thread releases the lock while inside the wait
|
||||
* function and reacquires it upon exiting the function.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* mutex.lock();
|
||||
* uint64_t end_time = Kernel::get_ms_count() + COND_WAIT_TIMEOUT;
|
||||
*
|
||||
* while (!condition_met) {
|
||||
* if (cond.wait_until(end_time)) {
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* if (condition_met) {
|
||||
* function_to_handle_condition();
|
||||
* }
|
||||
*
|
||||
* mutex.unlock();
|
||||
* @endcode
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
* @deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
|
||||
* rather than `Kernel::get_ms_count() + 5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
|
||||
bool wait_until(uint64_t millisec);
|
||||
|
||||
/** Wait for a notification until the specified time.
|
||||
*
|
||||
* Wait until causes the current thread to block until the condition
|
||||
* variable is notified, or a specific time given by millisec parameter is
|
||||
* reached.
|
||||
*
|
||||
* @param abs_time Absolute end time referenced to `Kernel::Clock`
|
||||
* @return `cv_status::timeout` if a timeout occurred, `cv_status::no_timeout` otherwise.
|
||||
*
|
||||
* @note - The thread calling this function must be the owner of the
|
||||
* ConditionVariable's mutex, and it must be locked exactly once.
|
||||
*
|
||||
* @note - Spurious notifications can occur, so the caller of this API
|
||||
* should check to make sure the condition the caller is waiting on has
|
||||
* been met.
|
||||
*
|
||||
* @note - The current thread releases the lock while inside the wait
|
||||
* function and reacquires it upon exiting the function.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* mutex.lock();
|
||||
* Kernel::Clock::time_point end_time = Kernel::Clock::now() + 2s;
|
||||
*
|
||||
* while (!condition_met) {
|
||||
* if (cond.wait_until(end_time) == cv_status::timeout) {
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* if (condition_met) {
|
||||
* function_to_handle_condition();
|
||||
* }
|
||||
*
|
||||
* mutex.unlock();
|
||||
* @endcode
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
cv_status wait_until(Kernel::Clock::time_point abs_time);
|
||||
|
||||
/** Wait for a predicate until the specified time.
|
||||
*
|
||||
* Wait until causes the current thread to block until the predicate is true,
|
||||
* or a specific time given by abs_time parameter is reached.
|
||||
*
|
||||
* @param abs_time Absolute end time referenced to `Kernel::Clock`
|
||||
* @param pred A function-like object such that `pred()` is convertible to bool
|
||||
* @return The state of the predicate
|
||||
*
|
||||
* @note - The thread calling this function must be the owner of the
|
||||
* ConditionVariable's mutex, and it must be locked exactly once.
|
||||
*
|
||||
* @note - The current thread releases the mutex while inside the wait
|
||||
* function and reacquires it upon exiting the function.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* extern bool data_available();
|
||||
*
|
||||
* mutex.lock();
|
||||
*
|
||||
* if (cond.wait_until(Kernel::Clock::now() + 2s, data_available)) {
|
||||
* function_to_handle_data();
|
||||
* }
|
||||
*
|
||||
* mutex.unlock();
|
||||
* @endcode
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
template <class Predicate>
|
||||
bool wait_until(Kernel::Clock::time_point abs_time, Predicate pred)
|
||||
{
|
||||
while (!pred()) {
|
||||
if (wait_until(abs_time) == cv_status::timeout) {
|
||||
return pred();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Wait for a notification or timeout.
|
||||
*
|
||||
* `Wait for` causes the current thread to block until the condition
|
||||
* variable receives a notification from another thread, or the timeout
|
||||
* specified by the millisec parameter is reached.
|
||||
*
|
||||
* @param millisec Timeout value or osWaitForever in case of no timeout.
|
||||
* @return `true` if a timeout occurred, `false` otherwise.
|
||||
*
|
||||
* @note - The thread calling this function must be the owner of the
|
||||
* ConditionVariable's mutex, and it must be locked exactly once.
|
||||
*
|
||||
* @note - Spurious notifications can occur, so the caller of this API
|
||||
* should check to make sure the condition the caller is waiting on has
|
||||
* been met.
|
||||
*
|
||||
* @note - The current thread releases the lock while inside the wait
|
||||
* function and reacquire it upon exiting the function.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* mutex.lock();
|
||||
*
|
||||
* while (!condition_met) {
|
||||
* cond.wait_for(MAX_SLEEP_TIME);
|
||||
* if (!condition_met) {
|
||||
* do_other_work_while_condition_false();
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* if (condition_met) {
|
||||
* function_to_handle_condition();
|
||||
* }
|
||||
*
|
||||
* mutex.unlock();
|
||||
* @endcode
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
* @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
|
||||
bool wait_for(uint32_t millisec);
|
||||
|
||||
/** Wait for a notification or timeout.
|
||||
*
|
||||
* `Wait for` causes the current thread to block until the condition
|
||||
* variable receives a notification from another thread, or the timeout
|
||||
* specified by the millisec parameter is reached.
|
||||
*
|
||||
* @param rel_time Timeout value.
|
||||
* @return `cv_status::timeout` if a timeout occurred, `cv_status::no_timeout` otherwise.
|
||||
*
|
||||
* @note - The thread calling this function must be the owner of the
|
||||
* ConditionVariable's mutex, and it must be locked exactly once.
|
||||
*
|
||||
* @note - Spurious notifications can occur, so the caller of this API
|
||||
* should check to make sure the condition the caller is waiting on has
|
||||
* been met.
|
||||
*
|
||||
* @note - The current thread releases the lock while inside the wait
|
||||
* function and reacquire it upon exiting the function.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* mutex.lock();
|
||||
*
|
||||
* while (!condition_met) {
|
||||
* cond.wait_for(MAX_SLEEP_TIME);
|
||||
* if (!condition_met) {
|
||||
* do_other_work_while_condition_false();
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* if (condition_met) {
|
||||
* function_to_handle_condition();
|
||||
* }
|
||||
*
|
||||
* mutex.unlock();
|
||||
* @endcode
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
cv_status wait_for(Kernel::Clock::duration_u32 rel_time);
|
||||
|
||||
/** Wait for a predicate or timeout.
|
||||
*
|
||||
* `Wait for` causes the current thread to block until the predicate
|
||||
* is true, or the timeout specified by the rel_time parameter is reached.
|
||||
*
|
||||
* @param rel_time Timeout value.
|
||||
* @param pred a function-like object such that `pred()` is convertible to bool
|
||||
* @return The state of the predicate
|
||||
*
|
||||
* @note - The thread calling this function must be the owner of the
|
||||
* ConditionVariable's mutex, and it must be locked exactly once.
|
||||
*
|
||||
* @note - The current thread releases the mutex while inside the wait
|
||||
* function and reacquire it upon exiting the function.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* extern bool data_available();
|
||||
*
|
||||
* mutex.lock();
|
||||
*
|
||||
* if (cond.wait_for(2s, data_available)) {
|
||||
* function_to_handle_data();
|
||||
* }
|
||||
*
|
||||
* mutex.unlock();
|
||||
* @endcode
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
template <class Predicate>
|
||||
bool wait_for(Kernel::Clock::duration rel_time, Predicate pred)
|
||||
{
|
||||
return wait_until(Kernel::Clock::now() + rel_time, std::move(pred));
|
||||
}
|
||||
|
||||
/** Notify one waiter on this condition variable that a condition changed.
|
||||
*
|
||||
* This function unblocks one of the threads waiting for the condition
|
||||
* variable.
|
||||
*
|
||||
* @note - The thread calling this function must be the owner of the
|
||||
* ConditionVariable's mutex.
|
||||
*
|
||||
* @note - The thread that is unblocked on ConditionVariable::notify_one is
|
||||
* undefined if there are multiple waiters.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
void notify_one();
|
||||
|
||||
/** Notify all waiters on this condition variable that a condition changed.
|
||||
*
|
||||
* This function unblocks all of the threads waiting for the condition
|
||||
* variable.
|
||||
*
|
||||
* @note - The thread calling this function must be the owner of the
|
||||
* ConditionVariable's mutex.
|
||||
*
|
||||
* @note - If there are one or more waiters and one or more threads
|
||||
* attempting to acquire the condition variable's mutex the order in which
|
||||
* the mutex is acquired is undefined.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
void notify_all();
|
||||
|
||||
/** ConditionVariable destructor.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
~ConditionVariable();
|
||||
|
||||
#if !defined(DOXYGEN_ONLY)
|
||||
protected:
|
||||
struct Waiter {
|
||||
Waiter();
|
||||
Semaphore sem;
|
||||
Waiter *prev;
|
||||
Waiter *next;
|
||||
bool in_list;
|
||||
};
|
||||
|
||||
static void _add_wait_list(Waiter **wait_list, Waiter *waiter);
|
||||
static void _remove_wait_list(Waiter **wait_list, Waiter *waiter);
|
||||
Mutex &_mutex;
|
||||
Waiter *_wait_list;
|
||||
#endif // !defined(DOXYGEN_ONLY)
|
||||
};
|
||||
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
} // namespace rtos
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,175 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2019 ARM Limited
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef EVENT_FLAG_H
|
||||
#define EVENT_FLAG_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <stdint.h>
|
||||
#include "rtos/Kernel.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos-public-api */
|
||||
/** @{*/
|
||||
|
||||
/**
|
||||
* \defgroup rtos_EventFlags EventFlags class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** The EventFlags class is used to control event flags or wait for event flags other threads control.
|
||||
|
||||
@note
|
||||
EventFlags support 31 flags. The MSB flag is ignored. It is used to return an error code (@a osFlagsError).
|
||||
|
||||
@note
|
||||
Memory considerations: The EventFlags control structures will be created on the current thread's stack, both for the Mbed OS
|
||||
and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
|
||||
*/
|
||||
class EventFlags : private mbed::NonCopyable<EventFlags> {
|
||||
public:
|
||||
/** Create and initialize an EventFlags object.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
EventFlags();
|
||||
|
||||
/** Create and initialize an EventFlags object.
|
||||
|
||||
@param name name to be used for this EventFlags. It has to stay allocated for the lifetime of the thread.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
EventFlags(const char *name);
|
||||
|
||||
/** Set the specified event flags.
|
||||
@param flags the flags that will be set.
|
||||
@return event flags after setting or error code if highest bit set (see @a osFlagsError for details).
|
||||
|
||||
@note This function may be called from ISR context.
|
||||
*/
|
||||
uint32_t set(uint32_t flags);
|
||||
|
||||
/** Clear the specified event flags.
|
||||
@param flags the flags that will be cleared (default: 0x7fffffff -- all flags).
|
||||
@return event flags before clearing or error code if highest bit set (see @a osFlagsError for details).
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
uint32_t clear(uint32_t flags = 0x7fffffff);
|
||||
|
||||
/** Get the currently set event flags.
|
||||
@return current event flags.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
uint32_t get() const;
|
||||
|
||||
/** Wait for all of the specified event flags to become signaled.
|
||||
@param flags the flags to wait for (default: 0 -- no flags).
|
||||
@param millisec timeout value (default: osWaitForever).
|
||||
@param clear clear specified event flags after waiting for them (default: true).
|
||||
@return event flags before clearing or error code if highest bit set (see @a osFlagsError for details).
|
||||
|
||||
@note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
*/
|
||||
uint32_t wait_all(uint32_t flags = 0, uint32_t millisec = osWaitForever, bool clear = true);
|
||||
|
||||
/** Wait for all of the specified event flags to become signaled.
|
||||
@param flags the flags to wait for.
|
||||
@param rel_time timeout value.
|
||||
@param clear clear specified event flags after waiting for them (default: true).
|
||||
@return event flags before clearing or error code if highest bit set (see @a osFlagsError for details).
|
||||
|
||||
@note You may call this function from ISR context if the rel_time parameter is set to 0.
|
||||
*/
|
||||
uint32_t wait_all_for(uint32_t flags, Kernel::Clock::duration_u32 rel_time, bool clear = true);
|
||||
|
||||
/** Wait for all of the specified event flags to become signaled.
|
||||
@param flags the flags to wait for.
|
||||
@param abs_time timeout value.
|
||||
@param clear clear specified event flags after waiting for them (default: true).
|
||||
@return event flags before clearing or error code if highest bit set (see @a osFlagsError for details).
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
uint32_t wait_all_until(uint32_t flags, Kernel::Clock::time_point abs_time, bool clear = true);
|
||||
|
||||
/** Wait for any of the specified event flags to become signaled.
|
||||
@param flags the flags to wait for (default: 0 -- no flags).
|
||||
@param millisec timeout value (default: osWaitForever).
|
||||
@param clear clear specified event flags after waiting for them (default: true).
|
||||
@return event flags before clearing or error code if highest bit set (see @a osFlagsError for details).
|
||||
|
||||
@note This function may be called from ISR context if the millisec parameter is set to 0.
|
||||
*/
|
||||
uint32_t wait_any(uint32_t flags = 0, uint32_t millisec = osWaitForever, bool clear = true);
|
||||
|
||||
/** Wait for any of the specified event flags to become signaled.
|
||||
@param flags the flags to wait for.
|
||||
@param rel_time timeout value.
|
||||
@param clear clear specified event flags after waiting for them (default: true).
|
||||
@return event flags before clearing or error code if highest bit set (see @a osFlagsError for details).
|
||||
|
||||
@note This function may be called from ISR context if the millisec parameter is set to 0.
|
||||
*/
|
||||
uint32_t wait_any_for(uint32_t flags, Kernel::Clock::duration_u32 rel_time, bool clear = true);
|
||||
|
||||
/** Wait for any of the specified event flags to become signaled.
|
||||
@param flags the flags to wait for.
|
||||
@param abs_time timeout value.
|
||||
@param clear clear specified event flags after waiting for them (default: true).
|
||||
@return event flags before clearing or error code if highest bit set (see @a osFlagsError for details).
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
uint32_t wait_any_until(uint32_t flags, Kernel::Clock::time_point abs_time, bool clear = true);
|
||||
|
||||
/** EventFlags destructor.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
~EventFlags();
|
||||
|
||||
private:
|
||||
void constructor(const char *name = nullptr);
|
||||
uint32_t wait_for(uint32_t flags, uint32_t opt, Kernel::Clock::duration_u32 rel_time, bool clear);
|
||||
uint32_t wait_until(uint32_t flags, uint32_t opt, Kernel::Clock::time_point abs_time, bool clear);
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osEventFlagsId_t _id;
|
||||
mbed_rtos_storage_event_flags_t _obj_mem;
|
||||
#else
|
||||
uint32_t _flags;
|
||||
#endif
|
||||
};
|
||||
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,143 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017-2019 ARM Limited
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef KERNEL_H
|
||||
#define KERNEL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <chrono>
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#if !MBED_CONF_RTOS_PRESENT
|
||||
#include "platform/source/mbed_os_timer.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace rtos {
|
||||
|
||||
/** \addtogroup rtos-public-api */
|
||||
/** @{*/
|
||||
|
||||
/** Functions in the Kernel namespace control RTOS kernel information. */
|
||||
namespace Kernel {
|
||||
|
||||
namespace impl {
|
||||
/* Internal integer-returning function.
|
||||
*
|
||||
* ARM EABI means that `time_point`s do not get returned in registers, so
|
||||
* it's worth having the actual exteernal definition return an integer, and only
|
||||
* convert to `time_point` via the inline function `now()`.
|
||||
*/
|
||||
uint64_t get_tick_count();
|
||||
}
|
||||
|
||||
/** Read the current RTOS kernel millisecond tick count.
|
||||
The tick count corresponds to the tick count the RTOS uses for timing
|
||||
purposes. It increments monotonically from 0 at boot, so it effectively
|
||||
never wraps. If the underlying RTOS only provides a 32-bit tick count,
|
||||
this method expands it to 64 bits.
|
||||
@return RTOS kernel current tick count
|
||||
@note Mbed OS always uses millisecond RTOS ticks, and this could only wrap
|
||||
after half a billion years.
|
||||
@note You cannot call this function from ISR context.
|
||||
@deprecated Use `Kernel::Clock::now()` to get a chrono time_point instead of an integer millisecond count.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Use `Kernel::Clock::now()` to get a chrono time_point instead of an integer millisecond count.")
|
||||
uint64_t get_ms_count();
|
||||
|
||||
/** A C++11 chrono TrivialClock for the kernel millisecond tick count
|
||||
*
|
||||
* @note To fit better into the chrono framework, Kernel::Clock uses
|
||||
* std::chrono::milliseconds as its representation, which makes it signed
|
||||
* and at least 45 bits (so it will be int64_t or equivalent).
|
||||
*/
|
||||
struct Clock {
|
||||
Clock() = delete;
|
||||
/* Standard TrivialClock fields */
|
||||
using duration = std::chrono::milliseconds;
|
||||
using rep = duration::rep;
|
||||
using period = duration::period;
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
using time_point = std::chrono::time_point<Clock>;
|
||||
#else
|
||||
/* In non-RTOS builds, the clock maps directly to the underlying clock, and must
|
||||
* indicate that here, so we can do implicit conversion internally.
|
||||
*/
|
||||
using time_point = std::chrono::time_point<mbed::internal::OsClock, duration>;
|
||||
#endif
|
||||
static constexpr bool is_steady = true;
|
||||
static time_point now()
|
||||
{
|
||||
return time_point(duration(impl::get_tick_count()));
|
||||
}
|
||||
/* Extension to make it easy to use 32-bit durations for some APIs, as we historically have,
|
||||
* for efficiency.
|
||||
*/
|
||||
using duration_u32 = std::chrono::duration<uint32_t, period>;
|
||||
|
||||
/** Lock the clock to ensure it stays running; dummy for API compatibility with HighResClock */
|
||||
static void lock()
|
||||
{
|
||||
}
|
||||
|
||||
/** Unlock the clock, allowing it to stop during power saving; dummy for API compatibility with HighResClock */
|
||||
static void unlock()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** Maximum duration for Kernel::Clock::duration_u32-based APIs
|
||||
*
|
||||
* @note As duration_u32-based APIs pass through straight to CMSIS-RTOS, they will
|
||||
* interpret duration_u32(0xFFFFFFFF) as "wait forever". Indicate maximum
|
||||
* wait time of 0xFFFFFFFE for these calls (which is ~49 days).
|
||||
*/
|
||||
constexpr Clock::duration_u32 wait_for_u32_max{osWaitForever - 1};
|
||||
|
||||
/** Magic "wait forever" constant for Kernel::Clock::duration_u32-based APIs
|
||||
*
|
||||
* Many duration_u32-based APIs treat duration_u32(0xFFFFFFFF) as "wait forever".
|
||||
*/
|
||||
constexpr Clock::duration_u32 wait_for_u32_forever{osWaitForever};
|
||||
|
||||
/** Attach a function to be called by the RTOS idle task.
|
||||
@param fptr pointer to the function to be called
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
@note Bare metal profile: This API is not supported.
|
||||
*/
|
||||
void attach_idle_hook(void (*fptr)(void));
|
||||
|
||||
/** Attach a function to be called when a thread terminates.
|
||||
@param fptr pointer to the function to be called
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
@note Bare metal profile: This API is not supported.
|
||||
*/
|
||||
void attach_thread_terminate_hook(void (*fptr)(osThreadId_t id));
|
||||
|
||||
} // namespace Kernel
|
||||
|
||||
/** @}*/
|
||||
|
||||
} // namespace rtos
|
||||
#endif
|
|
@ -0,0 +1,385 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2019 ARM Limited
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef MAIL_H
|
||||
#define MAIL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rtos/Queue.h"
|
||||
#include "rtos/MemoryPool.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "platform/mbed_assert.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#ifndef MBED_NO_GLOBAL_USING_DIRECTIVE
|
||||
using namespace rtos;
|
||||
#endif
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos-public-api */
|
||||
/** @{*/
|
||||
|
||||
/**
|
||||
* \defgroup rtos_Mail Mail class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** The Mail class allows you to control, send, receive or wait for mail.
|
||||
* A mail is a memory block that is sent to a thread or interrupt service routine (ISR).
|
||||
* @tparam T Data type of a single mail message element.
|
||||
* @tparam queue_sz Maximum number of mail messages in queue.
|
||||
*
|
||||
* @note
|
||||
* Memory considerations: The mail data store and control structures are part of this class - they do not (themselves)
|
||||
* allocate memory on the heap, both for the Mbed OS and underlying RTOS objects (static or dynamic RTOS memory
|
||||
* pools are not being used).
|
||||
*
|
||||
* @note
|
||||
* Bare metal profile: This class is not supported.
|
||||
*/
|
||||
template<typename T, uint32_t queue_sz>
|
||||
class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
|
||||
public:
|
||||
/** Create and initialize Mail queue.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
Mail() = default;
|
||||
|
||||
/** Check if the mail queue is empty.
|
||||
*
|
||||
* @return State of queue.
|
||||
* @retval true Mail queue is empty.
|
||||
* @retval false Mail queue contains mail.
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
*/
|
||||
bool empty() const
|
||||
{
|
||||
return _queue.empty();
|
||||
}
|
||||
|
||||
/** Check if the mail queue is full.
|
||||
*
|
||||
* @return State of queue.
|
||||
* @retval true Mail queue is full.
|
||||
* @retval false Mail queue is not full.
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
*/
|
||||
bool full() const
|
||||
{
|
||||
return _queue.full();
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, without blocking.
|
||||
*
|
||||
* @param millisec Not used (see note).
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
* @note If blocking is required, use Mail::try_alloc_for or Mail::try_alloc_until
|
||||
* @deprecated Replaced with try_alloc. In future alloc() will be an untimed blocking call.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_alloc. In future alloc() will be an untimed blocking call.")
|
||||
T *alloc(MBED_UNUSED uint32_t millisec = 0)
|
||||
{
|
||||
return try_alloc();
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, without blocking.
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
* @note If blocking is required, use Mail::try_alloc_for or Mail::try_alloc_until
|
||||
*/
|
||||
T *try_alloc()
|
||||
{
|
||||
return _pool.try_alloc();
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, optionally blocking.
|
||||
*
|
||||
* @param rel_time Timeout value, or Kernel::wait_for_u32_forever.
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
*/
|
||||
T *try_alloc_for(Kernel::Clock::duration_u32 rel_time)
|
||||
{
|
||||
return _pool.try_alloc_for(rel_time);
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, optionally blocking.
|
||||
*
|
||||
* @param millisec Timeout value, or osWaitForever.
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
* @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
|
||||
T *alloc_for(uint32_t millisec)
|
||||
{
|
||||
return try_alloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, blocking.
|
||||
*
|
||||
* @param abs_time Absolute timeout time, referenced to Kernel::Clock.
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
* @note the underlying RTOS may have a limit to the maximum wait time
|
||||
* due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
* wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
* the wait will time out earlier than specified.
|
||||
*/
|
||||
T *try_alloc_until(Kernel::Clock::time_point abs_time)
|
||||
{
|
||||
return _pool.try_alloc_until(abs_time);
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, blocking.
|
||||
*
|
||||
* @param millisec Absolute timeout time, referenced to Kernel::get_ms_count().
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
* @note the underlying RTOS may have a limit to the maximum wait time
|
||||
* due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
* wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
* the wait will time out earlier than specified.
|
||||
* @deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
|
||||
* rather than `Kernel::get_ms_count() + 5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
|
||||
T *alloc_until(uint64_t millisec)
|
||||
{
|
||||
return try_alloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, and set memory block to zero.
|
||||
*
|
||||
* @param millisec Not used (see note).
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
* @note If blocking is required, use Mail::try_calloc_for or Mail::try_calloc_until
|
||||
* @deprecated Replaced with try_calloc. In future calloc() will be an untimed blocking call.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_calloc. In future calloc() will be an untimed blocking call.")
|
||||
T *calloc(MBED_UNUSED uint32_t millisec = 0)
|
||||
{
|
||||
return try_calloc();
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, and set memory block to zero.
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
* @note If blocking is required, use Mail::try_calloc_for or Mail::try_calloc_until
|
||||
*/
|
||||
T *try_calloc()
|
||||
{
|
||||
return _pool.try_calloc();
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, optionally blocking, and set memory block to zero.
|
||||
*
|
||||
* @param rel_time Timeout value, or Kernel::wait_for_u32_forever.
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context if the rel_time parameter is set to 0.
|
||||
*/
|
||||
T *try_calloc_for(Kernel::Clock::duration_u32 rel_time)
|
||||
{
|
||||
return _pool.try_calloc_for(rel_time);
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, optionally blocking, and set memory block to zero.
|
||||
*
|
||||
* @param millisec Timeout value, or osWaitForever.
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
* @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
|
||||
T *calloc_for(uint32_t millisec)
|
||||
{
|
||||
return try_calloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, blocking, and set memory block to zero.
|
||||
*
|
||||
* @param abs_time Absolute timeout time, referenced to Kernel::Clock.
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
* @note the underlying RTOS may have a limit to the maximum wait time
|
||||
* due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
* wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
* the wait will time out earlier than specified.
|
||||
*/
|
||||
T *try_calloc_until(Kernel::Clock::time_point abs_time)
|
||||
{
|
||||
return _pool.try_calloc_until(abs_time);
|
||||
}
|
||||
|
||||
/** Allocate a memory block of type T, blocking, and set memory block to zero.
|
||||
*
|
||||
* @param millisec Absolute timeout time, referenced to Kernel::get_ms_count().
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
* @note the underlying RTOS may have a limit to the maximum wait time
|
||||
* due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
* wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
* the wait will time out earlier than specified.
|
||||
* @deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
|
||||
* rather than `Kernel::get_ms_count() + 5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
|
||||
T *calloc_until(uint64_t millisec)
|
||||
{
|
||||
return try_calloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
|
||||
}
|
||||
|
||||
/** Put a mail in the queue.
|
||||
*
|
||||
* @param mptr Memory block previously allocated with Mail::alloc or Mail::calloc.
|
||||
*
|
||||
* @return Status code that indicates the execution status of the function (osOK on success).
|
||||
* See note.
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
* @note As the mail should have already been allocated, and the memory pool is the same size
|
||||
* as the queue, the put operation should always succeed, despite being implemented with
|
||||
* Queue::try_put - there is room in the queue for every mail from the pool. Therefore
|
||||
* use of the return value is deprecated, and the function will return void in future.
|
||||
*/
|
||||
osStatus put(T *mptr)
|
||||
{
|
||||
bool ok = _queue.try_put(mptr);
|
||||
MBED_ASSERT(ok);
|
||||
return ok ? osOK : osErrorResource;
|
||||
}
|
||||
|
||||
/** Get a mail from the queue.
|
||||
*
|
||||
* @param rel_time Timeout value (default: Kernel::wait_for_u32_forever).
|
||||
*
|
||||
* @return Event that contains mail information and status code. The status code
|
||||
* is stored in the status member:
|
||||
* @a osEventMail Mail successfully received.
|
||||
* @a osOK No mail is available (and no timeout was specified).
|
||||
* @a osEventTimeout No mail has arrived during the given timeout period.
|
||||
* @a osErrorParameter A parameter is invalid or outside of a permitted range.
|
||||
*
|
||||
* @note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
* @deprecated Replaced with try_get and try_get_for. In future get will be an untimed blocking call.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_get and try_get_for. In future get will be an untimed blocking call.")
|
||||
osEvent get(uint32_t millisec = osWaitForever)
|
||||
{
|
||||
osEvent evt = _queue.get(millisec);
|
||||
if (evt.status == osEventMessage) {
|
||||
evt.status = osEventMail;
|
||||
}
|
||||
return evt;
|
||||
}
|
||||
|
||||
/** Get a mail from the queue.
|
||||
*
|
||||
* @return Pointer to received mail, or nullptr if none was received.
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
*/
|
||||
T *try_get()
|
||||
{
|
||||
T *mptr = nullptr;
|
||||
_queue.try_get(&mptr);
|
||||
return mptr;
|
||||
}
|
||||
|
||||
/** Get a mail from the queue.
|
||||
*
|
||||
* @param rel_time Timeout value or Kernel::wait_for_u32_forever.
|
||||
*
|
||||
* @return Pointer to received mail, or nullptr if none was received.
|
||||
*
|
||||
* @note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
*/
|
||||
T *try_get_for(Kernel::Clock::duration_u32 rel_time)
|
||||
{
|
||||
T *mptr = nullptr;
|
||||
_queue.try_get_for(rel_time, &mptr);
|
||||
return mptr;
|
||||
}
|
||||
|
||||
/** Free a memory block from a mail.
|
||||
*
|
||||
* @param mptr Pointer to the memory block that was obtained with Mail::get.
|
||||
*
|
||||
* @return Status code that indicates the execution status of the function (osOK on success).
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
*/
|
||||
osStatus free(T *mptr)
|
||||
{
|
||||
return _pool.free(mptr);
|
||||
}
|
||||
|
||||
private:
|
||||
Queue<T, queue_sz> _queue;
|
||||
MemoryPool<T, queue_sz> _pool;
|
||||
};
|
||||
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,288 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2019 ARM Limited
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef MEMORYPOOL_H
|
||||
#define MEMORYPOOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
#include "platform/mbed_assert.h"
|
||||
#include "Kernel.h"
|
||||
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos-public-api */
|
||||
/** @{*/
|
||||
|
||||
/**
|
||||
* \defgroup rtos_MemoryPool MemoryPool class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Define and manage fixed-size memory pools of objects of a given type.
|
||||
@tparam T data type of a single object (element).
|
||||
@tparam queue_sz maximum number of objects (elements) in the memory pool.
|
||||
|
||||
@note
|
||||
Memory considerations: The memory pool data store and control structures will be created on current thread's stack,
|
||||
both for the mbed OS and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
|
||||
|
||||
@note
|
||||
Bare metal profile: This class is not supported.
|
||||
*/
|
||||
template<typename T, uint32_t pool_sz>
|
||||
class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
|
||||
MBED_STATIC_ASSERT(pool_sz > 0, "Invalid memory pool size. Must be greater than 0.");
|
||||
public:
|
||||
/** Create and Initialize a memory pool.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
MemoryPool()
|
||||
{
|
||||
memset(_pool_mem, 0, sizeof(_pool_mem));
|
||||
osMemoryPoolAttr_t attr = { 0 };
|
||||
attr.mp_mem = _pool_mem;
|
||||
attr.mp_size = sizeof(_pool_mem);
|
||||
attr.cb_mem = &_obj_mem;
|
||||
attr.cb_size = sizeof(_obj_mem);
|
||||
_id = osMemoryPoolNew(pool_sz, sizeof(T), &attr);
|
||||
MBED_ASSERT(_id);
|
||||
}
|
||||
|
||||
/** Destroy a memory pool
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
~MemoryPool()
|
||||
{
|
||||
osMemoryPoolDelete(_id);
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, without blocking.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
@deprecated Replaced with try_alloc. In future alloc() will be an untimed blocking call.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_alloc. In future alloc() will be an untimed blocking call.")
|
||||
T *alloc()
|
||||
{
|
||||
return try_alloc();
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, without blocking.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
T *try_alloc()
|
||||
{
|
||||
return (T *)osMemoryPoolAlloc(_id, 0);
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, optionally blocking.
|
||||
@param millisec timeout value (osWaitForever to wait forever)
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
@deprecated Replaced with `try_alloc_for`. For example use `try_alloc_for(5s)` rather than `alloc_for(5000)`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with `try_alloc_for`. For example use `try_alloc_for(5s)` rather than `alloc_for(5000)`.")
|
||||
T *alloc_for(uint32_t millisec)
|
||||
{
|
||||
return try_alloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, optionally blocking.
|
||||
@param rel_time timeout value (Kernel::wait_for_u32_forever to wait forever)
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context if the rel_time parameter is set to 0.
|
||||
*/
|
||||
T *try_alloc_for(Kernel::Clock::duration_u32 rel_time)
|
||||
{
|
||||
return (T *)osMemoryPoolAlloc(_id, rel_time.count());
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, blocking.
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count().
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the wait will time out earlier than specified.
|
||||
@deprecated Replaced with `try_alloc_until`. For example use `try_alloc_until(Kernel::Clock::now() + 5s)`
|
||||
rather than `alloc_until(Kernel::get_ms_count() + 5000)`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with `try_alloc_until`. For example use `try_alloc_until(Kernel::Clock::now() + 5s)` rather than `alloc_until(Kernel::get_ms_count() + 5000)`.")
|
||||
T *alloc_until(uint64_t millisec)
|
||||
{
|
||||
return try_alloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, blocking.
|
||||
@param abs_time absolute timeout time, referenced to Kernel::Clock.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the wait will time out earlier than specified.
|
||||
*/
|
||||
T *try_alloc_until(Kernel::Clock::time_point abs_time)
|
||||
{
|
||||
Kernel::Clock::time_point now = Kernel::Clock::now();
|
||||
Kernel::Clock::duration_u32 rel_time;
|
||||
if (now >= abs_time) {
|
||||
rel_time = rel_time.zero();
|
||||
} else if (abs_time - now > Kernel::wait_for_u32_max) {
|
||||
rel_time = Kernel::wait_for_u32_max;
|
||||
} else {
|
||||
rel_time = abs_time - now;
|
||||
}
|
||||
return try_alloc_for(rel_time);
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, without blocking, and set memory block to zero.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
@deprecated Replaced with try_calloc. In future calloc() will be an untimed blocking call.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_calloc. In future calloc() will be an untimed blocking call.")
|
||||
T *calloc()
|
||||
{
|
||||
return try_calloc();
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, without blocking, and set memory block to zero.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
T *try_calloc()
|
||||
{
|
||||
T *item = try_alloc();
|
||||
if (item != nullptr) {
|
||||
memset(item, 0, sizeof(T));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, optionally blocking, and set memory block to zero.
|
||||
@param millisec timeout value (osWaitForever to wait forever)
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
@deprecated Replaced with `try_calloc_for`. For example use `try_calloc_for(5s)` rather than `calloc_for(5000)`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with `try_calloc_for`. For example use `try_calloc_for(5s)` rather than `calloc_for(5000)`.")
|
||||
T *calloc_for(uint32_t millisec)
|
||||
{
|
||||
return try_calloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, optionally blocking, and set memory block to zero.
|
||||
@param rel_time timeout value (Kernel::wait_for_u32_forever to wait forever)
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context if the rel_time parameter is set to 0.
|
||||
*/
|
||||
T *try_calloc_for(Kernel::Clock::duration_u32 rel_time)
|
||||
{
|
||||
T *item = try_alloc_for(rel_time);
|
||||
if (item != nullptr) {
|
||||
memset(item, 0, sizeof(T));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, blocking, and set memory block to zero.
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count().
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the wait will time out earlier than specified.
|
||||
@deprecated Replaced with `try_calloc_until`. For example use `try_calloc_until(Kernel::Clock::now() + 5s)`
|
||||
rather than `calloc_until(Kernel::get_ms_count() + 5000)`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with `try_calloc_until`. For example use `try_calloc_until(Kernel::Clock::now() + 5s)` rather than `calloc_until(Kernel::get_ms_count() + 5000)`.")
|
||||
T *calloc_until(uint64_t millisec)
|
||||
{
|
||||
return try_calloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
|
||||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, blocking, and set memory block to zero.
|
||||
@param abs_time absolute timeout time, referenced to Kernel::Clock.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the wait will time out earlier than specified.
|
||||
*/
|
||||
T *try_calloc_until(Kernel::Clock::time_point abs_time)
|
||||
{
|
||||
T *item = try_alloc_until(abs_time);
|
||||
if (item != nullptr) {
|
||||
memset(item, 0, sizeof(T));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/** Free a memory block.
|
||||
@param block address of the allocated memory block to be freed.
|
||||
@return osOK on successful deallocation, osErrorParameter if given memory block id
|
||||
is nullptr or invalid, or osErrorResource if given memory block is in an
|
||||
invalid memory pool state.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
osStatus free(T *block)
|
||||
{
|
||||
return osMemoryPoolFree(_id, block);
|
||||
}
|
||||
|
||||
private:
|
||||
osMemoryPoolId_t _id;
|
||||
char _pool_mem[MBED_RTOS_STORAGE_MEM_POOL_MEM_SIZE(pool_sz, sizeof(T))];
|
||||
mbed_rtos_storage_mem_pool_t _obj_mem;
|
||||
};
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,234 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2019 ARM Limited
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef MUTEX_H
|
||||
#define MUTEX_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "rtos/Kernel.h"
|
||||
|
||||
#include "platform/NonCopyable.h"
|
||||
#include "platform/ScopedLock.h"
|
||||
#include "platform/mbed_toolchain.h"
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos-public-api */
|
||||
/** @{*/
|
||||
|
||||
class Mutex;
|
||||
/** Typedef for the mutex lock
|
||||
*
|
||||
* Usage:
|
||||
* @code
|
||||
* void foo(Mutex &m) {
|
||||
* ScopedMutexLock lock(m);
|
||||
* // Mutex lock protects code in this block
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
typedef mbed::ScopedLock<Mutex> ScopedMutexLock;
|
||||
|
||||
/**
|
||||
* \defgroup rtos_Mutex Mutex class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** The Mutex class is used to synchronize the execution of threads.
|
||||
This is, for example, used to protect access to a shared resource.
|
||||
|
||||
In bare-metal builds, the Mutex class is a dummy, so lock() and unlock() are no-ops.
|
||||
|
||||
@note You cannot use member functions of this class in ISR context. If you require Mutex functionality within
|
||||
ISR handler, consider using @a Semaphore.
|
||||
|
||||
@note
|
||||
Memory considerations: The mutex control structures are created on the current thread's stack, both for the Mbed OS
|
||||
and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
|
||||
*/
|
||||
class Mutex : private mbed::NonCopyable<Mutex> {
|
||||
public:
|
||||
/** Create and Initialize a Mutex object
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
Mutex();
|
||||
|
||||
/** Create and Initialize a Mutex object
|
||||
|
||||
@param name name to be used for this mutex. It has to stay allocated for the lifetime of the thread.
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
Mutex(const char *name);
|
||||
|
||||
/**
|
||||
Wait until a Mutex becomes available.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
void lock();
|
||||
|
||||
/** Try to lock the mutex, and return immediately
|
||||
@return true if the mutex was acquired, false otherwise.
|
||||
@note equivalent to trylock_for(0)
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
bool trylock();
|
||||
|
||||
/** Try to lock the mutex for a specified time
|
||||
@param millisec timeout value.
|
||||
@return true if the mutex was acquired, false otherwise.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the lock attempt will time out earlier than specified.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
|
||||
bool trylock_for(uint32_t millisec);
|
||||
|
||||
/** Try to lock the mutex for a specified time
|
||||
@param rel_time timeout value.
|
||||
@return true if the mutex was acquired, false otherwise.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the lock attempt will time out earlier than specified.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
bool trylock_for(Kernel::Clock::duration_u32 rel_time);
|
||||
|
||||
/** Try to lock the mutex until specified time
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
|
||||
@return true if the mutex was acquired, false otherwise.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the lock attempt will time out earlier than specified.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@deprecated Pass a chrono time_point, not an integer millisecond count. For example use
|
||||
`Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
|
||||
bool trylock_until(uint64_t millisec);
|
||||
|
||||
/** Try to lock the mutex until specified time
|
||||
@param abs_time absolute timeout time, referenced to Kernel::get_ms_count()
|
||||
@return true if the mutex was acquired, false otherwise.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the lock attempt will time out earlier than specified.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
bool trylock_until(Kernel::Clock::time_point abs_time);
|
||||
|
||||
/**
|
||||
Unlock the mutex that has previously been locked by the same thread
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
void unlock();
|
||||
|
||||
/** Get the owner the this mutex
|
||||
@return the current owner of this mutex.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
osThreadId_t get_owner();
|
||||
|
||||
/** Mutex destructor
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
~Mutex();
|
||||
|
||||
private:
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
void constructor(const char *name = nullptr);
|
||||
friend class ConditionVariable;
|
||||
|
||||
osMutexId_t _id;
|
||||
mbed_rtos_storage_mutex_t _obj_mem;
|
||||
uint32_t _count;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !MBED_CONF_RTOS_PRESENT
|
||||
inline Mutex::Mutex()
|
||||
{
|
||||
}
|
||||
|
||||
inline Mutex::Mutex(const char *)
|
||||
{
|
||||
}
|
||||
|
||||
inline Mutex::~Mutex()
|
||||
{
|
||||
}
|
||||
|
||||
inline void Mutex::lock()
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Mutex::trylock()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Mutex::trylock_for(uint32_t)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Mutex::trylock_for(Kernel::Clock::duration_u32)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Mutex::trylock_until(uint64_t)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Mutex::trylock_until(Kernel::Clock::time_point)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Mutex::unlock()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,348 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2019 ARM Limited
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef QUEUE_H
|
||||
#define QUEUE_H
|
||||
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "rtos/Kernel.h"
|
||||
#include "platform/mbed_error.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos-public-api */
|
||||
/** @{*/
|
||||
|
||||
/**
|
||||
* \defgroup rtos_Queue Queue class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** The Queue class represents a collection of objects that are stored first by
|
||||
* order of priority, and then in first-in, first-out (FIFO) order.
|
||||
*
|
||||
* You can use a queue when you need to store data and then access it in the same
|
||||
* order that it has been stored. The order in which you retrieve the data is in
|
||||
* order of descending priority. If multiple elements have the same priority,
|
||||
* they are retrieved in FIFO order.
|
||||
*
|
||||
* The object type stored in the queue can be an integer, pointer or a generic
|
||||
* type given by the template parameter T.
|
||||
*
|
||||
* @tparam T Specifies the type of elements stored in the queue.
|
||||
* @tparam queue_sz Maximum number of messages that you can store in the queue.
|
||||
*
|
||||
* @note Memory considerations: The queue control structures are created on the
|
||||
* current thread's stack, both for the Mbed OS and underlying RTOS
|
||||
* objects (static or dynamic RTOS memory pools are not being used).
|
||||
*
|
||||
* @note Bare metal profile: This class is not supported.
|
||||
*/
|
||||
template<typename T, uint32_t queue_sz>
|
||||
class Queue : private mbed::NonCopyable<Queue<T, queue_sz> > {
|
||||
public:
|
||||
/** Create and initialize a message Queue of objects of the parameterized
|
||||
* type `T` and maximum capacity specified by `queue_sz`.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
Queue()
|
||||
{
|
||||
osMessageQueueAttr_t attr = { 0 };
|
||||
attr.mq_mem = _queue_mem;
|
||||
attr.mq_size = sizeof(_queue_mem);
|
||||
attr.cb_mem = &_obj_mem;
|
||||
attr.cb_size = sizeof(_obj_mem);
|
||||
_id = osMessageQueueNew(queue_sz, sizeof(T *), &attr);
|
||||
MBED_ASSERT(_id);
|
||||
}
|
||||
|
||||
/** Queue destructor
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
~Queue()
|
||||
{
|
||||
osMessageQueueDelete(_id);
|
||||
}
|
||||
|
||||
/** Check if the queue is empty.
|
||||
*
|
||||
* @return True if the queue is empty, false if not
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
*/
|
||||
bool empty() const
|
||||
{
|
||||
return osMessageQueueGetCount(_id) == 0;
|
||||
}
|
||||
|
||||
/** Check if the queue is full.
|
||||
*
|
||||
* @return True if the queue is full, false if not
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
*/
|
||||
bool full() const
|
||||
{
|
||||
return osMessageQueueGetSpace(_id) == 0;
|
||||
}
|
||||
|
||||
/** Get number of queued messages in the queue.
|
||||
*
|
||||
* @return Number of items in the queue
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
*/
|
||||
uint32_t count() const
|
||||
{
|
||||
return osMessageQueueGetCount(_id);
|
||||
}
|
||||
|
||||
/** Inserts the given element to the end of the queue.
|
||||
*
|
||||
* This function puts the message pointed to by `data` into the queue. The
|
||||
* parameter `prio` is used to sort the message according to their priority
|
||||
* (higher numbers indicate higher priority) on insertion.
|
||||
*
|
||||
* The function does not block, and returns immediately if the queue is full.
|
||||
*
|
||||
* @param data Pointer to the element to insert into the queue.
|
||||
* @param prio Priority of the operation or 0 in case of default.
|
||||
* (default: 0)
|
||||
*
|
||||
* @return true if the element was inserted, false otherwise.
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
*/
|
||||
bool try_put(T *data, uint8_t prio = 0)
|
||||
{
|
||||
return try_put_for(Kernel::Clock::duration_u32::zero(), data, prio);
|
||||
}
|
||||
|
||||
/** Inserts the given element to the end of the queue.
|
||||
*
|
||||
* This function puts the message pointed to by `data` into the queue. The
|
||||
* parameter `prio` is used to sort the message according to their priority
|
||||
* (higher numbers indicate higher priority) on insertion.
|
||||
*
|
||||
* The timeout indicated by the parameter `rel_time` specifies how long the
|
||||
* function blocks waiting for the message to be inserted into the
|
||||
* queue.
|
||||
*
|
||||
* The parameter `rel_time` can have the following values:
|
||||
* - When the duration is 0, the function returns instantly. You could use
|
||||
* `try_put` instead.
|
||||
* - When the duration is Kernel::wait_for_u32_forever, the function waits for an
|
||||
* infinite time.
|
||||
* - For all other values, the function waits for the given duration.
|
||||
*
|
||||
* @param rel_time Timeout for the operation to be executed.
|
||||
* @param data Pointer to the element to insert into the queue.
|
||||
* @param prio Priority of the operation or 0 in case of default.
|
||||
* (default: 0)
|
||||
*
|
||||
* @return true if the element was inserted, false otherwise.
|
||||
*
|
||||
* @note You may call this function from ISR context if the rel_time
|
||||
* parameter is set to 0.
|
||||
*
|
||||
*/
|
||||
bool try_put_for(Kernel::Clock::duration_u32 rel_time, T *data, uint8_t prio = 0)
|
||||
{
|
||||
osStatus status = osMessageQueuePut(_id, &data, prio, rel_time.count());
|
||||
return status == osOK;
|
||||
}
|
||||
|
||||
/** Inserts the given element to the end of the queue.
|
||||
*
|
||||
* This function puts the message pointed to by `data` into the queue. The
|
||||
* parameter `prio` is used to sort the message according to their priority
|
||||
* (higher numbers indicate higher priority) on insertion.
|
||||
*
|
||||
* The timeout indicated by the parameter `millisec` specifies how long the
|
||||
* function blocks waiting for the message to be inserted into the
|
||||
* queue.
|
||||
*
|
||||
* The parameter `millisec` can have the following values:
|
||||
* - When the timeout is 0, the function returns instantly.
|
||||
* - When the timeout is osWaitForever, the function waits for an
|
||||
* infinite time.
|
||||
* - For all other values, the function waits for the given number of
|
||||
* milliseconds.
|
||||
*
|
||||
* @param data Pointer to the element to insert into the queue.
|
||||
* @param millisec Timeout for the operation to be executed, or 0 in case
|
||||
* of no timeout.
|
||||
* @param prio Priority of the operation or 0 in case of default.
|
||||
* (default: 0)
|
||||
*
|
||||
* @return Status code that indicates the execution status of the function:
|
||||
* @a osOK The message has been successfully inserted
|
||||
* into the queue.
|
||||
* @a osErrorTimeout The message could not be inserted into the
|
||||
* queue in the given time.
|
||||
* @a osErrorResource The message could not be inserted because
|
||||
* the queue is full.
|
||||
* @a osErrorParameter Internal error or nonzero timeout specified
|
||||
* in an ISR.
|
||||
*
|
||||
* @note You may call this function from ISR context if the millisec
|
||||
* parameter is set to 0.
|
||||
* @deprecated Replaced with try_put and try_put_for. In future put will be an untimed blocking call.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_put and try_put_for. In future put will be an untimed blocking call.")
|
||||
osStatus put(T *data, uint32_t millisec = 0, uint8_t prio = 0)
|
||||
{
|
||||
return osMessageQueuePut(_id, &data, prio, millisec);
|
||||
}
|
||||
|
||||
/** Get a message from the queue.
|
||||
*
|
||||
* This function retrieves a message from the queue. The message is stored
|
||||
* in the location pointed to be the parameter `data_out`.
|
||||
*
|
||||
* The function does not block, and returns immediately if the queue is empty.
|
||||
*
|
||||
* @param[out] data_out Pointer to location to write the element retrieved from the queue.
|
||||
*
|
||||
* @return true if an element was received and written to data_out.
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
*/
|
||||
bool try_get(T **data_out)
|
||||
{
|
||||
return try_get_for(Kernel::Clock::duration_u32::zero(), data_out);
|
||||
}
|
||||
|
||||
/** Get a message or wait for a message from the queue.
|
||||
*
|
||||
* This function retrieves a message from the queue. The message is stored
|
||||
* in the location pointed to be the parameter `data_out`.
|
||||
*
|
||||
* The timeout specified by the parameter `rel_time` specifies how long the
|
||||
* function waits to retrieve the message from the queue.
|
||||
*
|
||||
* The timeout parameter can have the following values:
|
||||
* - When the timeout is 0, the function returns instantly.
|
||||
* - When the timeout is Kernel::wait_for_u32_forever, the function waits
|
||||
* infinite time until the message is retrieved.
|
||||
* - When the timeout is any other value, the function waits for the
|
||||
* specified time before returning a timeout error.
|
||||
*
|
||||
* Messages are retrieved in descending priority order. If two messages
|
||||
* share the same priority level, they are retrieved in first-in, first-out
|
||||
* (FIFO) order.
|
||||
*
|
||||
* @param rel_time Timeout value.
|
||||
* @param[out] data_out Pointer to location to write the element retrieved from the queue.
|
||||
*
|
||||
* @return true if an element was received and written to data_out.
|
||||
*
|
||||
* @note You may call this function from ISR context if the rel_time
|
||||
* parameter is set to 0.
|
||||
*/
|
||||
bool try_get_for(Kernel::Clock::duration_u32 rel_time, T **data_out)
|
||||
{
|
||||
osStatus status = osMessageQueueGet(_id, data_out, nullptr, rel_time.count());
|
||||
return status == osOK;
|
||||
}
|
||||
|
||||
/** Get a message or wait for a message from the queue.
|
||||
*
|
||||
* This function retrieves a message from the queue. The message is stored
|
||||
* in the value field of the returned `osEvent` object.
|
||||
*
|
||||
* The timeout specified by the parameter `millisec` specifies how long the
|
||||
* function waits to retrieve the message from the queue.
|
||||
*
|
||||
* The timeout parameter can have the following values:
|
||||
* - When the timeout is 0, the function returns instantly.
|
||||
* - When the timeout is osWaitForever (default), the function waits
|
||||
* infinite time until the message is retrieved.
|
||||
* - When the timeout is any other value, the function waits for the
|
||||
* specified time before returning a timeout error.
|
||||
*
|
||||
* Messages are retrieved in descending priority order. If two messages
|
||||
* share the same priority level, they are retrieved in first-in, first-out
|
||||
* (FIFO) order.
|
||||
*
|
||||
* @param millisec Timeout value.
|
||||
*
|
||||
* @return Event information that includes the message in event. Message
|
||||
* value and the status code in event.status:
|
||||
* @a osEventMessage Message successfully received.
|
||||
* @a osOK No message is available in the queue, and no
|
||||
* timeout was specified.
|
||||
* @a osEventTimeout No message was received before a timeout
|
||||
* event occurred.
|
||||
* @a osErrorParameter A parameter is invalid or outside of a
|
||||
* permitted range.
|
||||
*
|
||||
* @note You may call this function from ISR context if the millisec
|
||||
* parameter is set to 0.
|
||||
* @deprecated Replaced with try_get and try_get_for. In future get will be an untimed blocking call.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_get and try_get_for. In future get will be an untimed blocking call.")
|
||||
osEvent get(uint32_t millisec = osWaitForever)
|
||||
{
|
||||
osEvent event;
|
||||
T *data = nullptr;
|
||||
osStatus_t res = osMessageQueueGet(_id, &data, nullptr, millisec);
|
||||
|
||||
switch (res) {
|
||||
case osOK:
|
||||
event.status = (osStatus)osEventMessage;
|
||||
event.value.p = data;
|
||||
break;
|
||||
case osErrorResource:
|
||||
event.status = osOK;
|
||||
break;
|
||||
case osErrorTimeout:
|
||||
event.status = (osStatus)osEventTimeout;
|
||||
break;
|
||||
case osErrorParameter:
|
||||
default:
|
||||
event.status = osErrorParameter;
|
||||
break;
|
||||
}
|
||||
event.def.message_id = _id;
|
||||
|
||||
return event;
|
||||
}
|
||||
private:
|
||||
osMessageQueueId_t _id;
|
||||
char _queue_mem[queue_sz * (sizeof(T *) + sizeof(mbed_rtos_storage_message_t))];
|
||||
mbed_rtos_storage_msg_queue_t _obj_mem;
|
||||
};
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
|
||||
} // namespace rtos
|
||||
|
||||
#endif
|
||||
|
||||
#endif // QUEUE_H
|
|
@ -0,0 +1,159 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2019 ARM Limited
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef SEMAPHORE_H
|
||||
#define SEMAPHORE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <chrono>
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "rtos/Kernel.h"
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos-public-api */
|
||||
/** @{*/
|
||||
|
||||
/**
|
||||
* \defgroup rtos_Semaphore Semaphore class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** The Semaphore class is used to manage and protect access to a set of shared resources.
|
||||
*
|
||||
* @note
|
||||
* Memory considerations: The semaphore control structures will be created on current thread's stack, both for the mbed OS
|
||||
* and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
|
||||
*/
|
||||
class Semaphore : private mbed::NonCopyable<Semaphore> {
|
||||
public:
|
||||
/** Create and Initialize a Semaphore object used for managing resources.
|
||||
@param count number of available resources; maximum index value is (count-1). (default: 0).
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
Semaphore(int32_t count = 0);
|
||||
|
||||
/** Create and Initialize a Semaphore object used for managing resources.
|
||||
@param count number of available resources
|
||||
@param max_count maximum number of available resources
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
Semaphore(int32_t count, uint16_t max_count);
|
||||
|
||||
/** Wait until a Semaphore resource becomes available.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
void acquire();
|
||||
|
||||
/** Try to acquire a Semaphore resource, and return immediately
|
||||
@return true if a resource was acquired, false otherwise.
|
||||
@note equivalent to try_acquire_for(0)
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
bool try_acquire();
|
||||
|
||||
/** Wait until a Semaphore resource becomes available.
|
||||
@param millisec timeout value.
|
||||
@return true if a resource was acquired, false otherwise.
|
||||
|
||||
@note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
@deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
|
||||
bool try_acquire_for(uint32_t millisec);
|
||||
|
||||
/** Wait until a Semaphore resource becomes available.
|
||||
@param rel_time timeout value.
|
||||
@return true if a resource was acquired, false otherwise.
|
||||
|
||||
@note You may call this function from ISR context if the rel_time parameter is set to 0.
|
||||
*/
|
||||
bool try_acquire_for(Kernel::Clock::duration_u32 rel_time);
|
||||
|
||||
/** Wait until a Semaphore resource becomes available.
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
|
||||
@return true if a resource was acquired, false otherwise.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the acquire attempt will time out earlier than specified.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@deprecated Pass a chrono time_point, not an integer millisecond count. For example use
|
||||
`Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
|
||||
bool try_acquire_until(uint64_t millisec);
|
||||
|
||||
/** Wait until a Semaphore resource becomes available.
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
|
||||
@return true if a resource was acquired, false otherwise.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the acquire attempt will time out earlier than specified.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
bool try_acquire_until(Kernel::Clock::time_point abs_time);
|
||||
|
||||
/** Release a Semaphore resource that was obtain with Semaphore::acquire.
|
||||
@return status code that indicates the execution status of the function:
|
||||
@a osOK the token has been correctly released.
|
||||
@a osErrorResource the maximum token count has been reached.
|
||||
@a osErrorParameter internal error.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
osStatus release(void);
|
||||
|
||||
/** Semaphore destructor
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
~Semaphore();
|
||||
|
||||
private:
|
||||
void constructor(int32_t count, uint16_t max_count);
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
int32_t _wait(uint32_t millisec);
|
||||
|
||||
osSemaphoreId_t _id;
|
||||
mbed_rtos_storage_semaphore_t _obj_mem;
|
||||
#else
|
||||
static bool semaphore_available(void *);
|
||||
int32_t _count;
|
||||
uint16_t _max_count;
|
||||
#endif
|
||||
};
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,290 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2019 ARM Limited
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef THIS_THREAD_H
|
||||
#define THIS_THREAD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "rtos/Kernel.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos-public-api */
|
||||
/** @{*/
|
||||
|
||||
/**
|
||||
* \defgroup rtos_ThisThread ThisThread namespace
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** The ThisThread namespace allows controlling the current thread.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* #include "mbed.h"
|
||||
* #include "rtos.h"
|
||||
*
|
||||
* Thread thread;
|
||||
* DigitalOut led1(LED1);
|
||||
*
|
||||
* #define STOP_FLAG 1
|
||||
*
|
||||
* // Blink function toggles the led in a long running loop
|
||||
* void blink(DigitalOut *led) {
|
||||
* while (!ThisThread::flags_wait_any_for(STOP_FLAG, 1000)) {
|
||||
* *led = !*led;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Spawns a thread to run blink for 5 seconds
|
||||
* int main() {
|
||||
* thread.start(callback(blink, &led1));
|
||||
* ThisThread::sleep_for(5000);
|
||||
* thread.signal_set(STOP_FLAG);
|
||||
* thread.join();
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
namespace ThisThread {
|
||||
/** Clears the specified Thread Flags of the currently running thread.
|
||||
@param flags specifies the flags of the thread that should be cleared.
|
||||
@return thread flags before clearing.
|
||||
@note You cannot call this function from ISR context.
|
||||
@see Thread::flags_set
|
||||
*/
|
||||
uint32_t flags_clear(uint32_t flags);
|
||||
|
||||
/** Returns the Thread Flags currently set for the currently running thread.
|
||||
@return current thread flags or 0 if not in a valid thread.
|
||||
@note You cannot call this function from ISR context.
|
||||
@see Thread::flags_set
|
||||
*/
|
||||
uint32_t flags_get();
|
||||
|
||||
/** Wait for all of the specified Thread Flags to become signaled for the current thread.
|
||||
@param flags specifies the flags to wait for
|
||||
@param clear whether to clear the specified flags after waiting for them. (default: true)
|
||||
@return actual thread flags before clearing, which will satisfy the wait
|
||||
@note You cannot call this function from ISR context.
|
||||
@see Thread::flags_set
|
||||
*/
|
||||
uint32_t flags_wait_all(uint32_t flags, bool clear = true);
|
||||
|
||||
/** Wait for any of the specified Thread Flags to become signaled for the current thread.
|
||||
@param flags specifies the flags to wait for
|
||||
@param clear whether to clear the specified flags after waiting for them. (default: true)
|
||||
@return actual thread flags before clearing, which will satisfy the wait
|
||||
@note You cannot call this function from ISR context.
|
||||
@see Thread::flags_set
|
||||
*/
|
||||
uint32_t flags_wait_any(uint32_t flags, bool clear = true);
|
||||
|
||||
/** Wait for all of the specified Thread Flags to become signaled for the current thread.
|
||||
@param flags specifies the flags to wait for
|
||||
@param millisec timeout value.
|
||||
@param clear whether to clear the specified flags after waiting for them. (default: true)
|
||||
@return actual thread flags before clearing, which may not satisfy the wait
|
||||
@note You cannot call this function from ISR context.
|
||||
@see Thread::flags_set
|
||||
@deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
|
||||
uint32_t flags_wait_all_for(uint32_t flags, uint32_t millisec, bool clear = true);
|
||||
|
||||
/** Wait for all of the specified Thread Flags to become signaled for the current thread.
|
||||
@param flags specifies the flags to wait for
|
||||
@param rel_time timeout value.
|
||||
@param clear whether to clear the specified flags after waiting for them. (default: true)
|
||||
@return actual thread flags before clearing, which may not satisfy the wait
|
||||
@note You cannot call this function from ISR context.
|
||||
@see Thread::flags_set
|
||||
*/
|
||||
uint32_t flags_wait_all_for(uint32_t flags, Kernel::Clock::duration_u32 rel_time, bool clear = true);
|
||||
|
||||
/** Wait for all of the specified Thread Flags to become signaled for the current thread.
|
||||
@param flags specifies the flags to wait for
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
|
||||
@param clear whether to clear the specified flags after waiting for them. (default: true)
|
||||
@return actual thread flags before clearing, which may not satisfy the wait
|
||||
@note You cannot call this function from ISR context.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the wait will time out earlier than specified.
|
||||
@see Thread::flags_set
|
||||
@deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
|
||||
rather than `Kernel::get_ms_count() + 5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
|
||||
uint32_t flags_wait_all_until(uint32_t flags, uint64_t millisec, bool clear = true);
|
||||
|
||||
/** Wait for all of the specified Thread Flags to become signaled for the current thread.
|
||||
@param flags specifies the flags to wait for
|
||||
@param abs_time absolute timeout time, referenced to Kernel::Clock
|
||||
@param clear whether to clear the specified flags after waiting for them. (default: true)
|
||||
@return actual thread flags before clearing, which may not satisfy the wait
|
||||
@note You cannot call this function from ISR context.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the wait will time out earlier than specified.
|
||||
@see Thread::flags_set
|
||||
*/
|
||||
uint32_t flags_wait_all_until(uint32_t flags, Kernel::Clock::time_point abs_time, bool clear = true);
|
||||
|
||||
/** Wait for any of the specified Thread Flags to become signaled for the current thread.
|
||||
@param flags specifies the flags to wait for
|
||||
@param millisec timeout value.
|
||||
@param clear whether to clear the specified flags after waiting for them. (default: true)
|
||||
@return actual thread flags before clearing, which may not satisfy the wait
|
||||
@note You cannot call this function from ISR context.
|
||||
@see Thread::flags_set
|
||||
@deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
|
||||
uint32_t flags_wait_any_for(uint32_t flags, uint32_t millisec, bool clear = true);
|
||||
|
||||
/** Wait for any of the specified Thread Flags to become signaled for the current thread.
|
||||
@param flags specifies the flags to wait for
|
||||
@param rel_time timeout value.
|
||||
@param clear whether to clear the specified flags after waiting for them. (default: true)
|
||||
@return actual thread flags before clearing, which may not satisfy the wait
|
||||
@note You cannot call this function from ISR context.
|
||||
@see Thread::flags_set
|
||||
*/
|
||||
uint32_t flags_wait_any_for(uint32_t flags, Kernel::Clock::duration_u32 rel_time, bool clear = true);
|
||||
|
||||
/** Wait for any of the specified Thread Flags to become signaled for the current thread.
|
||||
@param flags specifies the flags to wait for
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
|
||||
@param clear whether to clear the specified flags after waiting for them. (default: true)
|
||||
@return actual thread flags before clearing, which may not satisfy the wait
|
||||
@note You cannot call this function from ISR context.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the wait will time out earlier than specified.
|
||||
@see Thread::flags_set
|
||||
@deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
|
||||
rather than `Kernel::get_ms_count() + 5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
|
||||
uint32_t flags_wait_any_until(uint32_t flags, uint64_t millisec, bool clear = true);
|
||||
|
||||
/** Wait for any of the specified Thread Flags to become signaled for the current thread.
|
||||
@param flags specifies the flags to wait for
|
||||
@param abs_time absolute timeout time, referenced to Kernel::Clock
|
||||
@param clear whether to clear the specified flags after waiting for them. (default: true)
|
||||
@return actual thread flags before clearing, which may not satisfy the wait
|
||||
@note You cannot call this function from ISR context.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the wait will time out earlier than specified.
|
||||
@see Thread::flags_set
|
||||
*/
|
||||
uint32_t flags_wait_any_until(uint32_t flags, Kernel::Clock::time_point abs_time, bool clear = true);
|
||||
|
||||
/** Sleep for a specified time period in millisec:
|
||||
@param millisec time delay value
|
||||
@note You cannot call this function from ISR context.
|
||||
@note The equivalent functionality is accessible in C via thread_sleep_for.
|
||||
@deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
|
||||
void sleep_for(uint32_t millisec);
|
||||
|
||||
/** Sleep for a specified time period:
|
||||
@param rel_time time delay value
|
||||
@note You cannot call this function from ISR context.
|
||||
@note The equivalent functionality is accessible in C via thread_sleep_for.
|
||||
*/
|
||||
void sleep_for(Kernel::Clock::duration_u32 rel_time);
|
||||
|
||||
|
||||
/** Sleep until a specified time in millisec
|
||||
The specified time is according to Kernel::get_ms_count().
|
||||
@param millisec absolute time in millisec
|
||||
@note You cannot call this function from ISR context.
|
||||
@note if millisec is equal to or lower than the current tick count, this
|
||||
returns immediately.
|
||||
@note The equivalent functionality is accessible in C via thread_sleep_until.
|
||||
@deprecated Pass a chrono time_point, not an integer millisecond count. For example use
|
||||
`Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
|
||||
void sleep_until(uint64_t millisec);
|
||||
|
||||
/** Sleep until a specified time in millisec
|
||||
The specified time is according to Kernel::Clock.
|
||||
@param abs_time absolute time
|
||||
@note You cannot call this function from ISR context.
|
||||
@note if abs_time is equal to or lower than Kernel::Clock::now(), this
|
||||
returns immediately.
|
||||
@note The equivalent functionality is accessible in C via thread_sleep_until.
|
||||
*/
|
||||
void sleep_until(Kernel::Clock::time_point abs_time);
|
||||
|
||||
/** Pass control to next equal-priority thread that is in state READY.
|
||||
(Higher-priority READY threads would prevent us from running; this
|
||||
will not enable lower-priority threads to run, as we remain READY).
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
void yield();
|
||||
|
||||
/** Get the thread id of the current running thread.
|
||||
@return thread ID for reference by other functions or nullptr in case of error or in ISR context.
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
osThreadId_t get_id();
|
||||
|
||||
/** Get the thread name of the current running thread.
|
||||
@return thread name pointer or nullptr if thread has no name or in case of error.
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
const char *get_name();
|
||||
|
||||
};
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
|
||||
|
||||
namespace internal {
|
||||
/** \addtogroup rtos-internal-api */
|
||||
/** @{*/
|
||||
|
||||
struct flags_check_capture {
|
||||
uint32_t *flags;
|
||||
uint32_t options;
|
||||
uint32_t flags_wanted;
|
||||
uint32_t result;
|
||||
bool match;
|
||||
};
|
||||
|
||||
bool non_rtos_check_flags(void *handle);
|
||||
|
||||
}
|
||||
/** @}*/
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,284 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2019 ARM Limited
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef THREAD_H
|
||||
#define THREAD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "platform/Callback.h"
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
#include "rtos/Semaphore.h"
|
||||
#include "rtos/Mutex.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY) || defined(UNITTEST)
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos-public-api */
|
||||
/** @{*/
|
||||
|
||||
/**
|
||||
* \defgroup rtos_Thread Thread class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** The Thread class allow defining, creating, and controlling thread functions in the system.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* #include "mbed.h"
|
||||
* #include "rtos.h"
|
||||
*
|
||||
* Thread thread;
|
||||
* DigitalOut led1(LED1);
|
||||
* volatile bool running = true;
|
||||
*
|
||||
* // Blink function toggles the led in a long running loop
|
||||
* void blink(DigitalOut *led) {
|
||||
* while (running) {
|
||||
* *led = !*led;
|
||||
* ThisThread::sleep_for(1000);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Spawns a thread to run blink for 5 seconds
|
||||
* int main() {
|
||||
* thread.start(callback(blink, &led1));
|
||||
* ThisThread::sleep_for(5000);
|
||||
* running = false;
|
||||
* thread.join();
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @note
|
||||
* Memory considerations: The thread control structures will be created on current thread's stack, both for the mbed OS
|
||||
* and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
|
||||
* Additionally the stack memory for this thread will be allocated on the heap, if it wasn't supplied to the constructor.
|
||||
*
|
||||
* @note
|
||||
* MBED_TZ_DEFAULT_ACCESS (default:0) flag can be used to change the default access of all user threads in non-secure mode.
|
||||
* MBED_TZ_DEFAULT_ACCESS set to 1, means all non-secure user threads have access to call secure functions.
|
||||
* MBED_TZ_DEFAULT_ACCESS set to 0, means none of the non-secure user thread have access to call secure functions,
|
||||
* to give access to particular thread used overloaded constructor with `tz_module` as argument during thread creation.
|
||||
*
|
||||
* MBED_TZ_DEFAULT_ACCESS is target specific define, should be set in targets.json file for Cortex-M23/M33 devices.
|
||||
*
|
||||
* @note
|
||||
* Bare metal profile: This class is not supported.
|
||||
*/
|
||||
|
||||
class Thread : private mbed::NonCopyable<Thread> {
|
||||
public:
|
||||
/** Allocate a new thread without starting execution
|
||||
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: nullptr).
|
||||
@param name name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: nullptr)
|
||||
|
||||
@note Default value of tz_module will be MBED_TZ_DEFAULT_ACCESS
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
|
||||
Thread(osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = nullptr, const char *name = nullptr)
|
||||
{
|
||||
constructor(priority, stack_size, stack_mem, name);
|
||||
}
|
||||
|
||||
/** Allocate a new thread without starting execution
|
||||
@param tz_module trustzone thread identifier (osThreadAttr_t::tz_module)
|
||||
Context of RTOS threads in non-secure state must be saved when calling secure functions.
|
||||
tz_module ID is used to allocate context memory for threads, and it can be safely set to zero for
|
||||
threads not using secure calls at all. See "TrustZone RTOS Context Management" for more details.
|
||||
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: nullptr).
|
||||
@param name name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: nullptr)
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
|
||||
Thread(uint32_t tz_module, osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = nullptr, const char *name = nullptr)
|
||||
{
|
||||
constructor(tz_module, priority, stack_size, stack_mem, name);
|
||||
}
|
||||
|
||||
|
||||
/** Starts a thread executing the specified function.
|
||||
@param task function to be executed by this thread.
|
||||
@return status code that indicates the execution status of the function.
|
||||
@note a thread can only be started once
|
||||
|
||||
@note You cannot call this function ISR context.
|
||||
*/
|
||||
osStatus start(mbed::Callback<void()> task);
|
||||
|
||||
/** Wait for thread to terminate
|
||||
@return status code that indicates the execution status of the function.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
osStatus join();
|
||||
|
||||
/** Terminate execution of a thread and remove it from Active Threads
|
||||
@return status code that indicates the execution status of the function.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
osStatus terminate();
|
||||
|
||||
/** Set priority of an active thread
|
||||
@param priority new priority value for the thread function.
|
||||
@return status code that indicates the execution status of the function.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
osStatus set_priority(osPriority priority);
|
||||
|
||||
/** Get priority of an active thread
|
||||
@return current priority value of the thread function.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
osPriority get_priority() const;
|
||||
|
||||
/** Set the specified Thread Flags for the thread.
|
||||
@param flags specifies the flags of the thread that should be set.
|
||||
@return thread flags after setting or osFlagsError in case of incorrect parameters.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
uint32_t flags_set(uint32_t flags);
|
||||
|
||||
/** State of the Thread */
|
||||
enum State {
|
||||
Inactive, /**< NOT USED */
|
||||
Ready, /**< Ready to run */
|
||||
Running, /**< Running */
|
||||
WaitingDelay, /**< Waiting for a delay to occur */
|
||||
WaitingJoin, /**< Waiting for thread to join. Only happens when using RTX directly. */
|
||||
WaitingThreadFlag, /**< Waiting for a thread flag to be set */
|
||||
WaitingEventFlag, /**< Waiting for a event flag to be set */
|
||||
WaitingMutex, /**< Waiting for a mutex event to occur */
|
||||
WaitingSemaphore, /**< Waiting for a semaphore event to occur */
|
||||
WaitingMemoryPool, /**< Waiting for a memory pool */
|
||||
WaitingMessageGet, /**< Waiting for message to arrive */
|
||||
WaitingMessagePut, /**< Waiting for message to be send */
|
||||
WaitingInterval, /**< NOT USED */
|
||||
WaitingOr, /**< NOT USED */
|
||||
WaitingAnd, /**< NOT USED */
|
||||
WaitingMailbox, /**< NOT USED (Mail is implemented as MemoryPool and Queue) */
|
||||
|
||||
/* Not in sync with RTX below here */
|
||||
Deleted, /**< The task has been deleted or not started */
|
||||
};
|
||||
|
||||
/** State of this Thread
|
||||
@return the State of this Thread
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
State get_state() const;
|
||||
|
||||
/** Get the total stack memory size for this Thread
|
||||
@return the total stack memory size in bytes
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
uint32_t stack_size() const;
|
||||
|
||||
/** Get the currently unused stack memory for this Thread
|
||||
@return the currently unused stack memory in bytes
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
uint32_t free_stack() const;
|
||||
|
||||
/** Get the currently used stack memory for this Thread
|
||||
@return the currently used stack memory in bytes
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
uint32_t used_stack() const;
|
||||
|
||||
/** Get the maximum stack memory usage to date for this Thread
|
||||
@return the maximum stack memory usage to date in bytes
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
uint32_t max_stack() const;
|
||||
|
||||
/** Get thread name
|
||||
@return thread name or nullptr if the name was not set.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
const char *get_name() const;
|
||||
|
||||
/** Get thread id
|
||||
@return thread ID for reference by other functions.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
osThreadId_t get_id() const;
|
||||
|
||||
/** Thread destructor
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
*/
|
||||
virtual ~Thread();
|
||||
|
||||
private:
|
||||
// Required to share definitions without
|
||||
// delegated constructors
|
||||
void constructor(osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = nullptr,
|
||||
const char *name = nullptr);
|
||||
void constructor(uint32_t tz_module,
|
||||
osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = nullptr,
|
||||
const char *name = nullptr);
|
||||
static void _thunk(void *thread_ptr);
|
||||
|
||||
mbed::Callback<void()> _task;
|
||||
osThreadId_t _tid;
|
||||
osThreadAttr_t _attr;
|
||||
bool _dynamic_stack;
|
||||
bool _finished;
|
||||
Semaphore _join_sem;
|
||||
mutable Mutex _mutex;
|
||||
mbed_rtos_storage_thread_t _obj_mem;
|
||||
};
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,30 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2019 ARM Limited
|
||||
* 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 MBED_RTOS_RTX1_TYPES_H
|
||||
#define MBED_RTOS_RTX1_TYPES_H
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(UNITTEST)
|
||||
|
||||
#include "cmsis_os.h"
|
||||
|
||||
#else
|
||||
|
||||
typedef int32_t osStatus;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,26 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2019 ARM Limited
|
||||
* 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 MBED_RTOS_STORAGE_H
|
||||
#define MBED_RTOS_STORAGE_H
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(UNITTEST)
|
||||
|
||||
#include "mbed_rtx_storage.h"
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,80 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2019, ARM Limited, All Rights Reserved
|
||||
* 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 RTOS_TYPES_H_
|
||||
#define RTOS_TYPES_H_
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY) || defined(UNITTEST)
|
||||
#include "cmsis_os2.h"
|
||||
#else
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \addtogroup rtos-public-api */
|
||||
/** @{*/
|
||||
|
||||
/* Minimal definitions for bare metal form of RTOS */
|
||||
|
||||
// Timeout value.
|
||||
#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value.
|
||||
|
||||
// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait).
|
||||
#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default).
|
||||
#define osFlagsWaitAll 0x00000001U ///< Wait for all flags.
|
||||
#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for.
|
||||
|
||||
// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx).
|
||||
#define osFlagsError 0x80000000U ///< Error indicator.
|
||||
#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1).
|
||||
#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2).
|
||||
#define osFlagsErrorResource 0xFFFFFFFDU ///< osErrorResource (-3).
|
||||
#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4).
|
||||
#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6).
|
||||
|
||||
// Status code values returned by CMSIS-RTOS functions.
|
||||
typedef enum {
|
||||
osOK = 0, ///< Operation completed successfully.
|
||||
osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits.
|
||||
osErrorTimeout = -2, ///< Operation not completed within the timeout period.
|
||||
osErrorResource = -3, ///< Resource not available.
|
||||
osErrorParameter = -4, ///< Parameter error.
|
||||
osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation.
|
||||
osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines.
|
||||
osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization.
|
||||
} osStatus_t;
|
||||
|
||||
|
||||
// \details Thread ID identifies the thread.
|
||||
typedef void *osThreadId_t;
|
||||
|
||||
// Set the specified Thread Flags of a thread.
|
||||
// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
|
||||
// \param[in] flags specifies the flags of the thread that shall be set.
|
||||
// \return thread flags after setting or error code if highest bit set.
|
||||
uint32_t osThreadFlagsSet(osThreadId_t thread_id, uint32_t flags);
|
||||
|
||||
/** @}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* RTOS_TYPES_H_ */
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2012 ARM Limited
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef RTOS_H
|
||||
#define RTOS_H
|
||||
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "rtos/Kernel.h"
|
||||
#include "rtos/Thread.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "rtos/Mutex.h"
|
||||
#include "rtos/Semaphore.h"
|
||||
#include "rtos/Mail.h"
|
||||
#include "rtos/MemoryPool.h"
|
||||
#include "rtos/Queue.h"
|
||||
#include "rtos/EventFlags.h"
|
||||
#include "rtos/ConditionVariable.h"
|
||||
|
||||
|
||||
/** \defgroup rtos-public-api RTOS
|
||||
* \ingroup mbed-os-public
|
||||
*/
|
||||
|
||||
#ifndef MBED_NO_GLOBAL_USING_DIRECTIVE
|
||||
using namespace rtos;
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
# Copyright (c) 2020 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
target_sources(mbed-os PRIVATE
|
||||
mbed_boot.c
|
||||
mbed_rtos_rtx.c
|
||||
mbed_rtx_handlers.c
|
||||
mbed_rtx_idle.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(rtx5)
|
||||
|
||||
if(${MBED_TOOLCHAIN} STREQUAL "GCC_ARM")
|
||||
target_sources(mbed-os
|
||||
PRIVATE
|
||||
TOOLCHAIN_GCC_ARM/mbed_boot_gcc_arm.c
|
||||
)
|
||||
elseif(${MBED_TOOLCHAIN} STREQUAL "ARM")
|
||||
target_sources(mbed-os
|
||||
PRIVATE
|
||||
TOOLCHAIN_ARM_STD/mbed_boot_arm_std.c
|
||||
)
|
||||
elseif(${MBED_TOOLCHAIN} STREQUAL "IAR")
|
||||
target_sources(mbed-os
|
||||
PRIVATE
|
||||
TOOLCHAIN_IAR/mbed_boot_iar.c
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(mbed-os
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
rtx4
|
||||
)
|
|
@ -0,0 +1,76 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
function(_mbed_get_rtx_assembly TOOLCHAIN_DIR)
|
||||
get_property(target_labels GLOBAL PROPERTY MBED_TARGET_LABELS)
|
||||
foreach(key ${target_labels})
|
||||
if(${key} STREQUAL CORTEX_A)
|
||||
set(STARTUP_RTX_FILE TARGET_CORTEX_A/irq_ca.S)
|
||||
elseif(${key} STREQUAL M0)
|
||||
set(STARTUP_RTX_FILE TARGET_M0/irq_cm0.S)
|
||||
elseif(${key} STREQUAL M0P)
|
||||
set(STARTUP_RTX_FILE TARGET_M0P/irq_cm0.S)
|
||||
elseif(${key} STREQUAL M23)
|
||||
set(STARTUP_RTX_FILE TARGET_M23/irq_armv8mbl.S)
|
||||
elseif(${key} STREQUAL M3)
|
||||
set(STARTUP_RTX_FILE TARGET_M3/irq_cm3.S)
|
||||
elseif(${key} STREQUAL M33)
|
||||
set(STARTUP_RTX_FILE TARGET_M33/irq_armv8mbl.S)
|
||||
elseif(${key} STREQUAL RTOS_M4_M7)
|
||||
set(STARTUP_RTX_FILE TARGET_RTOS_M4_M7/irq_cm4f.S)
|
||||
endif()
|
||||
target_sources(mbed-os PRIVATE RTX/Source/${TOOLCHAIN_DIR}/${STARTUP_RTX_FILE})
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(_mbed_add_cortexa_handler_if)
|
||||
get_property(target_labels GLOBAL PROPERTY MBED_TARGET_LABELS)
|
||||
foreach(key ${target_labels})
|
||||
if(${key} STREQUAL CORTEX_A)
|
||||
target_sources(mbed-os PRIVATE RTX/Config/TARGET_CORTEX_A/handlers.c)
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
target_sources(mbed-os PRIVATE Include/cmsis_os2.h)
|
||||
target_sources(mbed-os PRIVATE Include/os_tick.h)
|
||||
|
||||
# Add Cortex A handlers if needed
|
||||
_mbed_add_cortexa_handler_if()
|
||||
|
||||
target_sources(mbed-os PRIVATE RTX/Config/RTX_Config.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Config/RTX_Config.h)
|
||||
target_sources(mbed-os PRIVATE RTX/Include/rtx_evr.h)
|
||||
target_sources(mbed-os PRIVATE RTX/Include/rtx_os.h)
|
||||
|
||||
if(${MBED_TOOLCHAIN} STREQUAL "GCC_ARM")
|
||||
_mbed_get_rtx_assembly(TOOLCHAIN_GCC)
|
||||
elseif(${MBED_TOOLCHAIN} STREQUAL "ARM")
|
||||
_mbed_get_rtx_assembly(TOOLCHAIN_ARM)
|
||||
elseif(${MBED_TOOLCHAIN} STREQUAL "IAR")
|
||||
_mbed_get_rtx_assembly(TOOLCHAIN_IAR)
|
||||
endif()
|
||||
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_core_ca.h)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_core_cm.h)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_delay.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_evflags.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_evr.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_kernel.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_lib.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_lib.h)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_memory.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_mempool.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_msgqueue.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_mutex.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_semaphore.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_system.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_thread.c)
|
||||
target_sources(mbed-os PRIVATE RTX/Source/rtx_timer.c)
|
||||
|
||||
target_sources(mbed-os PRIVATE Source/os_systick.c)
|
||||
target_sources(mbed-os PRIVATE Source/os_tick_ptim.c)
|
||||
|
||||
target_include_directories(mbed-os PUBLIC Include)
|
||||
target_include_directories(mbed-os PUBLIC RTX/Include)
|
||||
target_include_directories(mbed-os PUBLIC RTX/Source)
|
||||
target_include_directories(mbed-os PUBLIC RTX/Config)
|
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) 2020 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
mbed_add_cmake_directory_if_labels("TARGET")
|
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) 2020 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
mbed_add_cmake_directory_if_labels("TARGET")
|
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) 2020 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
mbed_add_cmake_directory_if_labels("TARGET")
|
Loading…
Reference in New Issue