mirror of https://github.com/ARMmbed/mbed-os.git
Add ThisThread
parent
6477b762d1
commit
1330eeecd0
TESTS/mbedmicro-rtos-mbed/threads
|
@ -59,13 +59,13 @@ void increment(counter_t *counter)
|
|||
|
||||
void increment_with_yield(counter_t *counter)
|
||||
{
|
||||
Thread::yield();
|
||||
ThisThread::yield();
|
||||
(*counter)++;
|
||||
}
|
||||
|
||||
void increment_with_wait(counter_t *counter)
|
||||
{
|
||||
Thread::wait(100);
|
||||
ThisThread::sleep_for(100);
|
||||
(*counter)++;
|
||||
}
|
||||
|
||||
|
@ -246,118 +246,128 @@ void test_self_terminate()
|
|||
delete thread;
|
||||
}
|
||||
|
||||
void signal_wait()
|
||||
void flags_wait()
|
||||
{
|
||||
osEvent evt = Thread::signal_wait(0x1);
|
||||
TEST_ASSERT_EQUAL(osEventSignal, evt.status);
|
||||
TEST_ASSERT_EQUAL(0x1, evt.value.signals);
|
||||
uint32_t flags = ThisThread::flags_wait_all(0x1);
|
||||
TEST_ASSERT_EQUAL(0x1, flags);
|
||||
}
|
||||
|
||||
void signal_wait_tout()
|
||||
void flags_wait_tout()
|
||||
{
|
||||
osEvent evt = Thread::signal_wait(0x2, 50);
|
||||
TEST_ASSERT_EQUAL(osEventTimeout, evt.status);
|
||||
uint32_t flags = ThisThread::flags_wait_all_for(0x2, 50);
|
||||
TEST_ASSERT_EQUAL(0x1, flags);
|
||||
}
|
||||
|
||||
void signal_wait_multibit()
|
||||
void flags_wait_multibit()
|
||||
{
|
||||
osEvent evt = Thread::signal_wait(0x1 | 0x2, 50);
|
||||
TEST_ASSERT_EQUAL(osEventSignal, evt.status);
|
||||
TEST_ASSERT_EQUAL(0x3, evt.value.signals);
|
||||
uint32_t flags = ThisThread::flags_wait_all(0x1 | 0x2);
|
||||
TEST_ASSERT_EQUAL(0x3, flags);
|
||||
}
|
||||
|
||||
void signal_wait_multibit_tout()
|
||||
void flags_wait_multibit_any()
|
||||
{
|
||||
osEvent evt = Thread::signal_wait(0x1 | 0x2, 50);
|
||||
TEST_ASSERT_EQUAL(osEventTimeout, evt.status);
|
||||
uint32_t flags = ThisThread::flags_wait_any(0x1 | 0x2);
|
||||
TEST_ASSERT_NOT_EQUAL(0x0, flags);
|
||||
}
|
||||
|
||||
void flags_wait_multibit_tout()
|
||||
{
|
||||
uint32_t flags = ThisThread::flags_wait_all_for(0x1 | 0x2, 50);
|
||||
TEST_ASSERT_NOT_EQUAL(0x3, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
Testing thread signal: wait
|
||||
Testing thread flags: wait
|
||||
Given two threads (A & B) are started
|
||||
when thread A executes @a signal_wait(0x1)
|
||||
and thread B execute @a signal_set(0x1)
|
||||
when thread A executes @a flags_wait_all(0x1)
|
||||
and thread B execute @a flags_set(0x1)
|
||||
then thread A exits the wait and continues execution
|
||||
|
||||
Testing thread signal: timeout
|
||||
Testing thread flags: timeout
|
||||
Given two threads (A & B) are started
|
||||
when thread A executes @a signal_wait(0x1 | 0x2, 50) with a timeout of 50ms
|
||||
and thread B execute @a signal_set(0x2)
|
||||
then thread A keeps waiting for correct signal until it timeouts
|
||||
when thread A executes @a flags_wait_all_for(0x1 | 0x2, 50) with a timeout of 50ms
|
||||
and thread B execute @a flags_set(0x2)
|
||||
then thread A keeps waiting for correct flags until it timeouts
|
||||
|
||||
Testing thread signal: multi-bit
|
||||
Testing thread flags: multi-bit
|
||||
Given two threads (A & B) are started
|
||||
when thread A executes @a signal_wait(0x1 | 0x2)
|
||||
and thread B execute @a signal_set(0x1 | 0x2)
|
||||
when thread A executes @a flags_wait_all(0x1 | 0x2)
|
||||
and thread B execute @a flags_set(0x1 | 0x2)
|
||||
then thread A exits the wait and continues execution
|
||||
|
||||
Testing thread signal: multi-bit timeout
|
||||
Testing thread flags: multi-bit any
|
||||
Given two threads (A & B) are started
|
||||
when thread A executes @a signal_wait(0x1, 50) with a timeout of 50ms
|
||||
and thread B execute @a signal_set(0x2)
|
||||
then thread A keeps waiting for correct signal until it timeouts
|
||||
when thread A executes @a flags_wait_any(0x1 | 0x2)
|
||||
and thread B execute @a flags_set(0x1)
|
||||
then thread A exits the wait and continues execution
|
||||
|
||||
Testing thread flags: multi-bit timeout
|
||||
Given two threads (A & B) are started
|
||||
when thread A executes @a flags_wait_all_for(0x1, 50) with a timeout of 50ms
|
||||
and thread B execute @a flags_set(0x2)
|
||||
then thread A keeps waiting for correct flags until it timeouts
|
||||
*/
|
||||
template <int S, void (*F)()>
|
||||
void test_thread_signal()
|
||||
void test_thread_flags_set()
|
||||
{
|
||||
Thread t_wait(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
|
||||
t_wait.start(callback(F));
|
||||
|
||||
Thread::yield();
|
||||
ThisThread::yield();
|
||||
|
||||
Thread::State state = t_wait.get_state();
|
||||
TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, state);
|
||||
|
||||
int32_t res = t_wait.signal_set(S);
|
||||
int32_t res = t_wait.flags_set(S);
|
||||
|
||||
t_wait.join();
|
||||
}
|
||||
|
||||
void signal_clr()
|
||||
void flags_clear()
|
||||
{
|
||||
Thread::yield();
|
||||
ThisThread::yield();
|
||||
|
||||
int32_t sig = Thread::signal_clr(0x1);
|
||||
int32_t sig = ThisThread::flags_clear(0x1);
|
||||
TEST_ASSERT_EQUAL(0x1, sig);
|
||||
|
||||
/* Signal cleared we should get timeout */
|
||||
osEvent evt = Thread::signal_wait(0x1, 0);
|
||||
TEST_ASSERT_EQUAL(osOK, evt.status);
|
||||
/* Flags cleared we should get timeout */
|
||||
uint32_t flags = ThisThread::flags_wait_all_for(0x1, 0);
|
||||
TEST_ASSERT_EQUAL(0, flags);
|
||||
}
|
||||
|
||||
/** Testing thread signals: signal clear
|
||||
/** Testing thread flags: flags clear
|
||||
|
||||
Given two threads (A & B) are started
|
||||
when thread A executes @a signal_set(0x1)
|
||||
and thread B execute @a signal_clr(0x1)
|
||||
and thread B execute @a signal_wait(0x1, 0)
|
||||
then thread B @a signal_wait status should be osOK indicating a timeout
|
||||
when thread A executes @a flags_set(0x1)
|
||||
and thread B execute @a flags_clear(0x1)
|
||||
and thread B execute @a flags_wait_all_for(0x1, 0)
|
||||
then thread B @a flags_wait_all_for return should be 0 indicating no flags set
|
||||
*/
|
||||
void test_thread_signal_clr()
|
||||
void test_thread_flags_clear()
|
||||
{
|
||||
Thread t_wait(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
|
||||
t_wait.start(callback(signal_clr));
|
||||
t_wait.start(callback(flags_clear));
|
||||
|
||||
int32_t res = t_wait.signal_set(0x1);
|
||||
int32_t res = t_wait.flags_set(0x1);
|
||||
TEST_ASSERT_EQUAL(0x1, res);
|
||||
|
||||
t_wait.join();
|
||||
}
|
||||
|
||||
void thread_wait_signal()
|
||||
void thread_wait_flags()
|
||||
{
|
||||
Thread::signal_wait(0x1);
|
||||
ThisThread::flags_wait_all(0x1);
|
||||
}
|
||||
|
||||
void stack_info()
|
||||
{
|
||||
Thread::signal_wait(0x1);
|
||||
ThisThread::flags_wait_all(0x1);
|
||||
|
||||
thread_wait_signal();
|
||||
thread_wait_flags();
|
||||
|
||||
Thread::signal_wait(0x1);
|
||||
ThisThread::flags_wait_all(0x1);
|
||||
}
|
||||
|
||||
/** Testing thread stack info
|
||||
|
@ -377,26 +387,26 @@ void test_thread_stack_info()
|
|||
Thread t(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
t.start(callback(stack_info));
|
||||
|
||||
Thread::yield();
|
||||
ThisThread::yield();
|
||||
|
||||
TEST_ASSERT_EQUAL(THREAD_STACK_SIZE, t.stack_size());
|
||||
TEST_ASSERT_EQUAL(THREAD_STACK_SIZE, t.free_stack() + t.used_stack());
|
||||
uint32_t last_stack = t.used_stack();
|
||||
|
||||
t.signal_set(0x1);
|
||||
Thread::yield();
|
||||
t.flags_set(0x1);
|
||||
ThisThread::yield();
|
||||
|
||||
TEST_ASSERT_EQUAL(THREAD_STACK_SIZE, t.free_stack() + t.used_stack());
|
||||
TEST_ASSERT(last_stack <= t.used_stack());
|
||||
last_stack = t.used_stack();
|
||||
|
||||
t.signal_set(0x1);
|
||||
Thread::yield();
|
||||
t.flags_set(0x1);
|
||||
ThisThread::yield();
|
||||
|
||||
TEST_ASSERT_EQUAL(THREAD_STACK_SIZE, t.free_stack() + t.used_stack());
|
||||
TEST_ASSERT(last_stack >= t.used_stack());
|
||||
|
||||
t.signal_set(0x1);
|
||||
t.flags_set(0x1);
|
||||
|
||||
t.join();
|
||||
}
|
||||
|
@ -427,9 +437,9 @@ void test_thread_name()
|
|||
{
|
||||
const char tname[] = "Amazing thread";
|
||||
Thread t(osPriorityNormal, THREAD_STACK_SIZE, NULL, tname);
|
||||
t.start(callback(thread_wait_signal));
|
||||
t.start(callback(thread_wait_flags));
|
||||
TEST_ASSERT_EQUAL(strcmp(tname, t.get_name()), 0);
|
||||
t.signal_set(0x1);
|
||||
t.flags_set(0x1);
|
||||
t.join();
|
||||
}
|
||||
|
||||
|
@ -473,7 +483,7 @@ void test_delay()
|
|||
|
||||
t.start(callback(test_delay_thread));
|
||||
|
||||
Thread::yield();
|
||||
ThisThread::yield();
|
||||
|
||||
TEST_ASSERT_EQUAL(Thread::WaitingDelay, t.get_state());
|
||||
|
||||
|
@ -481,33 +491,33 @@ void test_delay()
|
|||
TEST_ASSERT_EQUAL(Thread::Deleted, t.get_state());
|
||||
}
|
||||
|
||||
void test_signal_thread()
|
||||
void test_thread_flags_thread()
|
||||
{
|
||||
Thread::signal_wait(0x1);
|
||||
ThisThread::flags_wait_all(0x1);
|
||||
}
|
||||
|
||||
/** Testing thread states: wait signal
|
||||
/** Testing thread states: wait flags
|
||||
|
||||
Given the thread is running
|
||||
when thread waits for a signal
|
||||
then its state, as reported by @a get_state, is @a WaitingSignal
|
||||
when thread waits for flags
|
||||
then its state, as reported by @a get_state, is @a WaitingThreadFlag
|
||||
*/
|
||||
void test_signal()
|
||||
void test_thread_flags()
|
||||
{
|
||||
Thread t(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
|
||||
t.start(callback(test_signal_thread));
|
||||
t.start(callback(test_thread_flags_thread));
|
||||
|
||||
Thread::yield();
|
||||
ThisThread::yield();
|
||||
|
||||
TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state());
|
||||
|
||||
t.signal_set(0x1);
|
||||
t.flags_set(0x1);
|
||||
}
|
||||
|
||||
void test_evt_flag_thread(osEventFlagsId_t evtflg)
|
||||
void test_evt_flag_thread(EventFlags *evtflg)
|
||||
{
|
||||
osEventFlagsWait(evtflg, 0x1, osFlagsWaitAny, osWaitForever);
|
||||
evtflg->wait_any(0x1);
|
||||
}
|
||||
|
||||
/** Testing thread states: wait evt flag
|
||||
|
@ -519,22 +529,15 @@ void test_evt_flag_thread(osEventFlagsId_t evtflg)
|
|||
void test_evt_flag()
|
||||
{
|
||||
Thread t(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
mbed_rtos_storage_event_flags_t evtflg_mem;
|
||||
osEventFlagsAttr_t evtflg_attr;
|
||||
osEventFlagsId_t evtflg;
|
||||
EventFlags evtflg;
|
||||
|
||||
evtflg_attr.cb_mem = &evtflg_mem;
|
||||
evtflg_attr.cb_size = sizeof(evtflg_mem);
|
||||
evtflg = osEventFlagsNew(&evtflg_attr);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, evtflg);
|
||||
t.start(callback(test_evt_flag_thread, &evtflg));
|
||||
|
||||
t.start(callback(test_evt_flag_thread, evtflg));
|
||||
|
||||
Thread::yield();
|
||||
ThisThread::yield();
|
||||
|
||||
TEST_ASSERT_EQUAL(Thread::WaitingEventFlag, t.get_state());
|
||||
|
||||
osEventFlagsSet(evtflg, 0x1);
|
||||
evtflg.set(0x1);
|
||||
}
|
||||
|
||||
void test_mutex_thread(Mutex *mutex)
|
||||
|
@ -557,7 +560,7 @@ void test_mutex()
|
|||
|
||||
t.start(callback(test_mutex_thread, &mutex));
|
||||
|
||||
Thread::yield();
|
||||
ThisThread::yield();
|
||||
|
||||
TEST_ASSERT_EQUAL(Thread::WaitingMutex, t.get_state());
|
||||
|
||||
|
@ -582,7 +585,7 @@ void test_semaphore()
|
|||
|
||||
t.start(callback(test_semaphore_thread, &sem));
|
||||
|
||||
Thread::yield();
|
||||
ThisThread::yield();
|
||||
|
||||
TEST_ASSERT_EQUAL(Thread::WaitingSemaphore, t.get_state());
|
||||
|
||||
|
@ -607,7 +610,7 @@ void test_msg_get()
|
|||
|
||||
t.start(callback(test_msg_get_thread, &queue));
|
||||
|
||||
Thread::yield();
|
||||
ThisThread::yield();
|
||||
|
||||
TEST_ASSERT_EQUAL(Thread::WaitingMessageGet, t.get_state());
|
||||
|
||||
|
@ -635,7 +638,7 @@ void test_msg_put()
|
|||
|
||||
t.start(callback(test_msg_put_thread, &queue));
|
||||
|
||||
Thread::yield();
|
||||
ThisThread::yield();
|
||||
|
||||
TEST_ASSERT_EQUAL(Thread::WaitingMessagePut, t.get_state());
|
||||
queue.get();
|
||||
|
@ -681,7 +684,7 @@ void test_thread_ext_stack()
|
|||
void test_thread_prio()
|
||||
{
|
||||
Thread t(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
t.start(callback(thread_wait_signal));
|
||||
t.start(callback(thread_wait_flags));
|
||||
|
||||
TEST_ASSERT_EQUAL(osPriorityNormal, t.get_priority());
|
||||
|
||||
|
@ -689,7 +692,7 @@ void test_thread_prio()
|
|||
|
||||
TEST_ASSERT_EQUAL(osPriorityHigh, t.get_priority());
|
||||
|
||||
t.signal_set(0x1);
|
||||
t.flags_set(0x1);
|
||||
t.join();
|
||||
}
|
||||
|
||||
|
@ -726,12 +729,12 @@ static const case_t cases[] = {
|
|||
|
||||
{"Testing thread self terminate", test_self_terminate, DEFAULT_HANDLERS},
|
||||
|
||||
{"Testing thread signals: wait", test_thread_signal<0x1, signal_wait>, DEFAULT_HANDLERS},
|
||||
{"Testing thread signals: timeout", test_thread_signal<0x1, signal_wait_tout>, DEFAULT_HANDLERS},
|
||||
{"Testing thread signals: multi-bit", test_thread_signal<0x3, signal_wait_multibit>, DEFAULT_HANDLERS},
|
||||
{"Testing thread signals: multi-bit timeout", test_thread_signal<0x1, signal_wait_multibit_tout>, DEFAULT_HANDLERS},
|
||||
{"Testing thread signals: signal clear", test_thread_signal_clr, DEFAULT_HANDLERS},
|
||||
|
||||
{"Testing thread flags: wait", test_thread_flags_set<0x1, flags_wait>, DEFAULT_HANDLERS},
|
||||
{"Testing thread flags: timeout", test_thread_flags_set<0x1, flags_wait_tout>, DEFAULT_HANDLERS},
|
||||
{"Testing thread flags: multi-bit all", test_thread_flags_set<0x3, flags_wait_multibit>, DEFAULT_HANDLERS},
|
||||
{"Testing thread flags: multi-bit all timeout", test_thread_flags_set<0x1, flags_wait_multibit_tout>, DEFAULT_HANDLERS},
|
||||
{"Testing thread flags: multi-bit any", test_thread_flags_set<0x1, flags_wait_multibit_any>, DEFAULT_HANDLERS},
|
||||
{"Testing thread flags: flags clear", test_thread_flags_clear, DEFAULT_HANDLERS},
|
||||
|
||||
{"Testing thread stack info", test_thread_stack_info, DEFAULT_HANDLERS},
|
||||
{"Testing thread wait", test_thread_wait, DEFAULT_HANDLERS},
|
||||
|
@ -739,7 +742,7 @@ static const case_t cases[] = {
|
|||
|
||||
{"Testing thread states: deleted", test_deleted, DEFAULT_HANDLERS},
|
||||
{"Testing thread states: wait delay", test_delay, DEFAULT_HANDLERS},
|
||||
{"Testing thread states: wait signal", test_signal, DEFAULT_HANDLERS},
|
||||
{"Testing thread states: wait thread flags", test_thread_flags, DEFAULT_HANDLERS},
|
||||
{"Testing thread states: wait event flag", test_evt_flag, DEFAULT_HANDLERS},
|
||||
{"Testing thread states: wait mutex", test_mutex, DEFAULT_HANDLERS},
|
||||
{"Testing thread states: wait semaphore", test_semaphore, DEFAULT_HANDLERS},
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "rtos/Kernel.h"
|
||||
|
||||
#include "mbed.h"
|
||||
#include "rtos/rtos_idle.h"
|
||||
#include "rtos/rtos_handlers.h"
|
||||
|
||||
namespace rtos {
|
||||
|
||||
|
@ -61,4 +63,14 @@ uint64_t Kernel::get_ms_count()
|
|||
}
|
||||
}
|
||||
|
||||
void Kernel::attach_idle_hook(void (*fptr)(void))
|
||||
{
|
||||
rtos_attach_idle_hook(fptr);
|
||||
}
|
||||
|
||||
void Kernel::attach_thread_terminate_hook(void (*fptr)(osThreadId_t id))
|
||||
{
|
||||
rtos_attach_thread_terminate_hook(fptr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define KERNEL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos */
|
||||
|
@ -43,6 +44,20 @@ namespace Kernel {
|
|||
*/
|
||||
uint64_t get_ms_count();
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
void attach_idle_hook(void (*fptr)(void));
|
||||
|
||||
/** Attach a function to be called when a task is killed
|
||||
@param fptr pointer to the function to be called
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
void attach_thread_terminate_hook(void (*fptr)(osThreadId_t id));
|
||||
|
||||
} // namespace Kernel
|
||||
|
||||
} // namespace rtos
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "mbed_error.h"
|
||||
#include "mbed_interface.h"
|
||||
#include "RTX_Config.h"
|
||||
#include "rtos/rtos_handlers.h"
|
||||
|
||||
#ifdef RTE_Compiler_EventRecorder
|
||||
#include "EventRecorder.h" // Keil::Compiler:Event Recorder
|
||||
|
@ -30,7 +31,20 @@
|
|||
#endif
|
||||
|
||||
extern void rtos_idle_loop(void);
|
||||
extern void thread_terminate_hook(osThreadId_t id);
|
||||
|
||||
static void (*terminate_hook)(osThreadId_t id);
|
||||
|
||||
static void thread_terminate_hook(osThreadId_t id)
|
||||
{
|
||||
if (terminate_hook) {
|
||||
terminate_hook(id);
|
||||
}
|
||||
}
|
||||
|
||||
void rtos_attach_thread_terminate_hook(void (*fptr)(osThreadId_t id))
|
||||
{
|
||||
terminate_hook = fptr;
|
||||
}
|
||||
|
||||
__NO_RETURN void osRtxIdleThread(void *argument)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2012 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include "rtos/ThisThread.h"
|
||||
|
||||
#include "mbed.h"
|
||||
#include "rtos/rtos_idle.h"
|
||||
#include "mbed_assert.h"
|
||||
|
||||
namespace rtos {
|
||||
|
||||
uint32_t ThisThread::flags_clear(uint32_t flags)
|
||||
{
|
||||
flags = osThreadFlagsClear(flags);
|
||||
MBED_ASSERT(!(flags & osFlagsError));
|
||||
return flags;
|
||||
}
|
||||
|
||||
uint32_t ThisThread::flags_get()
|
||||
{
|
||||
return osThreadFlagsGet();
|
||||
}
|
||||
|
||||
static uint32_t flags_wait_for(uint32_t flags, uint32_t millisec, bool clear, uint32_t options)
|
||||
{
|
||||
if (!clear) {
|
||||
options |= osFlagsNoClear;
|
||||
}
|
||||
flags = osThreadFlagsWait(flags, options, millisec);
|
||||
if (flags & osFlagsError) {
|
||||
MBED_ASSERT((flags == osFlagsErrorTimeout && millisec != osWaitForever) ||
|
||||
(flags == osFlagsErrorResource && millisec == 0));
|
||||
flags = ThisThread::flags_get();
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static uint32_t flags_wait_until(uint32_t flags, uint64_t millisec, bool clear, uint32_t options)
|
||||
{
|
||||
uint64_t now = Kernel::get_ms_count();
|
||||
|
||||
uint32_t delay;
|
||||
if (now >= millisec) {
|
||||
delay = 0;
|
||||
} else if (millisec - now >= osWaitForever) {
|
||||
// Documentation permits early return for big offsets
|
||||
delay = osWaitForever - 1;
|
||||
} else {
|
||||
delay = millisec - now;
|
||||
}
|
||||
return flags_wait_for(flags, delay, clear, options);
|
||||
}
|
||||
|
||||
uint32_t ThisThread::flags_wait_all(uint32_t flags, bool clear)
|
||||
{
|
||||
return flags_wait_for(flags, osWaitForever, clear, osFlagsWaitAll);
|
||||
}
|
||||
|
||||
uint32_t ThisThread::flags_wait_all_for(uint32_t flags, uint32_t millisec, bool clear)
|
||||
{
|
||||
return flags_wait_for(flags, millisec, clear, osFlagsWaitAll);
|
||||
}
|
||||
|
||||
uint32_t ThisThread::flags_wait_all_until(uint32_t flags, uint64_t millisec, bool clear)
|
||||
{
|
||||
return flags_wait_until(flags, millisec, clear, osFlagsWaitAll);
|
||||
}
|
||||
|
||||
uint32_t ThisThread::flags_wait_any(uint32_t flags, bool clear)
|
||||
{
|
||||
return flags_wait_for(flags, osWaitForever, clear, osFlagsWaitAny);
|
||||
}
|
||||
|
||||
uint32_t ThisThread::flags_wait_any_for(uint32_t flags, uint32_t millisec, bool clear)
|
||||
{
|
||||
return flags_wait_for(flags, millisec, clear, osFlagsWaitAny);
|
||||
}
|
||||
|
||||
uint32_t ThisThread::flags_wait_any_until(uint32_t flags, uint64_t millisec, bool clear)
|
||||
{
|
||||
return flags_wait_until(flags, millisec, clear, osFlagsWaitAny);
|
||||
}
|
||||
|
||||
void ThisThread::sleep_for(uint32_t millisec)
|
||||
{
|
||||
osStatus_t status = osDelay(millisec);
|
||||
MBED_ASSERT(status == osOK);
|
||||
}
|
||||
|
||||
void ThisThread::sleep_until(uint64_t millisec)
|
||||
{
|
||||
// CMSIS-RTOS 2.1.0 had 64-bit time and osDelayUntil, but that's been revoked.
|
||||
// Limit ourselves to manual implementation assuming a >=32-bit osDelay.
|
||||
|
||||
// 64-bit time doesn't wrap (for half a billion years, at last)
|
||||
// make the effort to loop for unlimited sleep, as it doesn't cost much
|
||||
uint64_t now;
|
||||
|
||||
while ((now = Kernel::get_ms_count()) < millisec) {
|
||||
if (millisec - now > UINT32_MAX) {
|
||||
sleep_for(UINT32_MAX);
|
||||
continue;
|
||||
} else {
|
||||
sleep_for(millisec - now);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThisThread::yield()
|
||||
{
|
||||
osThreadYield();
|
||||
}
|
||||
|
||||
osThreadId_t ThisThread::get_id()
|
||||
{
|
||||
return osThreadGetId();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2018 ARM Limited
|
||||
*
|
||||
* 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 "cmsis_os2.h"
|
||||
#include "mbed_rtos1_types.h"
|
||||
#include "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"
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
/**
|
||||
* \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 or 0 in case of no time-out.
|
||||
@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, 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 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
|
||||
*/
|
||||
uint32_t flags_wait_all_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 millisec timeout value or 0 in case of no time-out.
|
||||
@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, 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 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
|
||||
*/
|
||||
uint32_t flags_wait_any_until(uint32_t flags, uint64_t millisec, 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.
|
||||
*/
|
||||
void sleep_for(uint32_t millisec);
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
void sleep_until(uint64_t millisec);
|
||||
|
||||
/** 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 NULL in case of error or in ISR context.
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
osThreadId_t get_id();
|
||||
|
||||
};
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -20,9 +20,11 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
#include "rtos/Thread.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
|
||||
#include "mbed.h"
|
||||
#include "rtos/rtos_idle.h"
|
||||
#include "rtos/rtos_handlers.h"
|
||||
#include "mbed_assert.h"
|
||||
|
||||
#define ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos))
|
||||
|
@ -33,14 +35,6 @@ MBED_STATIC_ASSERT(ALIGN_UP(1, 8) == 8, "ALIGN_UP macro error");
|
|||
MBED_STATIC_ASSERT(ALIGN_DOWN(7, 8) == 0, "ALIGN_DOWN macro error");
|
||||
MBED_STATIC_ASSERT(ALIGN_DOWN(8, 8) == 8, "ALIGN_DOWN macro error");
|
||||
|
||||
static void (*terminate_hook)(osThreadId_t id) = 0;
|
||||
extern "C" void thread_terminate_hook(osThreadId_t id)
|
||||
{
|
||||
if (terminate_hook != (void (*)(osThreadId_t))NULL) {
|
||||
terminate_hook(id);
|
||||
}
|
||||
}
|
||||
|
||||
namespace rtos {
|
||||
|
||||
#ifndef MBED_TZ_DEFAULT_ACCESS
|
||||
|
@ -195,6 +189,13 @@ osPriority Thread::get_priority()
|
|||
return ret;
|
||||
}
|
||||
|
||||
uint32_t Thread::flags_set(uint32_t flags)
|
||||
{
|
||||
flags = osThreadFlagsSet(_tid, flags);
|
||||
MBED_ASSERT(!(flags & osFlagsError));
|
||||
return flags;
|
||||
}
|
||||
|
||||
int32_t Thread::signal_set(int32_t flags)
|
||||
{
|
||||
return osThreadFlagsSet(_tid, flags);
|
||||
|
@ -338,6 +339,11 @@ const char *Thread::get_name()
|
|||
return _attr.name;
|
||||
}
|
||||
|
||||
osThreadId_t Thread::get_id() const
|
||||
{
|
||||
return _tid;
|
||||
}
|
||||
|
||||
int32_t Thread::signal_clr(int32_t flags)
|
||||
{
|
||||
return osThreadFlagsClear(flags);
|
||||
|
@ -379,37 +385,14 @@ osEvent Thread::signal_wait(int32_t signals, uint32_t millisec)
|
|||
|
||||
osStatus Thread::wait(uint32_t millisec)
|
||||
{
|
||||
return osDelay(millisec);
|
||||
ThisThread::sleep_for(millisec);
|
||||
return osOK;
|
||||
}
|
||||
|
||||
osStatus Thread::wait_until(uint64_t millisec)
|
||||
{
|
||||
// CMSIS-RTOS 2.1.0 and 2.1.1 differ in the time type, which we determine
|
||||
// by looking at the return type of osKernelGetTickCount. We assume
|
||||
// our header at least matches the implementation, so we don't try looking
|
||||
// at the run-time version report. (There's no compile-time version report)
|
||||
if (sizeof osKernelGetTickCount() == sizeof(uint64_t)) {
|
||||
// CMSIS-RTOS 2.1.0 has a 64-bit API. The corresponding RTX 5.2.0 can't
|
||||
// delay more than 0xfffffffe ticks, but there's no limit stated for
|
||||
// the generic API.
|
||||
return osDelayUntil(millisec);
|
||||
} else {
|
||||
// 64-bit time doesn't wrap (for half a billion years, at last)
|
||||
uint64_t now = Kernel::get_ms_count();
|
||||
// Report being late on entry
|
||||
if (now >= millisec) {
|
||||
return osErrorParameter;
|
||||
}
|
||||
// We're about to make a 32-bit delay call, so have at least this limit
|
||||
if (millisec - now > 0xFFFFFFFF) {
|
||||
return osErrorParameter;
|
||||
}
|
||||
// And this may have its own internal limit - we'll find out.
|
||||
// We hope/assume there's no problem with passing
|
||||
// osWaitForever = 0xFFFFFFFF - that value is only specified to have
|
||||
// special meaning for osSomethingWait calls.
|
||||
return osDelay(millisec - now);
|
||||
}
|
||||
ThisThread::sleep_until(millisec);
|
||||
return osOK;
|
||||
}
|
||||
|
||||
osStatus Thread::yield()
|
||||
|
@ -429,7 +412,7 @@ void Thread::attach_idle_hook(void (*fptr)(void))
|
|||
|
||||
void Thread::attach_terminate_hook(void (*fptr)(osThreadId_t id))
|
||||
{
|
||||
terminate_hook = fptr;
|
||||
rtos_attach_thread_terminate_hook(fptr);
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
|
|
|
@ -280,7 +280,6 @@ public:
|
|||
|
||||
/** Wait for thread to terminate
|
||||
@return status code that indicates the execution status of the function.
|
||||
@note not callable from interrupt
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
|
@ -308,12 +307,25 @@ public:
|
|||
*/
|
||||
osPriority get_priority();
|
||||
|
||||
/** 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);
|
||||
|
||||
/** Set the specified Thread Flags for the thread.
|
||||
@param signals specifies the signal flags of the thread that should be set.
|
||||
@return signal flags after setting or osFlagsError in case of incorrect parameters.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
@deprecated Other signal_xxx methods have been deprecated in favour of ThisThread::flags functions.
|
||||
To match this naming scheme, derived from CMSIS-RTOS2, Thread::flags_set is now provided.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.10",
|
||||
"Other signal_xxx methods have been deprecated in favour of ThisThread::flags functions. "
|
||||
"To match this naming scheme, derived from CMSIS-RTOS2, Thread::flags_set is now provided.")
|
||||
int32_t signal_set(int32_t signals);
|
||||
|
||||
/** State of the Thread */
|
||||
|
@ -381,12 +393,23 @@ public:
|
|||
*/
|
||||
const char *get_name();
|
||||
|
||||
/** 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;
|
||||
|
||||
/** Clears the specified Thread Flags of the currently running thread.
|
||||
@param signals specifies the signal flags of the thread that should be cleared.
|
||||
@return signal flags before clearing or osFlagsError in case of incorrect parameters.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@deprecated Static methods only affecting current thread cause confusion. Replaced by ThisThread::flags_clear.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.10",
|
||||
"Static methods only affecting current thread cause confusion. "
|
||||
"Replaced by ThisThread::flags_clear.")
|
||||
static int32_t signal_clr(int32_t signals);
|
||||
|
||||
/** Wait for one or more Thread Flags to become signaled for the current RUNNING thread.
|
||||
|
@ -395,7 +418,12 @@ public:
|
|||
@return event flag information or error code. @note if @a millisec is set to 0 and flag is no set the event carries osOK value.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@deprecated Static methods only affecting current thread cause confusion.
|
||||
Replaced by ThisThread::flags_wait_all, ThisThread::flags_wait_all_for, ThisThread::flags_wait_any and ThisThread:wait_any_for.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.10",
|
||||
"Static methods only affecting current thread cause confusion. "
|
||||
"Replaced by ThisThread::flags_wait_all, ThisThread::flags_wait_all_for, ThisThread::flags_wait_any and ThisThread:wait_any_for.")
|
||||
static osEvent signal_wait(int32_t signals, uint32_t millisec = osWaitForever);
|
||||
|
||||
/** Wait for a specified time period in milliseconds
|
||||
|
@ -406,7 +434,11 @@ public:
|
|||
@return status code that indicates the execution status of the function.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@deprecated Static methods only affecting current thread cause confusion. Replaced by ThisThread::sleep_for.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.10",
|
||||
"Static methods only affecting current thread cause confusion. "
|
||||
"Replaced by ThisThread::sleep_for.")
|
||||
static osStatus wait(uint32_t millisec);
|
||||
|
||||
/** Wait until a specified time in millisec
|
||||
|
@ -422,35 +454,56 @@ public:
|
|||
it may return with an immediate error, or wait for the maximum delay.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@deprecated Static methods only affecting current thread cause confusion. Replaced by ThisThread::sleep_until.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.10",
|
||||
"Static methods only affecting current thread cause confusion. "
|
||||
"Replaced by ThisThread::sleep_until.")
|
||||
static osStatus wait_until(uint64_t millisec);
|
||||
|
||||
/** Pass control to next thread that is in state READY.
|
||||
@return status code that indicates the execution status of the function.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@deprecated Static methods only affecting current thread cause confusion. Replaced by ThisThread::sleep_until.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.10",
|
||||
"Static methods only affecting current thread cause confusion. "
|
||||
"Replaced by ThisThread::yield.")
|
||||
static osStatus yield();
|
||||
|
||||
/** Get the thread id of the current running thread.
|
||||
@return thread ID for reference by other functions or NULL in case of error.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
@deprecated Static methods only affecting current thread cause confusion. Replaced by ThisThread::get_id.
|
||||
Use Thread::get_id for the ID of a specific Thread.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.10",
|
||||
"Static methods only affecting current thread cause confusion. "
|
||||
"Replaced by ThisThread::get_id. Use Thread::get_id for the ID of a specific Thread.")
|
||||
static osThreadId gettid();
|
||||
|
||||
/** 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.
|
||||
@deprecated Static methods affecting system cause confusion. Replaced by Kernel::attach_idle_hook.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.10",
|
||||
"Static methods affecting system cause confusion. "
|
||||
"Replaced by Kernel::attach_idle_hook.")
|
||||
static void attach_idle_hook(void (*fptr)(void));
|
||||
|
||||
/** Attach a function to be called when a task is killed
|
||||
@param fptr pointer to the function to be called
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
@deprecated Static methods affecting system cause confusion. Replaced by Kernel::attach_thread_terminate_hook.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.10",
|
||||
"Static methods affecting system cause confusion. "
|
||||
"Replaced by Kernel::attach_thread_terminate_hook.")
|
||||
static void attach_terminate_hook(void (*fptr)(osThreadId id));
|
||||
|
||||
/** Thread destructor
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "mbed_rtos_storage.h"
|
||||
#include "rtos/Kernel.h"
|
||||
#include "rtos/Thread.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "rtos/Mutex.h"
|
||||
#include "rtos/RtosTimer.h"
|
||||
#include "rtos/Semaphore.h"
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2012 ARM Limited
|
||||
*
|
||||
* 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_HANDLERS_H
|
||||
#define RTOS_HANDLERS_H
|
||||
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \defgroup rtos_handlers RTOS hook functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
@note
|
||||
Sets the hook function called by thread termination
|
||||
@param fptr Hook function pointer.
|
||||
*/
|
||||
void rtos_attach_thread_terminate_hook(void (*fptr)(osThreadId_t id));
|
||||
/** @}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
|
Loading…
Reference in New Issue