Clone of mbed rtos 2 for easy accessibility.
Fork of mbed-rtos by
Revision 123:58563e6cba1e, committed 2016-11-14
- Comitter:
- c1728p9
- Date:
- Mon Nov 14 17:14:42 2016 -0600
- Parent:
- 122:b744dfee1cf2
- Child:
- 124:66949d9d57c1
- Commit message:
- Configure RTOS to behave as it did before 5.0
Changed in this revision
--- a/rtos/Mail.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Mail.h Mon Nov 14 17:14:42 2016 -0600
@@ -28,6 +28,8 @@
#include "cmsis_os.h"
namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
/** The Mail class allow to control, send, receive, or wait for mail.
A mail is a memory block that is send to a thread or interrupt service routine.
@@ -107,3 +109,5 @@
#endif
+
+/** @}*/
--- a/rtos/MemoryPool.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/MemoryPool.h Mon Nov 14 17:14:42 2016 -0600
@@ -28,6 +28,8 @@
#include "cmsis_os.h"
namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
/** Define and manage fixed-size memory pools of objects of a given type.
@tparam T data type of a single object (element).
@@ -80,3 +82,5 @@
}
#endif
+
+/** @}*/
--- a/rtos/Mutex.cpp Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Mutex.cpp Mon Nov 14 17:14:42 2016 -0600
@@ -19,10 +19,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#include "Mutex.h"
+#include "rtos/Mutex.h"
#include <string.h>
-#include "mbed_error.h"
+#include "platform/mbed_error.h"
namespace rtos {
--- a/rtos/Mutex.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Mutex.h Mon Nov 14 17:14:42 2016 -0600
@@ -26,6 +26,8 @@
#include "cmsis_os.h"
namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
/** The Mutex class is used to synchronise the execution of threads.
This is for example used to protect access to a shared resource.
@@ -67,3 +69,5 @@
}
#endif
+
+/** @}*/
--- a/rtos/Queue.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Queue.h Mon Nov 14 17:14:42 2016 -0600
@@ -26,9 +26,11 @@
#include <string.h>
#include "cmsis_os.h"
-#include "mbed_error.h"
+#include "platform/mbed_error.h"
namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
/** The Queue class allow to control, send, receive, or wait for messages.
A message can be a integer or pointer value to a certain type T that is send
@@ -79,3 +81,5 @@
}
#endif
+
+/** @}*/
--- a/rtos/RtosTimer.cpp Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/RtosTimer.cpp Mon Nov 14 17:14:42 2016 -0600
@@ -19,13 +19,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#include "RtosTimer.h"
+#include "rtos/RtosTimer.h"
#include <string.h>
#include "mbed.h"
#include "cmsis_os.h"
-#include "mbed_error.h"
+#include "platform/mbed_error.h"
namespace rtos {
--- a/rtos/RtosTimer.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/RtosTimer.h Mon Nov 14 17:14:42 2016 -0600
@@ -24,10 +24,12 @@
#include <stdint.h>
#include "cmsis_os.h"
-#include "Callback.h"
-#include "toolchain.h"
+#include "platform/Callback.h"
+#include "platform/toolchain.h"
namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
/** The RtosTimer class allow creating and and controlling of timer functions in the system.
A timer function is called when a time period expires whereby both on-shot and
@@ -47,7 +49,7 @@
MBED_DEPRECATED_SINCE("mbed-os-5.1",
"Replaced with RtosTimer(Callback<void()>, os_timer_type)")
RtosTimer(void (*func)(void const *argument), os_timer_type type=osTimerPeriodic, void *argument=NULL) {
- constructor(mbed::Callback<void()>(argument, (void (*)(void *))func), type);
+ constructor(mbed::callback((void (*)(void *))func, argument), type);
}
/** Create timer.
@@ -62,10 +64,16 @@
@param obj pointer to the object to call the member function on.
@param method member function to be executed by this timer.
@param type osTimerOnce for one-shot or osTimerPeriodic for periodic behaviour. (default: osTimerPeriodic)
+ @deprecated
+ The RtosTimer constructor does not support cv-qualifiers. Replaced by
+ RtosTimer(callback(obj, method), os_timer_type).
*/
template <typename T, typename M>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "The RtosTimer constructor does not support cv-qualifiers. Replaced by "
+ "RtosTimer(callback(obj, method), os_timer_type).")
RtosTimer(T *obj, M method, os_timer_type type=osTimerPeriodic) {
- constructor(mbed::Callback<void()>(obj, method), type);
+ constructor(mbed::callback(obj, method), type);
}
/** Stop the timer.
@@ -99,3 +107,5 @@
}
#endif
+
+/** @}*/
--- a/rtos/Semaphore.cpp Wed Nov 09 12:22:14 2016 -0600 +++ b/rtos/Semaphore.cpp Mon Nov 14 17:14:42 2016 -0600 @@ -19,7 +19,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "Semaphore.h" +#include "rtos/Semaphore.h" #include <string.h>
--- a/rtos/Semaphore.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Semaphore.h Mon Nov 14 17:14:42 2016 -0600
@@ -26,6 +26,8 @@
#include "cmsis_os.h"
namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
/** The Semaphore class is used to manage and protect access to a set of shared resources. */
class Semaphore {
@@ -58,3 +60,5 @@
}
#endif
+
+/** @}*/
--- a/rtos/Thread.cpp Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Thread.cpp Mon Nov 14 17:14:42 2016 -0600
@@ -19,10 +19,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#include "Thread.h"
+#include "rtos/Thread.h"
#include "mbed.h"
-#include "rtos_idle.h"
+#include "rtos/rtos_idle.h"
// rt_tid2ptcb is an internal function which we exposed to get TCB for thread id
#undef NULL //Workaround for conflicting macros in rt_TypeDef.h and stdio.h
@@ -30,6 +30,15 @@
extern "C" P_TCB rt_tid2ptcb(osThreadId thread_id);
+
+static void (*terminate_hook)(osThreadId id) = 0;
+extern "C" void thread_terminate_hook(osThreadId id)
+{
+ if (terminate_hook != (void (*)(osThreadId))NULL) {
+ terminate_hook(id);
+ }
+}
+
namespace rtos {
void Thread::constructor(osPriority priority,
@@ -74,10 +83,7 @@
_thread_def.pthread = Thread::_thunk;
if (_thread_def.stack_pointer == NULL) {
_thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)];
- if (_thread_def.stack_pointer == NULL) {
- _mutex.unlock();
- return osErrorNoMemory;
- }
+ MBED_ASSERT(_thread_def.stack_pointer != NULL);
}
//Fill the stack with a magic word for maximum usage checking
@@ -88,8 +94,12 @@
_task = task;
_tid = osThreadCreate(&_thread_def, this);
if (_tid == NULL) {
- if (_dynamic_stack) delete[] (_thread_def.stack_pointer);
+ if (_dynamic_stack) {
+ delete[] (_thread_def.stack_pointer);
+ _thread_def.stack_pointer = (uint32_t*)NULL;
+ }
_mutex.unlock();
+ _join_sem.release();
return osErrorResource;
}
@@ -101,11 +111,14 @@
osStatus ret;
_mutex.lock();
- ret = osThreadTerminate(_tid);
+ // Set the Thread's tid to NULL and
+ // release the semaphore before terminating
+ // since this thread could be terminating itself
+ osThreadId local_id = _tid;
+ _join_sem.release();
_tid = (osThreadId)NULL;
- // Wake threads joining the terminated thread
- _join_sem.release();
+ ret = osThreadTerminate(local_id);
_mutex.unlock();
return ret;
@@ -116,6 +129,14 @@
if (ret < 0) {
return osErrorOS;
}
+
+ // The semaphore has been released so this thread is being
+ // terminated or has been terminated. Once the mutex has
+ // been locked it is ensured that the thread is deleted.
+ _mutex.lock();
+ MBED_ASSERT(NULL == _tid);
+ _mutex.unlock();
+
// Release sem so any other threads joining this thread wake up
_join_sem.release();
return osOK;
@@ -325,12 +346,17 @@
rtos_attach_idle_hook(fptr);
}
+void Thread::attach_terminate_hook(void (*fptr)(osThreadId id)) {
+ terminate_hook = fptr;
+}
+
Thread::~Thread() {
// terminate is thread safe
terminate();
#ifdef __MBED_CMSIS_RTOS_CM
if (_dynamic_stack) {
delete[] (_thread_def.stack_pointer);
+ _thread_def.stack_pointer = (uint32_t*)NULL;
}
#endif
}
--- a/rtos/Thread.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Thread.h Mon Nov 14 17:14:42 2016 -0600
@@ -24,14 +24,43 @@
#include <stdint.h>
#include "cmsis_os.h"
-#include "Callback.h"
-#include "toolchain.h"
-#include "Semaphore.h"
-#include "Mutex.h"
+#include "platform/Callback.h"
+#include "platform/toolchain.h"
+#include "rtos/Semaphore.h"
+#include "rtos/Mutex.h"
namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
-/** The Thread class allow defining, creating, and controlling thread functions in the system. */
+/** The Thread class allow defining, creating, and controlling thread functions in the system.
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "rtos.h"
+ *
+ * Thread thread;
+ * DigitalOut led1(LED1);
+ * volatile bool running = true;
+ *
+ * // Blink function toggles the led in a long running loop
+ * void blink(DigitalOut *led) {
+ * while (running) {
+ * *led = !*led;
+ * Thread::wait(1000);
+ * }
+ * }
+ *
+ * // Spawns a thread to run blink for 5 seconds
+ * int main() {
+ * thread.start(led1, blink);
+ * Thread::wait(5000);
+ * running = false;
+ * thread.join();
+ * }
+ * @endcode
+ */
class Thread {
public:
/** Allocate a new thread without starting execution
@@ -52,15 +81,20 @@
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
@deprecated
- Thread-spawning constructors hide errors and may lead to complex
- program state when a thread is declared.
+ Thread-spawning constructors hide errors. Replaced by thread.start(task).
+
+ @code
+ Thread thread(priority, stack_size, stack_pointer);
- The explicit Thread::start member function should be used to spawn
- a thread.
+ osStatus status = thread.start(task);
+ if (status != osOK) {
+ error("oh no!");
+ }
+ @endcode
*/
MBED_DEPRECATED_SINCE("mbed-os-5.1",
- "Thread-spawning constructors hide errors and may lead to complex "
- "program state when a thread is declared")
+ "Thread-spawning constructors hide errors. "
+ "Replaced by thread.start(task).")
Thread(mbed::Callback<void()> task,
osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
@@ -76,21 +110,26 @@
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
@deprecated
- Thread-spawning constructors hide errors and may lead to complex
- program state when a thread is declared.
+ Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
+
+ @code
+ Thread thread(priority, stack_size, stack_pointer);
- The explicit Thread::start member function should be used to spawn
- a thread.
+ osStatus status = thread.start(callback(task, argument));
+ if (status != osOK) {
+ error("oh no!");
+ }
+ @endcode
*/
template <typename T>
MBED_DEPRECATED_SINCE("mbed-os-5.1",
- "Thread-spawning constructors hide errors and may lead to complex "
- "program state when a thread is declared")
- Thread(T *obj, void (T::*method)(),
+ "Thread-spawning constructors hide errors. "
+ "Replaced by thread.start(callback(task, argument)).")
+ Thread(T *argument, void (T::*task)(),
osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
unsigned char *stack_pointer=NULL) {
- constructor(mbed::Callback<void()>(obj, method),
+ constructor(mbed::callback(task, argument),
priority, stack_size, stack_pointer);
}
@@ -102,21 +141,26 @@
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
@deprecated
- Thread-spawning constructors hide errors and may lead to complex
- program state when a thread is declared.
+ Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
+
+ @code
+ Thread thread(priority, stack_size, stack_pointer);
- The explicit Thread::start member function should be used to spawn
- a thread.
+ osStatus status = thread.start(callback(task, argument));
+ if (status != osOK) {
+ error("oh no!");
+ }
+ @endcode
*/
template <typename T>
MBED_DEPRECATED_SINCE("mbed-os-5.1",
- "Thread-spawning constructors hide errors and may lead to complex "
- "program state when a thread is declared")
- Thread(T *obj, void (*method)(T *),
+ "Thread-spawning constructors hide errors. "
+ "Replaced by thread.start(callback(task, argument)).")
+ Thread(T *argument, void (*task)(T *),
osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
unsigned char *stack_pointer=NULL) {
- constructor(mbed::Callback<void()>(obj, method),
+ constructor(mbed::callback(task, argument),
priority, stack_size, stack_pointer);
}
@@ -128,20 +172,25 @@
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
@deprecated
- Thread-spawning constructors hide errors and may lead to complex
- program state when a thread is declared.
+ Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
+
+ @code
+ Thread thread(priority, stack_size, stack_pointer);
- The explicit Thread::start member function should be used to spawn
- a thread.
+ osStatus status = thread.start(callback(task, argument));
+ if (status != osOK) {
+ error("oh no!");
+ }
+ @endcode
*/
MBED_DEPRECATED_SINCE("mbed-os-5.1",
- "Thread-spawning constructors hide errors and may lead to complex "
- "program state when a thread is declared")
+ "Thread-spawning constructors hide errors. "
+ "Replaced by thread.start(callback(task, argument)).")
Thread(void (*task)(void const *argument), void *argument=NULL,
osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
unsigned char *stack_pointer=NULL) {
- constructor(mbed::Callback<void()>(argument, (void (*)(void *))task),
+ constructor(mbed::callback((void (*)(void *))task, argument),
priority, stack_size, stack_pointer);
}
@@ -155,10 +204,15 @@
@param obj argument to task
@param method function to be executed by this thread.
@return status code that indicates the execution status of the function.
+ @deprecated
+ The start function does not support cv-qualifiers. Replaced by start(callback(obj, method)).
*/
template <typename T, typename M>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "The start function does not support cv-qualifiers. "
+ "Replaced by thread.start(callback(obj, method)).")
osStatus start(T *obj, M method) {
- return start(mbed::Callback<void()>(obj, method));
+ return start(mbed::callback(obj, method));
}
/** Wait for thread to terminate
@@ -268,6 +322,11 @@
*/
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
+ */
+ static void attach_terminate_hook(void (*fptr)(osThreadId id));
+
virtual ~Thread();
private:
@@ -292,3 +351,5 @@
}
#endif
+
+/** @}*/
--- a/rtos/rtos.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/rtos.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
@@ -22,13 +25,13 @@
#ifndef RTOS_H
#define RTOS_H
-#include "Thread.h"
-#include "Mutex.h"
-#include "RtosTimer.h"
-#include "Semaphore.h"
-#include "Mail.h"
-#include "MemoryPool.h"
-#include "Queue.h"
+#include "rtos/Thread.h"
+#include "rtos/Mutex.h"
+#include "rtos/RtosTimer.h"
+#include "rtos/Semaphore.h"
+#include "rtos/Mail.h"
+#include "rtos/MemoryPool.h"
+#include "rtos/Queue.h"
using namespace rtos;
@@ -37,8 +40,10 @@
*/
#include "mbed.h"
-#if (MBED_LIBRARY_VERSION < 124)
-#error "This version of RTOS requires mbed library version > 123"
+#if (MBED_LIBRARY_VERSION < 122)
+#error "This version of RTOS requires mbed library version > 121"
#endif
#endif
+
+/** @}*/
--- a/rtos/rtos_idle.c Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/rtos_idle.c Mon Nov 14 17:14:42 2016 -0600
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-#include "rtos_idle.h"
+#include "rtos/rtos_idle.h"
static void default_idle_hook(void)
{
--- a/rtos/rtos_idle.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/rtos_idle.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
@@ -35,3 +38,5 @@
#endif
#endif
+
+/** @}*/
--- a/rtx/TARGET_ARM7/RTX_CM_lib.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_ARM7/RTX_CM_lib.h Mon Nov 14 17:14:42 2016 -0600
@@ -198,15 +198,8 @@
extern void pre_main (void);
osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 0, NULL};
-// This define should be probably moved to the CMSIS layer
-
-#if defined(TARGET_LPC2460)
-extern unsigned char __usr_stack_top__[];
-#define INITIAL_SP (__usr_stack_top__)
-
-#else
-#error "no target defined"
-
+#ifndef INITIAL_SP
+ #error "no target defined"
#endif
#ifdef __CC_ARM
--- a/rtx/TARGET_ARM7/RTX_Conf_CM.c Wed Nov 09 12:22:14 2016 -0600 +++ b/rtx/TARGET_ARM7/RTX_Conf_CM.c Mon Nov 14 17:14:42 2016 -0600 @@ -39,6 +39,9 @@ * RTX User configuration part BEGIN *---------------------------------------------------------------------------*/ +// Include per-target RTX config file +#include "mbed_rtx.h" + //-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- // // <h>Thread Configuration @@ -49,20 +52,12 @@ // counting "main", but not counting "osTimerThread" // <i> Default: 6 #ifndef OS_TASKCNT -# if defined(TARGET_LPC2368) || defined(TARGET_LPC2460) -# define OS_TASKCNT 14 -# else -# error "no target defined" -# endif + #error "no target defined" #endif // <o>Scheduler (+ interrupts) stack size [bytes] <64-4096:8><#/4> #ifndef OS_SCHEDULERSTKSIZE -# if defined(TARGET_LPC2368) || defined(TARGET_LPC2460) -# define OS_SCHEDULERSTKSIZE (136*2) -# else -# error "no target defined" -# endif + #error "no target defined" #endif // <o>Idle stack size [bytes] <64-4096:8><#/4> @@ -101,15 +96,7 @@ // <i> Defines the timer clock value. // <i> Default: 6000000 (6MHz) #ifndef OS_CLOCK -# if defined(TARGET_LPC2368) -# define OS_CLOCK 96000000 - -# elif defined(TARGET_LPC2460) -# define OS_CLOCK 72000000 - -# else -# error "no target defined" -# endif + #error "no target defined" #endif // <o>Timer tick value [us] <1-1000000>
--- a/rtx/TARGET_CORTEX_A/RTX_CM_lib.h Wed Nov 09 12:22:14 2016 -0600 +++ b/rtx/TARGET_CORTEX_A/RTX_CM_lib.h Mon Nov 14 17:14:42 2016 -0600 @@ -51,7 +51,7 @@ #define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3] #define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2] -#define OS_TCB_SIZE 60 +#define OS_TCB_SIZE 64 #define OS_TMR_SIZE 8 #if defined (__CC_ARM) && !defined (__MICROLIB)
--- a/rtx/TARGET_CORTEX_A/RTX_Conf_CA.c Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_A/RTX_Conf_CA.c Mon Nov 14 17:14:42 2016 -0600
@@ -38,10 +38,8 @@
* RTX User configuration part BEGIN
*---------------------------------------------------------------------------*/
-#if defined(MBED_RTOS_SINGLE_THREAD)
-#define OS_TASKCNT 1
-#define OS_TIMERS 0
-#endif
+// Include per-target RTX config file
+#include "mbed_rtx.h"
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
//
@@ -122,11 +120,7 @@
// <i> Defines the timer clock value.
// <i> Default: 12000000 (12MHz)
#ifndef OS_CLOCK
-# if defined(TARGET_RZ_A1H) || defined(TARGET_VK_RZ_A1H)
- #define OS_CLOCK 12000000
-# else
-# error "no target defined"
-# endif
+ #error "no target defined"
#endif
// <o>Timer tick value [us] <1-1000000>
@@ -320,6 +314,14 @@
for (;;);
}
+/*----------------------------------------------------------------------------
+ * RTX Hooks
+ *---------------------------------------------------------------------------*/
+extern void thread_terminate_hook(osThreadId id);
+
+void sysThreadTerminate(osThreadId id) {
+ thread_terminate_hook(id);
+}
/*----------------------------------------------------------------------------
* RTX Configuration Functions
--- a/rtx/TARGET_CORTEX_A/cmsis_os.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_A/cmsis_os.h Mon Nov 14 17:14:42 2016 -0600
@@ -160,6 +160,7 @@
#define osFeature_Semaphore 65535 ///< maximum count for \ref osSemaphoreCreate function
#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available
#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available
+#define osFeature_ThreadEnum 1 ///< Thread enumeration available
#if defined (__CC_ARM)
#define os_InRegs __value_in_regs // Compiler specific: force struct in registers
@@ -223,6 +224,16 @@
osTimerPeriodic = 1 ///< repeating timer
} os_timer_type;
+typedef enum {
+ osThreadInfoState,
+ osThreadInfoStackSize,
+ osThreadInfoStackMax,
+ osThreadInfoEntry,
+ osThreadInfoArg,
+
+ osThreadInfo_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization.
+} osThreadInfo;
+
/// Entry point of a thread.
/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS.
typedef void (*os_pthread) (void const *argument);
@@ -261,6 +272,8 @@
/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS.
typedef struct os_mailQ_cb *osMailQId;
+/// Thread enumeration ID identifies the enumeration (pointer to a thread enumeration control block).
+typedef uint32_t *osThreadEnumId;
/// Thread Definition structure contains startup information of a thread.
/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS.
@@ -448,6 +461,13 @@
uint8_t osThreadGetState (osThreadId thread_id);
#endif
+/// Get into from an active thread.
+/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in] info information to read.
+/// \return current state of the thread function.
+/// \return requested info that includes the status code.
+os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info);
+
// ==== Generic Wait Functions ====
/// Wait for Timeout (Time Delay).
@@ -823,6 +843,26 @@
#endif // Mail Queues available
+// ==== Thread Enumeration Functions ====
+
+#if (defined (osFeature_ThreadEnum) && (osFeature_ThreadEnum != 0)) // Thread enumeration available
+
+/// Start a thread enumeration.
+/// \return an enumeration ID or NULL on error.
+osThreadEnumId _osThreadsEnumStart(void);
+
+/// Get the next task ID in the enumeration.
+/// \return a thread ID or NULL on if the end of the enumeration has been reached.
+osThreadId _osThreadEnumNext(osThreadEnumId enum_id);
+
+/// Free the enumeration structure.
+/// \param[in] enum_id pointer to the enumeration ID that was obtained with \ref _osThreadsEnumStart.
+/// \return status code that indicates the execution status of the function.
+osStatus _osThreadEnumFree(osThreadEnumId enum_id);
+
+#endif // Thread Enumeration available
+
+
// ==== RTX Extensions ====
/// os_suspend: http://www.keil.com/support/man/docs/rlarm/rlarm_os_suspend.htm
--- a/rtx/TARGET_CORTEX_A/rt_CMSIS.c Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_A/rt_CMSIS.c Mon Nov 14 17:14:42 2016 -0600
@@ -479,6 +479,10 @@
extern U32 IRQNestLevel; /* Indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR. */
+// Thread creation and destruction
+osMutexDef(osThreadMutex);
+osMutexId osMutexId_osThreadMutex;
+void sysThreadTerminate(osThreadId id);
// ==== Helper Functions ====
@@ -539,6 +543,11 @@
}
static __inline char __exceptional_mode(void) {
+ // Interrupts disabled
+ if (__get_CPSR() & 0x80) {
+ return 1;
+ }
+
switch(__get_mode()) {
case MODE_USR:
case MODE_SYS:
@@ -596,6 +605,8 @@
// Create OS Timers resources (Message Queue & Thread)
osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL);
osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL);
+ // Initialize thread mutex
+ osMutexId_osThreadMutex = osMutexCreate(osMutex(osThreadMutex));
}
sysThreadError(osOK);
@@ -708,6 +719,7 @@
SVC_0_1(svcThreadYield, osStatus, RET_osStatus)
SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus)
SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority)
+SVC_2_3(svcThreadGetInfo, os_InRegs osEvent, osThreadId, osThreadInfo, RET_osEvent)
// Thread Service Calls
@@ -846,6 +858,80 @@
return (osPriority)(ptcb->prio - 1 + osPriorityIdle);
}
+/// Get info from an active thread
+os_InRegs osEvent_type svcThreadGetInfo (osThreadId thread_id, osThreadInfo info) {
+ P_TCB ptcb;
+ osEvent ret;
+ ret.status = osOK;
+
+ ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
+ if (ptcb == NULL) {
+ ret.status = osErrorValue;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+ osEvent_ret_status;
+ return;
+#else
+ return osEvent_ret_status;
+#endif
+ }
+
+ if (osThreadInfoStackSize == info) {
+ uint32_t size;
+ size = ptcb->priv_stack;
+ if (0 == size) {
+ // This is an OS task - always a fixed size
+ size = os_stackinfo & 0x3FFFF;
+ }
+ ret.value.v = size;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+ osEvent_ret_value;
+ return;
+#else
+ return osEvent_ret_value;
+#endif
+ }
+
+ if (osThreadInfoStackMax == info) {
+ // Cortex-A RTX does not have stack init so
+ // the maximum stack usage cannot be obtained.
+ ret.status = osErrorResource;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+ osEvent_ret_status;
+ return;
+#else
+ return osEvent_ret_status;
+#endif
+ }
+
+ if (osThreadInfoEntry == info) {
+ ret.value.p = (void*)ptcb->ptask;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+ osEvent_ret_value;
+ return;
+#else
+ return osEvent_ret_value;
+#endif
+ }
+
+ if (osThreadInfoArg == info) {
+ ret.value.p = (void*)ptcb->argv;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+ osEvent_ret_value;
+ return;
+#else
+ return osEvent_ret_value;
+#endif
+ }
+
+ // Unsupported option so return error
+ ret.status = osErrorParameter;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+ osEvent_ret_status;
+ return;
+#else
+ return osEvent_ret_status;
+#endif
+}
// Thread Public API
@@ -856,7 +942,12 @@
// Privileged and not running
return svcThreadCreate(thread_def, argument);
} else {
- return __svcThreadCreate(thread_def, argument);
+ osThreadId id;
+ osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+ // Thread mutex must be held when a thread is created or terminated
+ id = __svcThreadCreate(thread_def, argument);
+ osMutexRelease(osMutexId_osThreadMutex);
+ return id;
}
}
@@ -868,8 +959,14 @@
/// Terminate execution of a thread and remove it from ActiveThreads
osStatus osThreadTerminate (osThreadId thread_id) {
+ osStatus status;
if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
- return __svcThreadTerminate(thread_id);
+ osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+ sysThreadTerminate(thread_id);
+ // Thread mutex must be held when a thread is created or terminated
+ status = __svcThreadTerminate(thread_id);
+ osMutexRelease(osMutexId_osThreadMutex);
+ return status;
}
/// Pass control to next thread that is in state READY
@@ -893,7 +990,14 @@
/// INTERNAL - Not Public
/// Auto Terminate Thread on exit (used implicitly when thread exists)
__NO_RETURN void osThreadExit (void) {
- __svcThreadTerminate(__svcThreadGetId());
+ osThreadId id;
+ // Thread mutex must be held when a thread is created or terminated
+ // Note - the mutex will be released automatically by the os when
+ // the thread is terminated
+ osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+ id = __svcThreadGetId();
+ sysThreadTerminate(id);
+ __svcThreadTerminate(id);
for (;;); // Should never come here
}
@@ -911,6 +1015,48 @@
}
#endif
+/// Get the requested info from the specified active thread
+os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info) {
+ osEvent ret;
+ if (__exceptional_mode()) {
+ ret.status = osErrorISR;
+ return ret; // Not allowed in ISR
+ }
+ return __svcThreadGetInfo(thread_id, info);
+}
+
+osThreadEnumId _osThreadsEnumStart() {
+ static uint32_t thread_enum_index;
+ osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+ thread_enum_index = 0;
+ return &thread_enum_index;
+}
+
+osThreadId _osThreadEnumNext(osThreadEnumId enum_id) {
+ uint32_t i;
+ osThreadId id = NULL;
+ uint32_t *index = (uint32_t*)enum_id;
+ for (i = *index; i < os_maxtaskrun; i++) {
+ if (os_active_TCB[i] != NULL) {
+ id = (osThreadId)os_active_TCB[i];
+ break;
+ }
+ }
+ if (i == os_maxtaskrun) {
+ // Include the idle task at the end of the enumeration
+ id = &os_idle_TCB;
+ }
+ *index = i + 1;
+ return id;
+}
+
+osStatus _osThreadEnumFree(osThreadEnumId enum_id) {
+ uint32_t *index = (uint32_t*)enum_id;
+ *index = 0;
+ osMutexRelease(osMutexId_osThreadMutex);
+ return osOK;
+}
+
// ==== Generic Wait Functions ====
// Generic Wait Service Calls declarations
--- a/rtx/TARGET_CORTEX_A/rt_TypeDef.h Wed Nov 09 12:22:14 2016 -0600 +++ b/rtx/TARGET_CORTEX_A/rt_TypeDef.h Mon Nov 14 17:14:42 2016 -0600 @@ -85,6 +85,7 @@ /* Task entry point used for uVision debugger */ FUNCP ptask; /* Task entry address */ + void *argv; /* Task argument */ } *P_TCB; #define TCB_TID 3 /* 'task id' offset */ #define TCB_STACKF 37 /* 'stack_frame' offset */
--- a/rtx/TARGET_CORTEX_M/HAL_CM.c Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/HAL_CM.c Mon Nov 14 17:14:42 2016 -0600
@@ -90,6 +90,32 @@
/* Task entry point. */
p_TCB->ptask = task_body;
+
+#ifdef __MBED_CMSIS_RTOS_CM
+ /* Set a magic word for checking of stack overflow.
+ For the main thread (ID: MAIN_THREAD_ID) the stack is in a memory area shared with the
+ heap, therefore the last word of the stack is a moving target.
+ We want to do stack/heap collision detection instead.
+ Similar applies to stack filling for the magic pattern.
+ */
+ if (p_TCB->task_id != MAIN_THREAD_ID) {
+ p_TCB->stack[0] = MAGIC_WORD;
+
+ /* Initialize stack with magic pattern. */
+ if (os_stackinfo & 0x10000000U) {
+ if (size > (16U+1U)) {
+ for (i = ((size - 16U)/2U) - 1U; i; i--) {
+ stk -= 2U;
+ stk[1] = MAGIC_PATTERN;
+ stk[0] = MAGIC_PATTERN;
+ }
+ if (--stk > p_TCB->stack) {
+ *stk = MAGIC_PATTERN;
+ }
+ }
+ }
+ }
+#else
/* Initialize stack with magic pattern. */
if (os_stackinfo & 0x10000000U) {
if (size > (16U+1U)) {
@@ -106,6 +132,7 @@
/* Set a magic word for checking of stack overflow. */
p_TCB->stack[0] = MAGIC_WORD;
+#endif
}
--- a/rtx/TARGET_CORTEX_M/RTX_CM_lib.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/RTX_CM_lib.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -52,7 +55,7 @@
#define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3]
#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2]
-#define OS_TCB_SIZE 60
+#define OS_TCB_SIZE 64
#define OS_TMR_SIZE 8
typedef void *OS_ID;
@@ -350,347 +353,43 @@
/* Main Thread definition */
extern void pre_main (void);
-
-#if defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832) || defined (TARGET_STM32F334R8) ||\
- defined(TARGET_STM32F302R8) || defined(TARGET_STM32F303K8) || defined (TARGET_STM32F334C8)
-static uint32_t thread_stack_main[DEFAULT_STACK_SIZE / sizeof(uint32_t)];
-#else
-static uint32_t thread_stack_main[DEFAULT_STACK_SIZE * 2 / sizeof(uint32_t)];
-#endif
-osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U, sizeof(thread_stack_main), thread_stack_main};
+osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U, 0U, NULL};
-/*
- * IAR Default Memory layout notes:
- * -Heap defined by "HEAP" region in .icf file
- * -Interrupt stack defined by "CSTACK" region in .icf file
- * -Value INITIAL_SP is ignored
- *
- * IAR Custom Memory layout notes:
- * -There is no custom layout available for IAR - everything must be defined in
- * the .icf file and use the default layout
- *
- *
- * GCC Default Memory layout notes:
- * -Block of memory from symbol __end__ to define INITIAL_SP used to setup interrupt
- * stack and heap in the function set_stack_heap()
- * -ISR_STACK_SIZE can be overridden to be larger or smaller
- *
- * GCC Custom Memory layout notes:
- * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE
- * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE
- *
- *
- * ARM Memory layout
- * -Block of memory from end of region "RW_IRAM1" to define INITIAL_SP used to setup interrupt
- * stack and heap in the function set_stack_heap()
- * -ISR_STACK_SIZE can be overridden to be larger or smaller
- *
- * ARM Custom Memory layout notes:
- * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE
- * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE
- *
- */
-
-
-// This define should be probably moved to the CMSIS layer
-#if defined(TARGET_LPC1768)
-#define INITIAL_SP (0x10008000UL)
-
-#elif defined(TARGET_LPC11U24)
-#define INITIAL_SP (0x10002000UL)
-
-#elif defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO)
-#define INITIAL_SP (0x10002000UL)
-
-#elif defined(TARGET_LPC1114)
-#define INITIAL_SP (0x10001000UL)
-
-#elif defined(TARGET_LPC812)
-#define INITIAL_SP (0x10001000UL)
-
-#elif defined(TARGET_LPC824) || defined(TARGET_SSCI824)
-#define INITIAL_SP (0x10002000UL)
-
-#elif defined(TARGET_KL25Z)
-#define INITIAL_SP (0x20003000UL)
-
-#elif defined(TARGET_KL26Z)
-#define INITIAL_SP (0x20003000UL)
-
-#elif defined(TARGET_KL27Z)
-#define INITIAL_SP (0x20003000UL)
-
-#elif defined(TARGET_K64F)
-#define INITIAL_SP (0x20030000UL)
-
-#if defined(__CC_ARM) || defined(__GNUC__)
-#define ISR_STACK_SIZE (0x1000)
+#ifdef __CC_ARM
+#if defined(TARGET_NUMAKER_PFM_NUC472)
+extern uint32_t Image$$ARM_LIB_HEAP$$Base[];
+#define HEAP_START ((uint32_t) Image$$ARM_LIB_HEAP$$Base)
+#else
+extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[];
+#define HEAP_START (Image$$RW_IRAM1$$ZI$$Limit)
+#endif
+#elif defined(__GNUC__)
+extern uint32_t __end__[];
+#define HEAP_START (__end__)
+#elif defined(__ICCARM__)
+#pragma section="HEAP"
+#define HEAP_END (void *)__section_end("HEAP")
#endif
-#elif defined(TARGET_K66F)
-#define INITIAL_SP (0x20030000UL)
-
-#elif defined(TARGET_K22F)
-#define INITIAL_SP (0x20010000UL)
-
-#elif defined(TARGET_KL46Z)
-#define INITIAL_SP (0x20006000UL)
-
-#elif defined(TARGET_KL43Z)
-#define INITIAL_SP (0x20006000UL)
-
-#elif defined(TARGET_KL05Z)
-#define INITIAL_SP (0x20000C00UL)
-
-#elif defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
-#define INITIAL_SP (0x10010000UL)
-
-#elif defined(TARGET_LPC4330)
-#define INITIAL_SP (0x10008000UL)
-
-#elif defined(TARGET_LPC4337)
-#define INITIAL_SP (0x10008000UL)
-
-#elif defined(TARGET_LPC1347)
-#define INITIAL_SP (0x10002000UL)
-
-#elif defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8)
-#define INITIAL_SP (0x20002000UL)
-
-#elif defined(TARGET_DISCO_F303VC)
-#define INITIAL_SP (0x2000A000UL)
-
-#elif defined(TARGET_STM32F407) || defined(TARGET_F407VG)
-#define INITIAL_SP (0x20020000UL)
-
-#elif defined(TARGET_STM32F401RE)
-#define INITIAL_SP (0x20018000UL)
-
-#elif defined(TARGET_LPC1549)
-#define INITIAL_SP (0x02009000UL)
-
-#elif defined(TARGET_LPC11U68)
-#define INITIAL_SP (0x10008000UL)
-
-#elif defined(TARGET_STM32F411RE)
-#define INITIAL_SP (0x20020000UL)
-
-#elif defined(TARGET_STM32F207ZG)
-#define INITIAL_SP (0x20020000UL)
-
-#elif defined(TARGET_STM32F410RB)
-#define INITIAL_SP (0x20008000UL)
-
-#elif defined(TARGET_STM32F103RB) || defined(TARGET_STM32L073RZ)
-#define INITIAL_SP (0x20005000UL)
-
-#elif defined(TARGET_STM32F302R8)
-#define INITIAL_SP (0x20004000UL)
-
-#elif defined(TARGET_STM32F334R8)
-#define INITIAL_SP (0x20003000UL)
-
-#elif defined(TARGET_STM32F334C8)
-#define INITIAL_SP (0x20003000UL)
-
-#elif defined(TARGET_STM32F405RG)
-#define INITIAL_SP (0x20020000UL)
-
-#elif defined(TARGET_STM32F429ZI)
-#define INITIAL_SP (0x20030000UL)
-
-#elif defined(TARGET_STM32L031K6) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)
-#define INITIAL_SP (0x20002000UL)
-
-#elif defined(TARGET_STM32F072RB)
-#define INITIAL_SP (0x20004000UL)
-
-#elif defined(TARGET_STM32F091RC)
-#define INITIAL_SP (0x20008000UL)
-
-#elif defined(TARGET_STM32F401VC)
-#define INITIAL_SP (0x20010000UL)
-
-#elif defined(TARGET_STM32F303RE)
-#define INITIAL_SP (0x20010000UL)
-
-#elif defined(TARGET_STM32F303K8)
-#define INITIAL_SP (0x20003000UL)
-
-#elif (defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG))
-#define INITIAL_SP (0x20050000UL)
-
-#elif defined(TARGET_MAX32610) || defined(TARGET_MAX32600) || defined(TARGET_MAX32620)
-#define INITIAL_SP (0x20008000UL)
-
-#elif defined(TARGET_TEENSY3_1)
-#define INITIAL_SP (0x20008000UL)
-
-#elif defined(TARGET_STM32L152RE)
-#define INITIAL_SP (0x20014000UL)
-
-#elif defined(TARGET_NZ32_SC151)
-#define INITIAL_SP (0x20008000UL)
-
-#elif defined(TARGET_STM32F446RE) || defined(TARGET_STM32F446VE) || defined(TARGET_STM32F446ZE)
-#define INITIAL_SP (0x20020000UL)
-
-#elif defined(TARGET_STM32F070RB) || defined(TARGET_STM32F030R8)
-#define INITIAL_SP (0x20002000UL)
-
-#elif defined(TARGET_STM32L432KC)
-#define INITIAL_SP (0x2000C000UL)
-
-#elif defined(TARGET_STM32L476VG)
-#define INITIAL_SP (0x20018000UL)
-
-#elif defined(TARGET_STM32L476RG)
-#define INITIAL_SP (0x20018000UL)
-
-#elif defined(TARGET_STM32F469NI)
-#define INITIAL_SP (0x20050000UL)
-
-#elif defined(TARGET_STM32L152RC)
-#define INITIAL_SP (0x20008000UL)
-
-#elif defined(TARGET_EFM32GG_STK3700) || defined(TARGET_BEETLE)
-#define INITIAL_SP (0x20020000UL)
-
-#elif defined(TARGET_EFM32HG_STK3400)
-#define INITIAL_SP (0x20002000UL)
+void set_main_stack(void) {
+#if defined(TARGET_NUMAKER_PFM_NUC472)
+ // Scheduler stack: OS_MAINSTKSIZE words
+ // Main thread stack: Reserved stack size - OS_MAINSTKSIZE words
+ os_thread_def_main.stack_pointer = (uint32_t *) FINAL_SP;
+ os_thread_def_main.stacksize = (uint32_t) INITIAL_SP - (uint32_t) FINAL_SP - OS_MAINSTKSIZE * 4;
+#else
+#if defined(__ICCARM__)
+ /* For IAR heap is defined .icf file */
+ uint32_t main_stack_size = ((uint32_t)INITIAL_SP - (uint32_t)HEAP_END) - interrupt_stack_size;
+#else
+ /* For ARM , uARM, or GCC_ARM , heap can grow and reach main stack */
+#endif
+ // That is the bottom of the main stack block: no collision detection
+ os_thread_def_main.stack_pointer = HEAP_START;
-#elif defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32PG_STK3401)
-#define INITIAL_SP (0x20008000UL)
-
-#elif defined(TARGET_MCU_NORDIC_32K)
-#define INITIAL_SP (0x20008000UL)
-
-#elif defined(TARGET_MCU_NORDIC_16K)
-#define INITIAL_SP (0x20004000UL)
-
-#elif defined(TARGET_MCU_NRF52832)
-#define INITIAL_SP (0x20010000UL)
-
-#elif (defined(TARGET_STM32F767ZI))
-#define INITIAL_SP (0x20080000UL)
-
-#elif defined(TARGET_NUMAKER_PFM_NUC472)
-# if defined(__CC_ARM)
-extern uint32_t Image$$ARM_LIB_HEAP$$Base[];
-extern uint32_t Image$$ARM_LIB_HEAP$$Length[];
-extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
-extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Length[];
-#define HEAP_START ((unsigned char*) Image$$ARM_LIB_HEAP$$Base)
-#define HEAP_SIZE ((uint32_t) Image$$ARM_LIB_HEAP$$Length)
-#define ISR_STACK_START ((unsigned char*)Image$$ARM_LIB_STACK$$ZI$$Base)
-#define ISR_STACK_SIZE ((uint32_t)Image$$ARM_LIB_STACK$$ZI$$Length)
-# elif defined(__GNUC__)
-extern uint32_t __StackTop[];
-extern uint32_t __StackLimit[];
-extern uint32_t __end__[];
-extern uint32_t __HeapLimit[];
-#define HEAP_START ((unsigned char*)__end__)
-#define HEAP_SIZE ((uint32_t)((uint32_t)__HeapLimit - (uint32_t)HEAP_START))
-#define ISR_STACK_START ((unsigned char*)__StackLimit)
-#define ISR_STACK_SIZE ((uint32_t)((uint32_t)__StackTop - (uint32_t)__StackLimit))
-# elif defined(__ICCARM__)
-/* No region declarations needed */
-# else
-#error "no toolchain defined"
-# endif
-
-#elif defined(TARGET_NCS36510)
-#define INITIAL_SP (0x40000000UL)
-
-#else
-#error "no target defined"
-
-#endif
-
-extern unsigned char *mbed_heap_start;
-extern uint32_t mbed_heap_size;
-
-unsigned char *mbed_stack_isr_start = 0;
-uint32_t mbed_stack_isr_size = 0;
-
-/*
- * Sanity check values
- */
-#if defined(__ICCARM__) && \
- (defined(HEAP_START) || defined(HEAP_SIZE) || \
- defined(ISR_STACK_START) && defined(ISR_STACK_SIZE))
- #error "No custom layout allowed for IAR. Use .icf file instead"
-#endif
-#if defined(HEAP_START) && !defined(HEAP_SIZE)
- #error "HEAP_SIZE must be defined if HEAP_START is defined"
+ // Leave OS_MAINSTKSIZE words for the scheduler and interrupts
+ os_thread_def_main.stacksize = (INITIAL_SP - (unsigned int)HEAP_START) - (OS_MAINSTKSIZE * 4);
#endif
-#if defined(ISR_STACK_START) && !defined(ISR_STACK_SIZE)
- #error "ISR_STACK_SIZE must be defined if ISR_STACK_START is defined"
-#endif
-#if defined(HEAP_SIZE) && !defined(HEAP_START)
- #error "HEAP_START must be defined if HEAP_SIZE is defined"
-#endif
-
-/* Interrupt stack and heap always defined for IAR
- * Main thread defined here
- */
-#if defined(__ICCARM__)
- #pragma section="CSTACK"
- #pragma section="HEAP"
- #define HEAP_START ((unsigned char*)__section_begin("HEAP"))
- #define HEAP_SIZE ((uint32_t)__section_size("HEAP"))
- #define ISR_STACK_START ((unsigned char*)__section_begin("CSTACK"))
- #define ISR_STACK_SIZE ((uint32_t)__section_size("CSTACK"))
-#endif
-
-/* Define heap region if it has not been defined already */
-#if !defined(HEAP_START)
- #if defined(__ICCARM__)
- #error "Heap should already be defined for IAR"
- #elif defined(__CC_ARM)
- extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[];
- #define HEAP_START ((unsigned char*)Image$$RW_IRAM1$$ZI$$Limit)
- #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START))
- #elif defined(__GNUC__)
- extern uint32_t __end__[];
- #define HEAP_START ((unsigned char*)__end__)
- #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START))
- #endif
-#endif
-
-/* Define stack sizes if they haven't been set already */
-#if !defined(ISR_STACK_SIZE)
- #define ISR_STACK_SIZE ((uint32_t)OS_MAINSTKSIZE * 4)
-#endif
-
-/*
- * set_stack_heap purpose is to set the following variables:
- * -mbed_heap_start
- * -mbed_heap_size
- * -mbed_stack_isr_start
- * -mbed_stack_isr_size
- *
- * Along with setting up os_thread_def_main
- */
-void set_stack_heap(void) {
-
- unsigned char *free_start = HEAP_START;
- uint32_t free_size = HEAP_SIZE;
-
-#ifdef ISR_STACK_START
- /* Interrupt stack explicitly specified */
- mbed_stack_isr_size = ISR_STACK_SIZE;
- mbed_stack_isr_start = ISR_STACK_START;
-#else
- /* Interrupt stack - reserve space at the end of the free block */
- mbed_stack_isr_size = ISR_STACK_SIZE;
- mbed_stack_isr_start = free_start + free_size - mbed_stack_isr_size;
- free_size -= mbed_stack_isr_size;
-#endif
-
- /* Heap - everything else */
- mbed_heap_size = free_size;
- mbed_heap_start = free_start;
}
#if defined (__CC_ARM)
@@ -704,7 +403,7 @@
void _main_init (void) {
osKernelInitialize();
#ifdef __MBED_CMSIS_RTOS_CM
- set_stack_heap();
+ set_main_stack();
#endif
osThreadCreate(&os_thread_def_main, NULL);
osKernelStart();
@@ -726,12 +425,15 @@
#else
+void * armcc_heap_base;
+void * armcc_heap_top;
+
int main(void);
void pre_main (void)
{
singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
- __rt_lib_init((unsigned)mbed_heap_start, (unsigned)(mbed_heap_start + mbed_heap_size));
+ __rt_lib_init((unsigned)armcc_heap_base, (unsigned)armcc_heap_top);
main();
}
@@ -746,10 +448,13 @@
__asm void __rt_entry (void) {
IMPORT __user_setup_stackheap
+ IMPORT armcc_heap_base
+ IMPORT armcc_heap_top
+ IMPORT _platform_post_stackheap_init
IMPORT os_thread_def_main
IMPORT osKernelInitialize
#ifdef __MBED_CMSIS_RTOS_CM
- IMPORT set_stack_heap
+ IMPORT set_main_stack
#endif
IMPORT osKernelStart
IMPORT osThreadCreate
@@ -763,12 +468,14 @@
* ARM Compiler ARM C and C++ Libraries and Floating-Point Support User Guide
*/
BL __user_setup_stackheap
- /* Ignore return value of __user_setup_stackheap since
- * this will be setup by set_stack_heap
- */
+ LDR R3,=armcc_heap_base
+ LDR R4,=armcc_heap_top
+ STR R0,[R3]
+ STR R2,[R4]
+ BL _platform_post_stackheap_init
BL osKernelInitialize
#ifdef __MBED_CMSIS_RTOS_CM
- BL set_stack_heap
+ BL set_main_stack
#endif
LDR R0,=os_thread_def_main
MOVS R1,#0
@@ -798,7 +505,6 @@
singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
malloc_mutex_id = osMutexCreate(osMutex(malloc_mutex));
env_mutex_id = osMutexCreate(osMutex(env_mutex));
- atexit(__libc_fini_array);
__libc_init_array();
main(0, NULL);
}
@@ -807,7 +513,7 @@
__asm (
"bl osKernelInitialize\n"
#ifdef __MBED_CMSIS_RTOS_CM
- "bl set_stack_heap\n"
+ "bl set_main_stack\n"
#endif
"ldr r0,=os_thread_def_main\n"
"movs r1,#0\n"
@@ -884,7 +590,7 @@
#endif
osKernelInitialize();
#ifdef __MBED_CMSIS_RTOS_CM
- set_stack_heap();
+ set_main_stack();
#endif
osThreadCreate(&os_thread_def_main, NULL);
osKernelStart();
@@ -898,3 +604,5 @@
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c Mon Nov 14 17:14:42 2016 -0600
@@ -39,6 +39,9 @@
* RTX User configuration part BEGIN
*---------------------------------------------------------------------------*/
+// Include per-target RTX config file
+#include "mbed_rtx.h"
+
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
//
// <h>Thread Configuration
@@ -48,23 +51,7 @@
// <i> Defines max. number of user threads that will run at the same time.
// <i> Default: 6
#ifndef OS_TASKCNT
-# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) || defined(TARGET_LPC4330) || defined(TARGET_LPC4337) || defined(TARGET_LPC1347) || defined(TARGET_K64F) || defined(TARGET_K66F)|| defined(TARGET_STM32F401RE)\
- || defined(TARGET_STM32F410RB) || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F407) || defined(TARGET_F407VG) || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_LPC11U68) \
- || defined(TARGET_STM32F411RE) || defined(TARGET_STM32F207ZG) || defined(TARGET_STM32F405RG) || defined(TARGET_K22F) || defined(TARGET_STM32F429ZI) || defined(TARGET_STM32F401VC) || defined(TARGET_MAX32610) || defined(TARGET_MAX32600) || defined(TARGET_MAX32620) || defined(TARGET_TEENSY3_1) \
- || defined(TARGET_STM32L152RE) || defined(TARGET_STM32F446RE) || defined(TARGET_STM32F446VE) || defined(TARGET_STM32F446ZE) || defined(TARGET_STM32L432KC) || defined(TARGET_STM32L476VG) || defined(TARGET_STM32L476RG) || defined(TARGET_STM32F469NI) || defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG) || defined(TARGET_STM32L152RC) \
- || defined(TARGET_EFM32GG_STK3700) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32PG_STK3401) || defined(TARGET_STM32F767ZI) \
- || defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NCS36510)
-# define OS_TASKCNT 14
-# elif defined(TARGET_LPC11U24) || defined(TARGET_STM32F303RE) || defined(TARGET_STM32F303K8) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) \
- || defined(TARGET_LPC812) || defined(TARGET_KL25Z) || defined(TARGET_KL26Z) || defined(TARGET_KL27Z) || defined(TARGET_KL05Z) || defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8) \
- || defined(TARGET_STM32F103RB) || defined(TARGET_LPC824) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) \
- || defined(TARGET_STM32L031K6) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) || defined(TARGET_STM32L073RZ) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F091RC) || defined(TARGET_NZ32_SC151) \
- || defined(TARGET_SSCI824) || defined(TARGET_STM32F030R8) || defined(TARGET_STM32F070RB) \
- || defined(TARGET_EFM32HG_STK3400) || defined(TARGET_MCU_NRF51822) || defined(TARGET_BEETLE) || defined(TARGET_MCU_NRF52832)
-# define OS_TASKCNT 6
-# else
-# error "no target defined"
-# endif
+ #error "no target defined"
#endif
#ifdef __MBED_CMSIS_RTOS_CM
@@ -84,28 +71,7 @@
// <o>Main Thread stack size [bytes] <64-32768:8><#/4>
#ifndef OS_MAINSTKSIZE
-# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) || defined(TARGET_LPC4330) || defined(TARGET_LPC4337) || defined(TARGET_LPC1347) || defined(TARGET_K64F) || defined(TARGET_K66F) ||defined(TARGET_STM32F401RE)\
- || defined(TARGET_STM32F410RB) || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F407) || defined(TARGET_F407VG) || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_LPC11U68) \
- || defined(TARGET_STM32F411RE) || defined(TARGET_STM32F405RG) || defined(TARGET_K22F) || defined(TARGET_STM32F429ZI) || defined(TARGET_STM32F401VC) || defined(TARGET_MAX32610) || defined(TARGET_MAX32600) || defined(TARGET_MAX32620) || defined(TARGET_TEENSY3_1) \
- || defined(TARGET_STM32L152RE) || defined(TARGET_STM32F446RE) || defined(TARGET_STM32F446VE) || defined(TARGET_STM32F446ZE) || defined(TARGET_STM32L432KC) || defined(TARGET_STM32L476VG) || defined(TARGET_STM32L476RG) || defined(TARGET_STM32F469NI) || defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG) || defined(TARGET_STM32L152RC) \
- ||defined(TARGET_EFM32GG_STK3700) || defined(TARGET_STM32F767ZI) || defined(TARGET_STM32F207ZG) \
- || defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NCS36510)
-# define OS_MAINSTKSIZE 256
-# elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) \
- || defined(TARGET_LPC812) || defined(TARGET_KL25Z) || defined(TARGET_KL26Z) || defined(TARGET_KL27Z) || defined(TARGET_KL05Z) || defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8) \
- || defined(TARGET_STM32F103RB) || defined(TARGET_LPC824) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F091RC) || defined(TARGET_NZ32_SC151) \
- || defined(TARGET_SSCI824) || defined(TARGET_STM32F030R8) || defined(TARGET_STM32F070RB) \
- || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32PG_STK3401)
-# define OS_MAINSTKSIZE 128
-# elif defined(TARGET_STM32F334R8) || defined(TARGET_STM32F303RE) || defined(TARGET_STM32F303K8) || defined(TARGET_STM32F334C8) \
- || defined(TARGET_STM32L031K6) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) || defined(TARGET_STM32L073RZ) \
- || defined(TARGET_EFM32HG_STK3400) || defined(TARGET_BEETLE)
-# define OS_MAINSTKSIZE 112
-# elif defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832)
-# define OS_MAINSTKSIZE 512
-# else
-# error "no target defined"
-# endif
+ #error "no target defined"
#endif
#ifndef __MBED_CMSIS_RTOS_CM
@@ -135,7 +101,11 @@
// <i> Initialize thread stack with watermark pattern for analyzing stack usage (current/maximum) in System and Thread Viewer.
// <i> Enabling this option increases significantly the execution time of osThreadCreate.
#ifndef OS_STKINIT
-#define OS_STKINIT 0
+ #if (defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED)
+ #define OS_STKINIT 1
+ #else
+ #define OS_STKINIT 0
+ #endif
#endif
// <o>Processor mode for thread execution
@@ -154,11 +124,7 @@
// <i> Cortex-M processors provide in most cases a SysTick timer that can be used as
// <i> as time-base for RTX.
#ifndef OS_SYSTICK
-# if defined(TARGET_MCU_NRF51822)
-# define OS_SYSTICK 0
-# else
-# define OS_SYSTICK 1
-# endif
+ #define OS_SYSTICK 1
#endif
//
// <o>RTOS Kernel Timer input clock frequency [Hz] <1-1000000000>
@@ -166,119 +132,7 @@
// <i> When the Cortex-M SysTick timer is used, the input clock
// <i> is on most systems identical with the core clock.
#ifndef OS_CLOCK
-# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_TEENSY3_1)
-# define OS_CLOCK 96000000
-
-# elif defined(TARGET_LPC1347) || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) || defined(TARGET_STM32F303RE)
-# define OS_CLOCK 72000000
-
-# elif defined(TARGET_STM32F303K8)
-# define OS_CLOCK 64000000
-
-# elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) || defined(TARGET_KL25Z) \
- || defined(TARGET_KL26Z) || defined(TARGET_KL27Z) || defined(TARGET_KL05Z) || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F051R8) || defined(TARGET_LPC11U68) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F091RC)
-# define OS_CLOCK 48000000
-
-# elif defined(TARGET_LPC812)
-# define OS_CLOCK 36000000
-
-# elif defined(TARGET_LPC824) || defined(TARGET_SSCI824)
-# define OS_CLOCK 30000000
-
-# elif defined(TARGET_STM32F100RB) || defined(TARGET_BEETLE)
-# define OS_CLOCK 24000000
-
-# elif defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) || defined(TARGET_K64F) || defined(TARGET_K66F)
-# define OS_CLOCK 120000000
-
-# elif defined(TARGET_LPC4330)
-# define OS_CLOCK 204000000
-
-# elif defined(TARGET_LPC4337)
-# define OS_CLOCK 204000000
-
-# elif defined(TARGET_STM32F407) || defined(TARGET_F407VG)
-# define OS_CLOCK 168000000
-
-# elif defined(TARGET_STM32F401RE)
-# define OS_CLOCK 84000000
-
-# elif defined(TARGET_STM32F411RE)
-# define OS_CLOCK 100000000
-
-# elif defined(TARGET_STM32F207ZG)
-# define OS_CLOCK 120000000
-
-# elif defined(TARGET_STM32F410RB)
-# define OS_CLOCK 100000000
-
-#elif defined(TARGET_STM32F103RB)
-# define OS_CLOCK 72000000
-
-#elif defined(TARGET_STM32F429ZI)
-# define OS_CLOCK 168000000
-
-#elif defined(TARGET_STM32F302R8)
-# define OS_CLOCK 72000000
-
-#elif defined(TARGET_STM32L031K6) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) || defined(TARGET_STM32L073RZ)
-# define OS_CLOCK 32000000
-
-#elif defined(TARGET_STM32F401VC)
-# define OS_CLOCK 84000000
-
-# elif defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG) || defined(TARGET_STM32F767ZI)
-# define OS_CLOCK 216000000
-
-#elif defined(TARGET_MAX32610) || defined(TARGET_MAX32600)
-# define OS_CLOCK 24000000
-
-#elif defined(TARGET_MAX32620)
-# define OS_CLOCK 96000000
-
-#elif defined(TARGET_NZ32_SC151)
-# define OS_CLOCK 32000000
-
-#elif defined(TARGET_STM32L152RE)
-# define OS_CLOCK 24000000
-
-#elif defined(TARGET_STM32F446RE) || defined(TARGET_STM32F446ZE) || defined(TARGET_STM32F446VE)
-# define OS_CLOCK 180000000
-
-#elif defined(TARGET_STM32F030R8)
-# define OS_CLOCK 48000000
-
-#elif defined(TARGET_STM32F070RB)
-# define OS_CLOCK 48000000
-
-#elif defined(TARGET_STM32L432KC) || defined(TARGET_STM32L476VG) || defined(TARGET_STM32L476RG) || defined(TARGET_K22F)
-# define OS_CLOCK 80000000
-
-#elif defined(TARGET_STM32F469NI)
-# define OS_CLOCK 168000000
-
-#elif defined(TARGET_STM32L152RC)
-# define OS_CLOCK 24000000
-
-#elif defined(TARGET_EFM32)
-# include "clocking.h"
-# define OS_CLOCK REFERENCE_FREQUENCY
-
-#elif defined(TARGET_MCU_NRF51822)
-# define OS_CLOCK 32768
-
-#elif defined(TARGET_MCU_NRF52832)
-# define OS_CLOCK 64000000
-
-#elif defined(TARGET_NUMAKER_PFM_NUC472)
-# define OS_CLOCK 84000000
-
-#elif defined(TARGET_NCS36510)
-# define OS_CLOCK 32000000
-
-# else
-# error "no target defined"
-# endif
+ #error "no target defined"
#endif
// <o>RTX Timer tick interval value [us] <1-1000000>
@@ -408,6 +262,15 @@
}
/*----------------------------------------------------------------------------
+ * RTX Hooks
+ *---------------------------------------------------------------------------*/
+extern void thread_terminate_hook(osThreadId id);
+
+void sysThreadTerminate(osThreadId id) {
+ thread_terminate_hook(id);
+}
+
+/*----------------------------------------------------------------------------
* RTX Configuration Functions
*---------------------------------------------------------------------------*/
--- a/rtx/TARGET_CORTEX_M/RTX_Config.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/RTX_Config.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -77,3 +80,5 @@
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c Mon Nov 14 17:14:42 2016 -0600
@@ -164,7 +164,9 @@
SVC_ContextSave
TST LR,#0x10 ; is it extended frame?
+#if (__FPU_PRESENT == 1)
VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs
+#endif
MOVEQ R0,#0x01 ; os_tsk->stack_frame val
MOVNE R0,#0x00
STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val
@@ -184,7 +186,9 @@
CMP R0,#0 ; Basic/Extended Stack Frame
MVNEQ LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value
MVNNE LR,#:NOT:0xFFFFFFED
+#if (__FPU_PRESENT == 1)
VLDMIANE R12!,{S16-S31} ; restore VFP hi-registers
+#endif
MSR PSP,R12 ; Write PSP
SVC_Exit
@@ -247,7 +251,9 @@
MRS R12,PSP ; Read PSP
TST LR,#0x10 ; is it extended frame?
+#if (__FPU_PRESENT == 1)
VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs
+#endif
MOVEQ R0,#0x01 ; os_tsk->stack_frame val
MOVNE R0,#0x00
STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val
@@ -266,7 +272,9 @@
CMP R0,#0 ; Basic/Extended Stack Frame
MVNEQ LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value
MVNNE LR,#:NOT:0xFFFFFFED
+#if (__FPU_PRESENT == 1)
VLDMIANE R12!,{S16-S31} ; restore VFP hi-regs
+#endif
MSR PSP,R12 ; Write PSP
Sys_Exit
--- a/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S Mon Nov 14 17:14:42 2016 -0600
@@ -188,8 +188,12 @@
SVC_ContextSave:
TST LR,#0x10 /* is it extended frame? */
+#if (__FPU_PRESENT == 1)
ITTE EQ
VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */
+#else
+ ITE EQ
+#endif
MOVEQ R0,#0x01 /* os_tsk->stack_frame val */
MOVNE R0,#0x00
STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */
@@ -207,10 +211,16 @@
LDMIA R12!,{R4-R11} /* Restore New Context */
LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */
CMP R0,#0 /* Basic/Extended Stack Frame */
+#if (__FPU_PRESENT == 1)
ITEE EQ
+#else
+ ITE EQ
+#endif
MVNEQ LR,#~0xFFFFFFFD /* set EXC_RETURN value */
MVNNE LR,#~0xFFFFFFED
+#if (__FPU_PRESENT == 1)
VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */
+#endif
MSR PSP,R12 /* Write PSP */
SVC_Exit:
@@ -274,8 +284,12 @@
MRS R12,PSP /* Read PSP */
TST LR,#0x10 /* is it extended frame? */
+#if (__FPU_PRESENT == 1)
ITTE EQ
VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */
+#else
+ ITE EQ
+#endif
MOVEQ R0,#0x01 /* os_tsk->stack_frame val */
MOVNE R0,#0x00
STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */
@@ -292,10 +306,16 @@
LDMIA R12!,{R4-R11} /* Restore New Context */
LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */
CMP R0,#0 /* Basic/Extended Stack Frame */
+#if (__FPU_PRESENT == 1)
ITEE EQ
+#else
+ ITE EQ
+#endif
MVNEQ LR,#~0xFFFFFFFD /* set EXC_RETURN value */
MVNNE LR,#~0xFFFFFFED
+#if (__FPU_PRESENT == 1)
VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */
+#endif
MSR PSP,R12 /* Write PSP */
Sys_Exit:
--- a/rtx/TARGET_CORTEX_M/cmsis_os.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/cmsis_os.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/* ----------------------------------------------------------------------
* $Date: 5. February 2013
* $Revision: V1.02
@@ -74,16 +77,22 @@
#ifdef __MBED_CMSIS_RTOS_CM
-/* Single thread - disable timers and set task count to one */
-#if defined(MBED_RTOS_SINGLE_THREAD)
-#define OS_TASKCNT 1
-#define OS_TIMERS 0
+/* If os timers macro is set to 0, there's no timer thread created, therefore
+ * main thread has tid 0x01
+ */
+#if defined(OS_TIMERS) && (OS_TIMERS == 0)
+#define MAIN_THREAD_ID 0x01
+#else
+#define MAIN_THREAD_ID 0x02
+#endif
#endif
+#if defined(TARGET_XDOT_L151CC)
+#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE/2)
+#else
+#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4)
#endif
-#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4)
-
#define osCMSIS 0x10002U ///< CMSIS-RTOS API version (main [31:16] .sub [15:0])
#define osCMSIS_RTX ((4<<16)|80) ///< RTOS identification and version (main [31:16] .sub [15:0])
@@ -99,6 +108,7 @@
#define osFeature_Semaphore 65535 ///< Maximum count for \ref osSemaphoreCreate function
#define osFeature_Wait 0 ///< osWait not available
#define osFeature_SysTick 1 ///< osKernelSysTick functions available
+#define osFeature_ThreadEnum 1 ///< Thread enumeration available
#if defined (__CC_ARM)
#define os_InRegs __value_in_regs // Compiler specific: force struct in registers
@@ -159,6 +169,16 @@
osTimerPeriodic = 1 ///< repeating timer
} os_timer_type;
+typedef enum {
+ osThreadInfoState,
+ osThreadInfoStackSize,
+ osThreadInfoStackMax,
+ osThreadInfoEntry,
+ osThreadInfoArg,
+
+ osThreadInfo_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization.
+} osThreadInfo;
+
/// Entry point of a thread.
typedef void (*os_pthread) (void const *argument);
@@ -188,6 +208,8 @@
/// Mail ID identifies the mail queue (pointer to a mail queue control block).
typedef struct os_mailQ_cb *osMailQId;
+/// Thread enumeration ID identifies the enumeration (pointer to a thread enumeration control block).
+typedef uint32_t *osThreadEnumId;
/// Thread Definition structure contains startup information of a thread.
typedef struct os_thread_def {
@@ -358,6 +380,13 @@
uint8_t osThreadGetState (osThreadId thread_id);
#endif
+/// Get into from an active thread.
+/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in] info information to read.
+/// \return current state of the thread function.
+/// \return requested info that includes the status code.
+os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info);
+
// ==== Generic Wait Functions ====
/// Wait for Timeout (Time Delay).
@@ -680,6 +709,26 @@
#endif // Mail Queues available
+// ==== Thread Enumeration Functions ====
+
+#if (defined (osFeature_ThreadEnum) && (osFeature_ThreadEnum != 0)) // Thread enumeration available
+
+/// Start a thread enumeration.
+/// \return an enumeration ID or NULL on error.
+osThreadEnumId _osThreadsEnumStart(void);
+
+/// Get the next task ID in the enumeration.
+/// \return a thread ID or NULL on if the end of the enumeration has been reached.
+osThreadId _osThreadEnumNext(osThreadEnumId enum_id);
+
+/// Free the enumeration structure.
+/// \param[in] enum_id pointer to the enumeration ID that was obtained with \ref _osThreadsEnumStart.
+/// \return status code that indicates the execution status of the function.
+osStatus _osThreadEnumFree(osThreadEnumId enum_id);
+
+#endif // Thread Enumeration available
+
+
// ==== RTX Extensions ====
/// Suspend the RTX task scheduler.
@@ -696,3 +745,5 @@
#endif
#endif // _CMSIS_OS_H
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_CMSIS.c Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_CMSIS.c Mon Nov 14 17:14:42 2016 -0600
@@ -392,6 +392,10 @@
extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ;
extern osMessageQId osMessageQId_osTimerMessageQ;
+// Thread creation and destruction
+osMutexDef(osThreadMutex);
+osMutexId osMutexId_osThreadMutex;
+void sysThreadTerminate(osThreadId id);
// ==== Helper Functions ====
@@ -490,6 +494,8 @@
// Create OS Timers resources (Message Queue & Thread)
osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL);
osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL, NULL);
+ // Initialize thread mutex
+ osMutexId_osThreadMutex = osMutexCreate(osMutex(osThreadMutex));
}
sysThreadError(osOK);
@@ -546,7 +552,7 @@
/// Initialize the RTOS Kernel for creating objects
osStatus osKernelInitialize (void) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
if ((__get_CONTROL() & 1U) == 0U) { // Privileged mode
@@ -560,7 +566,7 @@
osStatus osKernelStart (void) {
uint32_t stack[8];
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
@@ -601,7 +607,7 @@
/// Check if the RTOS kernel is already started
int32_t osKernelRunning (void) {
- if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {
+ if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {
// in ISR or Privileged
return (int32_t)os_running;
} else {
@@ -611,7 +617,7 @@
/// Get the RTOS kernel system timer counter
uint32_t osKernelSysTick (void) {
- if (__get_IPSR() != 0U) { return 0U; } // Not allowed in ISR
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { return 0U; } // Not allowed in ISR
return __svcKernelSysTick();
}
@@ -632,6 +638,7 @@
SVC_0_1(svcThreadYield, osStatus, RET_osStatus)
SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus)
SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority)
+SVC_2_3(svcThreadGetInfo, os_InRegs osEvent, osThreadId, osThreadInfo, RET_osEvent)
// Thread Service Calls
@@ -791,6 +798,67 @@
return (osPriority)(ptcb->prio - 1 + osPriorityIdle);
}
+/// Get info from an active thread
+os_InRegs osEvent_type svcThreadGetInfo (osThreadId thread_id, osThreadInfo info) {
+ P_TCB ptcb;
+ osEvent ret;
+ ret.status = osOK;
+
+ ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
+ if (ptcb == NULL) {
+ ret.status = osErrorValue;
+ return osEvent_ret_status;
+ }
+
+ if (osThreadInfoStackSize == info) {
+ uint32_t size;
+ size = ptcb->priv_stack;
+ if (0 == size) {
+ // This is an OS task - always a fixed size
+ size = os_stackinfo & 0x3FFFF;
+ }
+ ret.value.v = size;
+ return osEvent_ret_value;
+ }
+
+ if (osThreadInfoStackMax == info) {
+ uint32_t i;
+ uint32_t *stack_ptr;
+ uint32_t stack_size;
+ if (!(os_stackinfo & (1 << 28))) {
+ // Stack init must be turned on for max stack usage
+ ret.status = osErrorResource;
+ return osEvent_ret_status;
+ }
+ stack_ptr = (uint32_t*)ptcb->stack;
+ stack_size = ptcb->priv_stack;
+ if (0 == stack_size) {
+ // This is an OS task - always a fixed size
+ stack_size = os_stackinfo & 0x3FFFF;
+ }
+ for (i = 1; i <stack_size / 4; i++) {
+ if (stack_ptr[i] != MAGIC_PATTERN) {
+ break;
+ }
+ }
+ ret.value.v = stack_size - i * 4;
+ return osEvent_ret_value;
+ }
+
+ if (osThreadInfoEntry == info) {
+ ret.value.p = (void*)ptcb->ptask;
+ return osEvent_ret_value;
+ }
+
+ if (osThreadInfoArg == info) {
+ ret.value.p = (void*)ptcb->argv;
+ return osEvent_ret_value;
+ }
+
+ // Unsupported option so return error
+ ret.status = osErrorParameter;
+ return osEvent_ret_status;
+}
// Thread Public API
@@ -799,20 +867,25 @@
return osThreadContextCreate(thread_def, argument, NULL);
}
osThreadId osThreadContextCreate (const osThreadDef_t *thread_def, void *argument, void *context) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return NULL; // Not allowed in ISR
}
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
// Privileged and not running
return svcThreadCreate(thread_def, argument, context);
} else {
- return __svcThreadCreate(thread_def, argument, context);
+ osThreadId id;
+ osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+ // Thread mutex must be held when a thread is created or terminated
+ id = __svcThreadCreate(thread_def, argument, context);
+ osMutexRelease(osMutexId_osThreadMutex);
+ return id;
}
}
/// Return the thread ID of the current running thread
osThreadId osThreadGetId (void) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return NULL; // Not allowed in ISR
}
return __svcThreadGetId();
@@ -820,15 +893,21 @@
/// Terminate execution of a thread and remove it from ActiveThreads
osStatus osThreadTerminate (osThreadId thread_id) {
- if (__get_IPSR() != 0U) {
+ osStatus status;
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
- return __svcThreadTerminate(thread_id);
+ osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+ sysThreadTerminate(thread_id);
+ // Thread mutex must be held when a thread is created or terminated
+ status = __svcThreadTerminate(thread_id);
+ osMutexRelease(osMutexId_osThreadMutex);
+ return status;
}
/// Pass control to next thread that is in state READY
osStatus osThreadYield (void) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
return __svcThreadYield();
@@ -836,7 +915,7 @@
/// Change priority of an active thread
osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
return __svcThreadSetPriority(thread_id, priority);
@@ -844,7 +923,7 @@
/// Get current priority of an active thread
osPriority osThreadGetPriority (osThreadId thread_id) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osPriorityError; // Not allowed in ISR
}
return __svcThreadGetPriority(thread_id);
@@ -852,8 +931,15 @@
/// INTERNAL - Not Public
/// Auto Terminate Thread on exit (used implicitly when thread exists)
-__NO_RETURN void osThreadExit (void) {
- __svcThreadTerminate(__svcThreadGetId());
+__NO_RETURN void osThreadExit (void) {
+ osThreadId id;
+ // Thread mutex must be held when a thread is created or terminated
+ // Note - the mutex will be released automatically by the os when
+ // the thread is terminated
+ osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+ id = __svcThreadGetId();
+ sysThreadTerminate(id);
+ __svcThreadTerminate(id);
for (;;); // Should never come here
}
@@ -862,7 +948,7 @@
uint8_t osThreadGetState (osThreadId thread_id) {
P_TCB ptcb;
- if (__get_IPSR() != 0U) return osErrorISR; // Not allowed in ISR
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) return osErrorISR; // Not allowed in ISR
ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
if (ptcb == NULL) return INACTIVE;
@@ -871,6 +957,49 @@
}
#endif
+/// Get the requested info from the specified active thread
+os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info) {
+ osEvent ret;
+
+ if (__get_IPSR() != 0U) { // Not allowed in ISR
+ ret.status = osErrorISR;
+ return ret;
+ }
+ return __svcThreadGetInfo(thread_id, info);
+}
+
+osThreadEnumId _osThreadsEnumStart() {
+ static uint32_t thread_enum_index;
+ osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+ thread_enum_index = 0;
+ return &thread_enum_index;
+}
+
+osThreadId _osThreadEnumNext(osThreadEnumId enum_id) {
+ uint32_t i;
+ osThreadId id = NULL;
+ uint32_t *index = (uint32_t*)enum_id;
+ for (i = *index; i < os_maxtaskrun; i++) {
+ if (os_active_TCB[i] != NULL) {
+ id = (osThreadId)os_active_TCB[i];
+ break;
+ }
+ }
+ if (i == os_maxtaskrun) {
+ // Include the idle task at the end of the enumeration
+ id = &os_idle_TCB;
+ }
+ *index = i + 1;
+ return id;
+}
+
+osStatus _osThreadEnumFree(osThreadEnumId enum_id) {
+ uint32_t *index = (uint32_t*)enum_id;
+ *index = 0;
+ osMutexRelease(osMutexId_osThreadMutex);
+ return osOK;
+}
+
// ==== Generic Wait Functions ====
// Generic Wait Service Calls declarations
@@ -911,7 +1040,7 @@
/// Wait for Timeout (Time Delay)
osStatus osDelay (uint32_t millisec) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
return __svcDelay(millisec);
@@ -925,7 +1054,7 @@
ret.status = osErrorOS;
return ret;
#else
- if (__get_IPSR() != 0U) { // Not allowed in ISR
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // Not allowed in ISR
ret.status = osErrorISR;
return ret;
}
@@ -1208,7 +1337,7 @@
/// Create timer
osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return NULL; // Not allowed in ISR
}
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1221,7 +1350,7 @@
/// Start or restart timer
osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
return __svcTimerStart(timer_id, millisec);
@@ -1229,7 +1358,7 @@
/// Stop timer
osStatus osTimerStop (osTimerId timer_id) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
return __svcTimerStop(timer_id);
@@ -1237,7 +1366,7 @@
/// Delete timer
osStatus osTimerDelete (osTimerId timer_id) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
return __svcTimerDelete(timer_id);
@@ -1374,7 +1503,7 @@
/// Set the specified Signal Flags of an active thread
int32_t osSignalSet (osThreadId thread_id, int32_t signals) {
- if (__get_IPSR() != 0U) { // in ISR
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
return isrSignalSet(thread_id, signals);
} else { // in Thread
return __svcSignalSet(thread_id, signals);
@@ -1383,7 +1512,7 @@
/// Clear the specified Signal Flags of an active thread
int32_t osSignalClear (osThreadId thread_id, int32_t signals) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return (int32_t)0x80000000U; // Not allowed in ISR
}
return __svcSignalClear(thread_id, signals);
@@ -1393,7 +1522,7 @@
os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) {
osEvent ret;
- if (__get_IPSR() != 0U) { // Not allowed in ISR
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // Not allowed in ISR
ret.status = osErrorISR;
return ret;
}
@@ -1505,7 +1634,7 @@
/// Create and Initialize a Mutex object
osMutexId osMutexCreate (const osMutexDef_t *mutex_def) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return NULL; // Not allowed in ISR
}
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1518,7 +1647,7 @@
/// Wait until a Mutex becomes available
osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
return __svcMutexWait(mutex_id, millisec);
@@ -1526,7 +1655,7 @@
/// Release a Mutex that was obtained with osMutexWait
osStatus osMutexRelease (osMutexId mutex_id) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
return __svcMutexRelease(mutex_id);
@@ -1534,7 +1663,7 @@
/// Delete a Mutex that was created by osMutexCreate
osStatus osMutexDelete (osMutexId mutex_id) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
return __svcMutexDelete(mutex_id);
@@ -1672,7 +1801,7 @@
/// Create and Initialize a Semaphore object
osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return NULL; // Not allowed in ISR
}
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1685,7 +1814,7 @@
/// Wait until a Semaphore becomes available
int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return -1; // Not allowed in ISR
}
return __svcSemaphoreWait(semaphore_id, millisec);
@@ -1693,16 +1822,16 @@
/// Release a Semaphore
osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) {
- if (__get_IPSR() != 0U) { // in ISR
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
return isrSemaphoreRelease(semaphore_id);
- } else { // in Thread
+ } else { // in Thread
return __svcSemaphoreRelease(semaphore_id);
}
}
/// Delete a Semaphore that was created by osSemaphoreCreate
osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return osErrorISR; // Not allowed in ISR
}
return __svcSemaphoreDelete(semaphore_id);
@@ -1785,7 +1914,7 @@
/// Create and Initialize memory pool
osPoolId osPoolCreate (const osPoolDef_t *pool_def) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return NULL; // Not allowed in ISR
}
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1798,7 +1927,7 @@
/// Allocate a memory block from a memory pool
void *osPoolAlloc (osPoolId pool_id) {
- if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
+ if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
return sysPoolAlloc(pool_id);
} else { // in Thread
return __sysPoolAlloc(pool_id);
@@ -1809,7 +1938,7 @@
void *osPoolCAlloc (osPoolId pool_id) {
void *mem;
- if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
+ if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
mem = sysPoolAlloc(pool_id);
} else { // in Thread
mem = __sysPoolAlloc(pool_id);
@@ -1822,7 +1951,7 @@
/// Return an allocated memory block back to a specific memory pool
osStatus osPoolFree (osPoolId pool_id, void *block) {
- if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
+ if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
return sysPoolFree(pool_id, block);
} else { // in Thread
return __sysPoolFree(pool_id, block);
@@ -1962,7 +2091,7 @@
/// Create and Initialize Message Queue
osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return NULL; // Not allowed in ISR
}
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1975,7 +2104,7 @@
/// Put a Message to a Queue
osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
- if (__get_IPSR() != 0U) { // in ISR
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
return isrMessagePut(queue_id, info, millisec);
} else { // in Thread
return __svcMessagePut(queue_id, info, millisec);
@@ -1984,7 +2113,7 @@
/// Get a Message or Wait for a Message from a Queue
os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) {
- if (__get_IPSR() != 0U) { // in ISR
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
return isrMessageGet(queue_id, millisec);
} else { // in Thread
return __svcMessageGet(queue_id, millisec);
@@ -2121,7 +2250,7 @@
/// Create and Initialize mail queue
osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) {
- if (__get_IPSR() != 0U) {
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
return NULL; // Not allowed in ISR
}
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -2134,7 +2263,7 @@
/// Allocate a memory block from a mail
void *osMailAlloc (osMailQId queue_id, uint32_t millisec) {
- if (__get_IPSR() != 0U) { // in ISR
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
return sysMailAlloc(queue_id, millisec, 1U);
} else { // in Thread
return __sysMailAlloc(queue_id, millisec, 0U);
@@ -2146,7 +2275,7 @@
void *pool;
void *mem;
- if (__get_IPSR() != 0U) { // in ISR
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
mem = sysMailAlloc(queue_id, millisec, 1U);
} else { // in Thread
mem = __sysMailAlloc(queue_id, millisec, 0U);
@@ -2161,7 +2290,7 @@
/// Free a memory block from a mail
osStatus osMailFree (osMailQId queue_id, void *mail) {
- if (__get_IPSR() != 0U) { // in ISR
+ if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
return sysMailFree(queue_id, mail, 1U);
} else { // in Thread
return __sysMailFree(queue_id, mail, 0U);
--- a/rtx/TARGET_CORTEX_M/rt_Event.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Event.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -44,3 +47,5 @@
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_HAL_CM.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_HAL_CM.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -53,11 +56,19 @@
#endif
#ifndef __CMSIS_GENERIC
+
+__attribute__((always_inline)) static inline U32 __get_PRIMASK(void)
+{
+ register U32 primask __asm("primask");
+ return primask;
+}
+
#define __DMB() do {\
__schedule_barrier();\
__dmb(0xF);\
__schedule_barrier();\
} while (0)
+
#endif
#elif defined (__GNUC__) /* GNU Compiler */
@@ -77,6 +88,14 @@
#ifndef __CMSIS_GENERIC
+__attribute__((always_inline)) static inline U32 __get_PRIMASK(void)
+{
+ U32 result;
+
+ __asm volatile ("mrs %0, primask" : "=r" (result));
+ return result;
+}
+
__attribute__((always_inline)) static inline void __enable_irq(void)
{
__asm volatile ("cpsie i");
@@ -101,7 +120,7 @@
__attribute__(( always_inline)) static inline U8 __clz(U32 value)
{
U8 result;
-
+
__asm volatile ("clz %0, %1" : "=r" (result) : "r" (value));
return(result);
}
@@ -122,6 +141,14 @@
#ifndef __CMSIS_GENERIC
+static inline U32 __get_PRIMASK(void)
+{
+ U32 result;
+
+ __asm volatile ("mrs %0, primask" : "=r" (result));
+ return result;
+}
+
static inline void __enable_irq(void)
{
__asm volatile ("cpsie i");
@@ -203,8 +230,22 @@
#define rt_inc(p) while(__strex((__ldrex(p)+1U),p))
#define rt_dec(p) while(__strex((__ldrex(p)-1U),p))
#else
- #define rt_inc(p) __disable_irq();(*p)++;__enable_irq();
- #define rt_dec(p) __disable_irq();(*p)--;__enable_irq();
+ #define rt_inc(p) do {\
+ U32 primask = __get_PRIMASK();\
+ __disable_irq();\
+ (*p)++;\
+ if (!primask) {\
+ __enable_irq();\
+ }\
+ } while (0)
+ #define rt_dec(p) do {\
+ U32 primask = __get_PRIMASK();\
+ __disable_irq();\
+ (*p)--;\
+ if (!primask) {\
+ __enable_irq();\
+ }\
+ } while (0)
#endif
__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) {
@@ -220,6 +261,7 @@
if (c2 == size) { c2 = 0U; }
} while (__strex(c2, first));
#else
+ U32 primask = __get_PRIMASK();
__disable_irq();
if ((cnt = *count) < size) {
*count = (U8)(cnt+1U);
@@ -227,7 +269,9 @@
if (c2 == size) { c2 = 0U; }
*first = (U8)c2;
}
- __enable_irq ();
+ if (!primask) {
+ __enable_irq ();
+ }
#endif
return (cnt);
}
@@ -296,3 +340,5 @@
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_List.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_List.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -65,3 +68,5 @@
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Mailbox.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Mailbox.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -46,3 +49,5 @@
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_MemBox.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_MemBox.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -43,3 +46,5 @@
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Memory.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Memory.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -42,3 +45,5 @@
extern U32 rt_init_mem (void *pool, U32 size);
extern void *rt_alloc_mem (void *pool, U32 size);
extern U32 rt_free_mem (void *pool, void *mem);
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Mutex.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Mutex.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -42,3 +45,5 @@
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -56,3 +59,5 @@
#endif
#endif
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Robin.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Robin.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -43,3 +46,5 @@
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Semaphore.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Semaphore.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -44,3 +47,5 @@
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_System.c Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_System.c Mon Nov 14 17:14:42 2016 -0600
@@ -313,10 +313,22 @@
/*--------------------------- rt_stk_check ----------------------------------*/
__weak void rt_stk_check (void) {
+#ifdef __MBED_CMSIS_RTOS_CM
+ /* Check for stack overflow. */
+ if (os_tsk.run->task_id == MAIN_THREAD_ID) {
+ // TODO: For the main thread the check should be done against the main heap pointer
+ } else {
+ if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
+ (os_tsk.run->stack[0] != MAGIC_WORD)) {
+ os_error (OS_ERR_STK_OVF);
+ }
+ }
+#else
if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
(os_tsk.run->stack[0] != MAGIC_WORD)) {
os_error (OS_ERR_STK_OVF);
}
+#endif
}
/*----------------------------------------------------------------------------
--- a/rtx/TARGET_CORTEX_M/rt_System.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_System.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -50,3 +53,5 @@
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Task.c Wed Nov 09 12:22:14 2016 -0600 +++ b/rtx/TARGET_CORTEX_M/rt_Task.c Mon Nov 14 17:14:42 2016 -0600 @@ -247,6 +247,7 @@ task_context->task_id = (U8)i; /* Pass parameter 'argv' to 'rt_init_context' */ task_context->msg = argv; + task_context->argv = argv; /* For 'size == 0' system allocates the user stack from the memory pool. */ rt_init_context (task_context, (U8)(prio_stksz & 0xFFU), task);
--- a/rtx/TARGET_CORTEX_M/rt_Task.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Task.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -81,3 +84,5 @@
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Time.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Time.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -45,3 +48,5 @@
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Timer.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Timer.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -43,3 +46,5 @@
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_TypeDef.h Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_TypeDef.h Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
@@ -79,6 +82,7 @@
/* Task entry point used for uVision debugger */
FUNCP ptask; /* Task entry address */
+ void *argv; /* Task argument */
void *context; /* Pointer to thread context */
} *P_TCB;
#define TCB_STACKF 37 /* 'stack_frame' offset */
@@ -167,3 +171,5 @@
#define NULL ((void *) 0)
#endif
+
+/** @}*/
