Skip to content

Commit ccd1c21

Browse files
rgundinashif
authored andcommitted
lib/cmsis_rtos_v1: Implement support for thread APIs
These APIs allow defining, creating and controlling of thread related functionalities. Signed-off-by: Rajavardhan Gundi <[email protected]>
1 parent d22cd76 commit ccd1c21

File tree

6 files changed

+221
-2
lines changed

6 files changed

+221
-2
lines changed

include/cmsis_rtos_v1/cmsis_os.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666

6767
#include <stdint.h>
6868
#include <stddef.h>
69+
#include <kernel.h>
6970

7071
#ifdef __cplusplus
7172
extern "C"
@@ -166,6 +167,8 @@ typedef struct os_thread_def {
166167
osPriority tpriority; ///< initial thread priority
167168
uint32_t instances; ///< maximum number of instances of that thread function
168169
uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size
170+
void *stack_mem; ///< pointer to array of stack memory
171+
struct k_thread *cm_thread; ///< pointer to k_thread structure
169172
} osThreadDef_t;
170173

171174
/// Timer Definition structure contains timer parameters.
@@ -276,8 +279,10 @@ uint32_t osKernelSysTick (void);
276279
extern const osThreadDef_t os_thread_def_##name
277280
#else // define the object
278281
#define osThreadDef(name, priority, instances, stacksz) \
279-
const osThreadDef_t os_thread_def_##name = \
280-
{ (name), (priority), (instances), (stacksz) }
282+
static K_THREAD_STACK_ARRAY_DEFINE(stacks_##name, instances, CONFIG_CMSIS_THREAD_MAX_STACK_SIZE); \
283+
static struct k_thread cm_thread_##name[instances]; \
284+
static osThreadDef_t os_thread_def_##name = \
285+
{ (name), (priority), (instances), (stacksz), (void *)(stacks_##name), (cm_thread_##name)}
281286
#endif
282287

283288
/// Access a Thread definition.

lib/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ add_subdirectory_if_kconfig(ring_buffer)
88
add_subdirectory_if_kconfig(base64)
99
add_subdirectory(mempool)
1010
add_subdirectory_ifdef(CONFIG_PTHREAD_IPC posix)
11+
add_subdirectory_ifdef(CONFIG_CMSIS_RTOS_V1 cmsis_rtos_v1)
1112
add_subdirectory(rbtree)

lib/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ config BASE64
3131

3232
source "lib/posix/Kconfig"
3333

34+
source "lib/cmsis_rtos_v1/Kconfig"
3435
endmenu

lib/cmsis_rtos_v1/CMakeLists.txt

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
add_library(CMSIS INTERFACE)
3+
4+
target_include_directories(CMSIS INTERFACE ${PROJECT_SOURCE_DIR}/include/cmsis_rtos_v1)
5+
6+
zephyr_library()
7+
zephyr_library_sources_ifdef(CONFIG_CMSIS_RTOS_V1 cmsis_thread.c)
8+
9+
zephyr_library_link_libraries(CMSIS)
10+
target_link_libraries(CMSIS INTERFACE zephyr_interface)

lib/cmsis_rtos_v1/Kconfig

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#
2+
# Copyright (c) 2018 Intel Corporation
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
config CMSIS_RTOS_V1
7+
bool
8+
prompt "CMSIS RTOS v1 API"
9+
default n
10+
help
11+
This enables CMSIS RTOS v1 API support. This is an OS-integration
12+
layer which allows applications using CMSIS RTOS APIs to build on
13+
Zephyr.
14+
15+
if CMSIS_RTOS_V1
16+
config CMSIS_MAX_THREAD_COUNT
17+
int
18+
prompt "Maximum thread count in CMSIS RTOS application"
19+
default 10
20+
range 0 255
21+
help
22+
Mention max number of threads in CMSIS RTOS compliant application.
23+
There's a limitation on the number of threads due to memory
24+
related constraints.
25+
26+
config CMSIS_THREAD_MAX_STACK_SIZE
27+
int
28+
prompt "Max stack size threads can be allocated in CMSIS RTOS application"
29+
default 512
30+
help
31+
Mention max stack size threads can be allocated in CMSIS RTOS application.
32+
33+
config NUM_PREEMPT_PRIORITIES
34+
int
35+
default 7
36+
endif

lib/cmsis_rtos_v1/cmsis_thread.c

+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Copyright (c) 2018 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <kernel_structs.h>
8+
#include <atomic.h>
9+
#include <cmsis_os.h>
10+
11+
static inline int _is_thread_cmsis_inactive(struct k_thread *thread)
12+
{
13+
u8_t state = thread->base.thread_state;
14+
15+
return state & (_THREAD_PRESTART | _THREAD_DEAD);
16+
}
17+
18+
static inline s32_t zephyr_to_cmsis_priority(u32_t z_prio)
19+
{
20+
return(osPriorityRealtime - z_prio);
21+
}
22+
23+
static inline u32_t cmsis_to_zephyr_priority(s32_t c_prio)
24+
{
25+
return(osPriorityRealtime - c_prio);
26+
}
27+
28+
static void zephyr_thread_wrapper(void *arg1, void *arg2, void *arg3)
29+
{
30+
void * (*fun_ptr)(void *) = arg3;
31+
32+
fun_ptr(arg1);
33+
}
34+
35+
/**
36+
* @brief Create a new thread.
37+
*/
38+
osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *arg)
39+
{
40+
struct k_thread *cm_thread;
41+
u32_t prio;
42+
k_tid_t tid;
43+
u32_t stacksz;
44+
45+
k_thread_stack_t
46+
(*stk_ptr)[K_THREAD_STACK_LEN(CONFIG_CMSIS_THREAD_MAX_STACK_SIZE)];
47+
48+
__ASSERT(thread_def->stacksize >= 0 &&
49+
thread_def->stacksize <= CONFIG_CMSIS_THREAD_MAX_STACK_SIZE,
50+
"invalid stack size\n");
51+
52+
if (thread_def->instances == 0) {
53+
return NULL;
54+
}
55+
56+
if (_is_in_isr()) {
57+
return NULL;
58+
}
59+
60+
stacksz = thread_def->stacksize;
61+
if (stacksz == 0) {
62+
stacksz = CONFIG_CMSIS_THREAD_MAX_STACK_SIZE;
63+
}
64+
65+
cm_thread = thread_def->cm_thread;
66+
atomic_dec((atomic_t *)&thread_def->instances);
67+
stk_ptr = thread_def->stack_mem;
68+
prio = cmsis_to_zephyr_priority(thread_def->tpriority);
69+
70+
tid = k_thread_create(&cm_thread[thread_def->instances],
71+
stk_ptr[thread_def->instances], stacksz,
72+
(k_thread_entry_t)zephyr_thread_wrapper,
73+
(void *)arg, NULL, thread_def->pthread,
74+
prio, 0, K_NO_WAIT);
75+
76+
return ((osThreadId)tid);
77+
}
78+
79+
/**
80+
* @brief Return the thread ID of the current running thread.
81+
*/
82+
osThreadId osThreadGetId(void)
83+
{
84+
if (_is_in_isr()) {
85+
return NULL;
86+
}
87+
88+
return (osThreadId)k_current_get();
89+
}
90+
91+
/**
92+
* @brief Get current priority of an active thread.
93+
*/
94+
osPriority osThreadGetPriority(osThreadId thread_id)
95+
{
96+
k_tid_t thread = (k_tid_t)thread_id;
97+
u32_t priority;
98+
99+
if (_is_in_isr()) {
100+
return osPriorityError;
101+
}
102+
103+
priority = k_thread_priority_get(thread);
104+
return zephyr_to_cmsis_priority(priority);
105+
}
106+
107+
/**
108+
* @brief Change priority of an active thread.
109+
*/
110+
osStatus osThreadSetPriority(osThreadId thread_id, osPriority priority)
111+
{
112+
if (thread_id == NULL) {
113+
return osErrorParameter;
114+
}
115+
116+
if (_is_in_isr()) {
117+
return osErrorISR;
118+
}
119+
120+
if (priority < osPriorityIdle || priority > osPriorityRealtime) {
121+
return osErrorValue;
122+
}
123+
124+
if (_is_thread_cmsis_inactive((k_tid_t)thread_id)) {
125+
return osErrorResource;
126+
}
127+
128+
k_thread_priority_set((k_tid_t)thread_id,
129+
cmsis_to_zephyr_priority(priority));
130+
131+
return osOK;
132+
}
133+
134+
/**
135+
* @brief Terminate execution of a thread.
136+
*/
137+
osStatus osThreadTerminate(osThreadId thread_id)
138+
{
139+
if (thread_id == NULL) {
140+
return osErrorParameter;
141+
}
142+
143+
if (_is_in_isr()) {
144+
return osErrorISR;
145+
}
146+
147+
if (_is_thread_cmsis_inactive((k_tid_t)thread_id)) {
148+
return osErrorResource;
149+
}
150+
151+
k_thread_abort((k_tid_t)thread_id);
152+
return osOK;
153+
}
154+
155+
/**
156+
* @brief Pass control to next thread that is in READY state.
157+
*/
158+
osStatus osThreadYield(void)
159+
{
160+
if (_is_in_isr()) {
161+
return osErrorISR;
162+
}
163+
164+
k_yield();
165+
return osOK;
166+
}

0 commit comments

Comments
 (0)