Skip to content

Commit 1330eee

Browse files
committed
Add ThisThread
1 parent 6477b76 commit 1330eee

File tree

10 files changed

+597
-134
lines changed

10 files changed

+597
-134
lines changed

TESTS/mbedmicro-rtos-mbed/threads/main.cpp

Lines changed: 99 additions & 96 deletions
Large diffs are not rendered by default.

rtos/Kernel.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "rtos/Kernel.h"
2424

2525
#include "mbed.h"
26+
#include "rtos/rtos_idle.h"
27+
#include "rtos/rtos_handlers.h"
2628

2729
namespace rtos {
2830

@@ -61,4 +63,14 @@ uint64_t Kernel::get_ms_count()
6163
}
6264
}
6365

66+
void Kernel::attach_idle_hook(void (*fptr)(void))
67+
{
68+
rtos_attach_idle_hook(fptr);
69+
}
70+
71+
void Kernel::attach_thread_terminate_hook(void (*fptr)(osThreadId_t id))
72+
{
73+
rtos_attach_thread_terminate_hook(fptr);
74+
}
75+
6476
}

rtos/Kernel.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define KERNEL_H
2424

2525
#include <stdint.h>
26+
#include "cmsis_os2.h"
2627

2728
namespace rtos {
2829
/** \addtogroup rtos */
@@ -43,6 +44,20 @@ namespace Kernel {
4344
*/
4445
uint64_t get_ms_count();
4546

47+
/** Attach a function to be called by the RTOS idle task
48+
@param fptr pointer to the function to be called
49+
50+
@note You may call this function from ISR context.
51+
*/
52+
void attach_idle_hook(void (*fptr)(void));
53+
54+
/** Attach a function to be called when a task is killed
55+
@param fptr pointer to the function to be called
56+
57+
@note You may call this function from ISR context.
58+
*/
59+
void attach_thread_terminate_hook(void (*fptr)(osThreadId_t id));
60+
4661
} // namespace Kernel
4762

4863
} // namespace rtos

rtos/TARGET_CORTEX/mbed_rtx_handlers.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "mbed_error.h"
2222
#include "mbed_interface.h"
2323
#include "RTX_Config.h"
24+
#include "rtos/rtos_handlers.h"
2425

2526
#ifdef RTE_Compiler_EventRecorder
2627
#include "EventRecorder.h" // Keil::Compiler:Event Recorder
@@ -30,7 +31,20 @@
3031
#endif
3132

3233
extern void rtos_idle_loop(void);
33-
extern void thread_terminate_hook(osThreadId_t id);
34+
35+
static void (*terminate_hook)(osThreadId_t id);
36+
37+
static void thread_terminate_hook(osThreadId_t id)
38+
{
39+
if (terminate_hook) {
40+
terminate_hook(id);
41+
}
42+
}
43+
44+
void rtos_attach_thread_terminate_hook(void (*fptr)(osThreadId_t id))
45+
{
46+
terminate_hook = fptr;
47+
}
3448

3549
__NO_RETURN void osRtxIdleThread(void *argument)
3650
{

rtos/ThisThread.cpp

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2012 ARM Limited
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
#define __STDC_LIMIT_MACROS
24+
#include "rtos/ThisThread.h"
25+
26+
#include "mbed.h"
27+
#include "rtos/rtos_idle.h"
28+
#include "mbed_assert.h"
29+
30+
namespace rtos {
31+
32+
uint32_t ThisThread::flags_clear(uint32_t flags)
33+
{
34+
flags = osThreadFlagsClear(flags);
35+
MBED_ASSERT(!(flags & osFlagsError));
36+
return flags;
37+
}
38+
39+
uint32_t ThisThread::flags_get()
40+
{
41+
return osThreadFlagsGet();
42+
}
43+
44+
static uint32_t flags_wait_for(uint32_t flags, uint32_t millisec, bool clear, uint32_t options)
45+
{
46+
if (!clear) {
47+
options |= osFlagsNoClear;
48+
}
49+
flags = osThreadFlagsWait(flags, options, millisec);
50+
if (flags & osFlagsError) {
51+
MBED_ASSERT((flags == osFlagsErrorTimeout && millisec != osWaitForever) ||
52+
(flags == osFlagsErrorResource && millisec == 0));
53+
flags = ThisThread::flags_get();
54+
}
55+
56+
return flags;
57+
}
58+
59+
static uint32_t flags_wait_until(uint32_t flags, uint64_t millisec, bool clear, uint32_t options)
60+
{
61+
uint64_t now = Kernel::get_ms_count();
62+
63+
uint32_t delay;
64+
if (now >= millisec) {
65+
delay = 0;
66+
} else if (millisec - now >= osWaitForever) {
67+
// Documentation permits early return for big offsets
68+
delay = osWaitForever - 1;
69+
} else {
70+
delay = millisec - now;
71+
}
72+
return flags_wait_for(flags, delay, clear, options);
73+
}
74+
75+
uint32_t ThisThread::flags_wait_all(uint32_t flags, bool clear)
76+
{
77+
return flags_wait_for(flags, osWaitForever, clear, osFlagsWaitAll);
78+
}
79+
80+
uint32_t ThisThread::flags_wait_all_for(uint32_t flags, uint32_t millisec, bool clear)
81+
{
82+
return flags_wait_for(flags, millisec, clear, osFlagsWaitAll);
83+
}
84+
85+
uint32_t ThisThread::flags_wait_all_until(uint32_t flags, uint64_t millisec, bool clear)
86+
{
87+
return flags_wait_until(flags, millisec, clear, osFlagsWaitAll);
88+
}
89+
90+
uint32_t ThisThread::flags_wait_any(uint32_t flags, bool clear)
91+
{
92+
return flags_wait_for(flags, osWaitForever, clear, osFlagsWaitAny);
93+
}
94+
95+
uint32_t ThisThread::flags_wait_any_for(uint32_t flags, uint32_t millisec, bool clear)
96+
{
97+
return flags_wait_for(flags, millisec, clear, osFlagsWaitAny);
98+
}
99+
100+
uint32_t ThisThread::flags_wait_any_until(uint32_t flags, uint64_t millisec, bool clear)
101+
{
102+
return flags_wait_until(flags, millisec, clear, osFlagsWaitAny);
103+
}
104+
105+
void ThisThread::sleep_for(uint32_t millisec)
106+
{
107+
osStatus_t status = osDelay(millisec);
108+
MBED_ASSERT(status == osOK);
109+
}
110+
111+
void ThisThread::sleep_until(uint64_t millisec)
112+
{
113+
// CMSIS-RTOS 2.1.0 had 64-bit time and osDelayUntil, but that's been revoked.
114+
// Limit ourselves to manual implementation assuming a >=32-bit osDelay.
115+
116+
// 64-bit time doesn't wrap (for half a billion years, at last)
117+
// make the effort to loop for unlimited sleep, as it doesn't cost much
118+
uint64_t now;
119+
120+
while ((now = Kernel::get_ms_count()) < millisec) {
121+
if (millisec - now > UINT32_MAX) {
122+
sleep_for(UINT32_MAX);
123+
continue;
124+
} else {
125+
sleep_for(millisec - now);
126+
break;
127+
}
128+
}
129+
}
130+
131+
void ThisThread::yield()
132+
{
133+
osThreadYield();
134+
}
135+
136+
osThreadId_t ThisThread::get_id()
137+
{
138+
return osThreadGetId();
139+
}
140+
141+
}

0 commit comments

Comments
 (0)