Browse Source

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 <rajavardhan.gundi@intel.com>
pull/9414/head
Rajavardhan Gundi 7 years ago committed by Anas Nashif
parent
commit
ccd1c21824
  1. 9
      include/cmsis_rtos_v1/cmsis_os.h
  2. 1
      lib/CMakeLists.txt
  3. 1
      lib/Kconfig
  4. 10
      lib/cmsis_rtos_v1/CMakeLists.txt
  5. 36
      lib/cmsis_rtos_v1/Kconfig
  6. 166
      lib/cmsis_rtos_v1/cmsis_thread.c

9
include/cmsis_rtos_v1/cmsis_os.h

@ -66,6 +66,7 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <kernel.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
@ -166,6 +167,8 @@ typedef struct os_thread_def {
osPriority tpriority; ///< initial thread priority osPriority tpriority; ///< initial thread priority
uint32_t instances; ///< maximum number of instances of that thread function uint32_t instances; ///< maximum number of instances of that thread function
uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size
void *stack_mem; ///< pointer to array of stack memory
struct k_thread *cm_thread; ///< pointer to k_thread structure
} osThreadDef_t; } osThreadDef_t;
/// Timer Definition structure contains timer parameters. /// Timer Definition structure contains timer parameters.
@ -276,8 +279,10 @@ uint32_t osKernelSysTick (void);
extern const osThreadDef_t os_thread_def_##name extern const osThreadDef_t os_thread_def_##name
#else // define the object #else // define the object
#define osThreadDef(name, priority, instances, stacksz) \ #define osThreadDef(name, priority, instances, stacksz) \
const osThreadDef_t os_thread_def_##name = \ static K_THREAD_STACK_ARRAY_DEFINE(stacks_##name, instances, CONFIG_CMSIS_THREAD_MAX_STACK_SIZE); \
{ (name), (priority), (instances), (stacksz) } static struct k_thread cm_thread_##name[instances]; \
static osThreadDef_t os_thread_def_##name = \
{ (name), (priority), (instances), (stacksz), (void *)(stacks_##name), (cm_thread_##name)}
#endif #endif
/// Access a Thread definition. /// Access a Thread definition.

1
lib/CMakeLists.txt

@ -8,4 +8,5 @@ add_subdirectory_if_kconfig(ring_buffer)
add_subdirectory_if_kconfig(base64) add_subdirectory_if_kconfig(base64)
add_subdirectory(mempool) add_subdirectory(mempool)
add_subdirectory_ifdef(CONFIG_PTHREAD_IPC posix) add_subdirectory_ifdef(CONFIG_PTHREAD_IPC posix)
add_subdirectory_ifdef(CONFIG_CMSIS_RTOS_V1 cmsis_rtos_v1)
add_subdirectory(rbtree) add_subdirectory(rbtree)

1
lib/Kconfig

@ -31,4 +31,5 @@ config BASE64
source "lib/posix/Kconfig" source "lib/posix/Kconfig"
source "lib/cmsis_rtos_v1/Kconfig"
endmenu endmenu

10
lib/cmsis_rtos_v1/CMakeLists.txt

@ -0,0 +1,10 @@
add_library(CMSIS INTERFACE)
target_include_directories(CMSIS INTERFACE ${PROJECT_SOURCE_DIR}/include/cmsis_rtos_v1)
zephyr_library()
zephyr_library_sources_ifdef(CONFIG_CMSIS_RTOS_V1 cmsis_thread.c)
zephyr_library_link_libraries(CMSIS)
target_link_libraries(CMSIS INTERFACE zephyr_interface)

36
lib/cmsis_rtos_v1/Kconfig

@ -0,0 +1,36 @@
#
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
config CMSIS_RTOS_V1
bool
prompt "CMSIS RTOS v1 API"
default n
help
This enables CMSIS RTOS v1 API support. This is an OS-integration
layer which allows applications using CMSIS RTOS APIs to build on
Zephyr.
if CMSIS_RTOS_V1
config CMSIS_MAX_THREAD_COUNT
int
prompt "Maximum thread count in CMSIS RTOS application"
default 10
range 0 255
help
Mention max number of threads in CMSIS RTOS compliant application.
There's a limitation on the number of threads due to memory
related constraints.
config CMSIS_THREAD_MAX_STACK_SIZE
int
prompt "Max stack size threads can be allocated in CMSIS RTOS application"
default 512
help
Mention max stack size threads can be allocated in CMSIS RTOS application.
config NUM_PREEMPT_PRIORITIES
int
default 7
endif

166
lib/cmsis_rtos_v1/cmsis_thread.c

@ -0,0 +1,166 @@
/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel_structs.h>
#include <atomic.h>
#include <cmsis_os.h>
static inline int _is_thread_cmsis_inactive(struct k_thread *thread)
{
u8_t state = thread->base.thread_state;
return state & (_THREAD_PRESTART | _THREAD_DEAD);
}
static inline s32_t zephyr_to_cmsis_priority(u32_t z_prio)
{
return(osPriorityRealtime - z_prio);
}
static inline u32_t cmsis_to_zephyr_priority(s32_t c_prio)
{
return(osPriorityRealtime - c_prio);
}
static void zephyr_thread_wrapper(void *arg1, void *arg2, void *arg3)
{
void * (*fun_ptr)(void *) = arg3;
fun_ptr(arg1);
}
/**
* @brief Create a new thread.
*/
osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *arg)
{
struct k_thread *cm_thread;
u32_t prio;
k_tid_t tid;
u32_t stacksz;
k_thread_stack_t
(*stk_ptr)[K_THREAD_STACK_LEN(CONFIG_CMSIS_THREAD_MAX_STACK_SIZE)];
__ASSERT(thread_def->stacksize >= 0 &&
thread_def->stacksize <= CONFIG_CMSIS_THREAD_MAX_STACK_SIZE,
"invalid stack size\n");
if (thread_def->instances == 0) {
return NULL;
}
if (_is_in_isr()) {
return NULL;
}
stacksz = thread_def->stacksize;
if (stacksz == 0) {
stacksz = CONFIG_CMSIS_THREAD_MAX_STACK_SIZE;
}
cm_thread = thread_def->cm_thread;
atomic_dec((atomic_t *)&thread_def->instances);
stk_ptr = thread_def->stack_mem;
prio = cmsis_to_zephyr_priority(thread_def->tpriority);
tid = k_thread_create(&cm_thread[thread_def->instances],
stk_ptr[thread_def->instances], stacksz,
(k_thread_entry_t)zephyr_thread_wrapper,
(void *)arg, NULL, thread_def->pthread,
prio, 0, K_NO_WAIT);
return ((osThreadId)tid);
}
/**
* @brief Return the thread ID of the current running thread.
*/
osThreadId osThreadGetId(void)
{
if (_is_in_isr()) {
return NULL;
}
return (osThreadId)k_current_get();
}
/**
* @brief Get current priority of an active thread.
*/
osPriority osThreadGetPriority(osThreadId thread_id)
{
k_tid_t thread = (k_tid_t)thread_id;
u32_t priority;
if (_is_in_isr()) {
return osPriorityError;
}
priority = k_thread_priority_get(thread);
return zephyr_to_cmsis_priority(priority);
}
/**
* @brief Change priority of an active thread.
*/
osStatus osThreadSetPriority(osThreadId thread_id, osPriority priority)
{
if (thread_id == NULL) {
return osErrorParameter;
}
if (_is_in_isr()) {
return osErrorISR;
}
if (priority < osPriorityIdle || priority > osPriorityRealtime) {
return osErrorValue;
}
if (_is_thread_cmsis_inactive((k_tid_t)thread_id)) {
return osErrorResource;
}
k_thread_priority_set((k_tid_t)thread_id,
cmsis_to_zephyr_priority(priority));
return osOK;
}
/**
* @brief Terminate execution of a thread.
*/
osStatus osThreadTerminate(osThreadId thread_id)
{
if (thread_id == NULL) {
return osErrorParameter;
}
if (_is_in_isr()) {
return osErrorISR;
}
if (_is_thread_cmsis_inactive((k_tid_t)thread_id)) {
return osErrorResource;
}
k_thread_abort((k_tid_t)thread_id);
return osOK;
}
/**
* @brief Pass control to next thread that is in READY state.
*/
osStatus osThreadYield(void)
{
if (_is_in_isr()) {
return osErrorISR;
}
k_yield();
return osOK;
}
Loading…
Cancel
Save