Official mbed Real Time Operating System based on the RTX implementation of the CMSIS-RTOS API open standard.
Dependents: Assignment_3__Embedded_Software
Fork of mbed-rtos by
Diff: rtos/Thread.cpp
- Revision:
- 118:6635230e06ba
- Parent:
- 115:11950e007d8a
- Child:
- 119:19af2d39a542
--- a/rtos/Thread.cpp Mon May 23 11:00:15 2016 +0100 +++ b/rtos/Thread.cpp Mon Jul 25 14:12:24 2016 +0100 @@ -21,7 +21,7 @@ */ #include "Thread.h" -#include "mbed_error.h" +#include "mbed.h" #include "rtos_idle.h" // rt_tid2ptcb is an internal function which we exposed to get TCB for thread id @@ -32,34 +32,81 @@ namespace rtos { -Thread::Thread(void (*task)(void const *argument), void *argument, - osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) { +void Thread::constructor(osPriority priority, + uint32_t stack_size, unsigned char *stack_pointer) { + _tid = 0; + _dynamic_stack = (stack_pointer == NULL); + #if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) - _thread_def.pthread = task; _thread_def.tpriority = priority; _thread_def.stacksize = stack_size; - if (stack_pointer != NULL) { - _thread_def.stack_pointer = (uint32_t*)stack_pointer; - _dynamic_stack = false; - } else { - _thread_def.stack_pointer = new uint32_t[stack_size/sizeof(uint32_t)]; + _thread_def.stack_pointer = (uint32_t*)stack_pointer; +#endif +} + +void Thread::constructor(Callback<void()> task, + osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) { + constructor(priority, stack_size, stack_pointer); + + switch (start(task)) { + case osErrorResource: + error("OS ran out of threads!\n"); + break; + case osErrorParameter: + error("Thread already running!\n"); + break; + case osErrorNoMemory: + error("Error allocating the stack memory\n"); + default: + break; + } +} + +osStatus Thread::start(Callback<void()> task) { + if (_tid != 0) { + return osErrorParameter; + } + +#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) + _thread_def.pthread = (void (*)(const void *))Callback<void()>::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) - error("Error allocating the stack memory\n"); - _dynamic_stack = true; + return osErrorNoMemory; } - + //Fill the stack with a magic word for maximum usage checking - for (uint32_t i = 0; i < (stack_size / sizeof(uint32_t)); i++) { + for (uint32_t i = 0; i < (_thread_def.stacksize / sizeof(uint32_t)); i++) { _thread_def.stack_pointer[i] = 0xE25A2EA5; } #endif - _tid = osThreadCreate(&_thread_def, argument); + _task = task; + _tid = osThreadCreate(&_thread_def, &_task); + if (_tid == NULL) { + if (_dynamic_stack) delete[] (_thread_def.stack_pointer); + return osErrorResource; + } + return osOK; } osStatus Thread::terminate() { return osThreadTerminate(_tid); } +osStatus Thread::join() { + while (true) { + uint8_t state = get_state(); + if (state == Thread::Inactive || state == osErrorParameter) { + return osOK; + } + + osStatus status = yield(); + if (status != osOK) { + return status; + } + } +} + osStatus Thread::set_priority(osPriority priority) { return osThreadSetPriority(_tid, priority); }