Skip to content

Add ThisThread namespace and deprecate static Thread methods #7872

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 99 additions & 96 deletions TESTS/mbedmicro-rtos-mbed/threads/main.cpp

Large diffs are not rendered by default.

17 changes: 15 additions & 2 deletions rtos/Kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@
#include "rtos/Kernel.h"

#include "mbed.h"
#include "rtos/rtos_idle.h"
#include "rtos/rtos_handlers.h"

namespace rtos {

uint64_t Kernel::get_ms_count() {
uint64_t Kernel::get_ms_count()
{
// CMSIS-RTOS 2.1.0 and 2.1.1 differ in the time type. 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)
Expand All @@ -36,7 +39,7 @@ uint64_t Kernel::get_ms_count() {
// 2.1.x who knows? We assume could go back to uint64_t
if (sizeof osKernelGetTickCount() == sizeof(uint64_t)) {
return osKernelGetTickCount();
} else /* assume 32-bit */ {
} else { /* assume 32-bit */
// Based on suggestion in CMSIS-RTOS 2.1.1 docs, but with reentrancy
// protection for the tick memory. We use critical section rather than a
// mutex, as hopefully this method can be callable from interrupt later -
Expand All @@ -60,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);
}

}
15 changes: 15 additions & 0 deletions rtos/Kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#define KERNEL_H

#include <stdint.h>
#include "cmsis_os2.h"

namespace rtos {
/** \addtogroup rtos */
Expand All @@ -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
Expand Down
122 changes: 68 additions & 54 deletions rtos/TARGET_CORTEX/mbed_rtx_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -30,45 +31,58 @@
#endif

extern void rtos_idle_loop(void);
extern void thread_terminate_hook(osThreadId_t id);

__NO_RETURN void osRtxIdleThread (void *argument)
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)
{
for (;;) {
rtos_idle_loop();
rtos_idle_loop();
}
}

__NO_RETURN uint32_t osRtxErrorNotify (uint32_t code, void *object_id)
__NO_RETURN uint32_t osRtxErrorNotify(uint32_t code, void *object_id)
{
osThreadId_t tid = osThreadGetId();

switch (code) {
case osRtxErrorStackUnderflow:
// Stack underflow detected for thread (thread_id=object_id)
// Note: "overflow" is printed instead of "underflow" due to end user familiarity with overflow errors
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_STACK_OVERFLOW), "CMSIS-RTOS error: Stack overflow", code);
break;
case osRtxErrorISRQueueOverflow:
// ISR Queue overflow detected when inserting object (object_id)
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_ISR_QUEUE_OVERFLOW), "CMSIS-RTOS error: ISR Queue overflow", code);
break;
case osRtxErrorTimerQueueOverflow:
// User Timer Callback Queue overflow detected for timer (timer_id=object_id)
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_TIMER_QUEUE_OVERFLOW), "CMSIS-RTOS error: User Timer Callback Queue overflow", code);
break;
case osRtxErrorClibSpace:
// Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_CLIB_SPACE_UNAVAILABLE), "CMSIS-RTOS error: STD C/C++ library libspace not available", code);
break;
case osRtxErrorClibMutex:
// Standard C/C++ library mutex initialization failed
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_CLIB_MUTEX_INIT_FAILURE), "CMSIS-RTOS error: STD C/C++ library mutex initialization failed", code);
break;
default:
//Unknown error flagged from kernel
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_UNKNOWN), "CMSIS-RTOS error: Unknown", code);
break;
case osRtxErrorStackUnderflow:
// Stack underflow detected for thread (thread_id=object_id)
// Note: "overflow" is printed instead of "underflow" due to end user familiarity with overflow errors
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_STACK_OVERFLOW), "CMSIS-RTOS error: Stack overflow", code);
break;
case osRtxErrorISRQueueOverflow:
// ISR Queue overflow detected when inserting object (object_id)
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_ISR_QUEUE_OVERFLOW), "CMSIS-RTOS error: ISR Queue overflow", code);
break;
case osRtxErrorTimerQueueOverflow:
// User Timer Callback Queue overflow detected for timer (timer_id=object_id)
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_TIMER_QUEUE_OVERFLOW), "CMSIS-RTOS error: User Timer Callback Queue overflow", code);
break;
case osRtxErrorClibSpace:
// Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_CLIB_SPACE_UNAVAILABLE), "CMSIS-RTOS error: STD C/C++ library libspace not available", code);
break;
case osRtxErrorClibMutex:
// Standard C/C++ library mutex initialization failed
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_CLIB_MUTEX_INIT_FAILURE), "CMSIS-RTOS error: STD C/C++ library mutex initialization failed", code);
break;
default:
//Unknown error flagged from kernel
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_UNKNOWN), "CMSIS-RTOS error: Unknown", code);
break;
}

/* That shouldn't be reached */
Expand All @@ -77,52 +91,52 @@ __NO_RETURN uint32_t osRtxErrorNotify (uint32_t code, void *object_id)

#if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED

static const char* error_msg(int32_t status)
static const char *error_msg(int32_t status)
{
switch (status) {
case osError:
return "Unspecified RTOS error";
case osErrorTimeout:
return "Operation not completed within the timeout period";
case osErrorResource:
return "Resource not available";
case osErrorParameter:
return "Parameter error";
case osErrorNoMemory:
return "System is out of memory";
case osErrorISR:
return "Not allowed in ISR context";
default:
return "Unknown";
case osError:
return "Unspecified RTOS error";
case osErrorTimeout:
return "Operation not completed within the timeout period";
case osErrorResource:
return "Resource not available";
case osErrorParameter:
return "Parameter error";
case osErrorNoMemory:
return "System is out of memory";
case osErrorISR:
return "Not allowed in ISR context";
default:
return "Unknown";
}
}

void EvrRtxKernelError (int32_t status)
void EvrRtxKernelError(int32_t status)
{
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_RTOS_EVENT), error_msg(status), status);
}

void EvrRtxThreadError (osThreadId_t thread_id, int32_t status)
void EvrRtxThreadError(osThreadId_t thread_id, int32_t status)
{
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_RTOS_THREAD_EVENT), error_msg(status), thread_id);
}

void EvrRtxTimerError (osTimerId_t timer_id, int32_t status)
void EvrRtxTimerError(osTimerId_t timer_id, int32_t status)
{
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_RTOS_TIMER_EVENT), error_msg(status), timer_id);
}

void EvrRtxEventFlagsError (osEventFlagsId_t ef_id, int32_t status)
void EvrRtxEventFlagsError(osEventFlagsId_t ef_id, int32_t status)
{
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_RTOS_EVENT_FLAGS_EVENT), error_msg(status), ef_id);
}

void EvrRtxMutexError (osMutexId_t mutex_id, int32_t status)
void EvrRtxMutexError(osMutexId_t mutex_id, int32_t status)
{
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_RTOS_MUTEX_EVENT), error_msg(status), mutex_id);
}

void EvrRtxSemaphoreError (osSemaphoreId_t semaphore_id, int32_t status)
void EvrRtxSemaphoreError(osSemaphoreId_t semaphore_id, int32_t status)
{
// Ignore semaphore overflow, the count will saturate with a returned error
if (status == osRtxErrorSemaphoreCountLimit) {
Expand All @@ -132,20 +146,20 @@ void EvrRtxSemaphoreError (osSemaphoreId_t semaphore_id, int32_t status)
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_RTOS_SEMAPHORE_EVENT), error_msg(status), semaphore_id);
}

void EvrRtxMemoryPoolError (osMemoryPoolId_t mp_id, int32_t status)
void EvrRtxMemoryPoolError(osMemoryPoolId_t mp_id, int32_t status)
{
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_RTOS_MEMORY_POOL_EVENT), error_msg(status), mp_id);
}

void EvrRtxMessageQueueError (osMessageQueueId_t mq_id, int32_t status)
void EvrRtxMessageQueueError(osMessageQueueId_t mq_id, int32_t status)
{
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_RTOS_MESSAGE_QUEUE_EVENT), error_msg(status), mq_id);
}

#endif

// RTX hook which gets called when a thread terminates, using the event function to call hook
void EvrRtxThreadExit (void)
void EvrRtxThreadExit(void)
{
osThreadId_t thread_id = osThreadGetId();
thread_terminate_hook(thread_id);
Expand All @@ -154,7 +168,7 @@ void EvrRtxThreadExit (void)
#endif
}

void EvrRtxThreadTerminate (osThreadId_t thread_id)
void EvrRtxThreadTerminate(osThreadId_t thread_id)
{
thread_terminate_hook(thread_id);
#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_TERMINATE_DISABLE) && defined(RTE_Compiler_EventRecorder))
Expand Down
Loading