TeamGyro / mbed-rtos

Dependents:   GYRO_MPU6050 Bluetooth_Powered_Multimeter_Using_STM32F429_and_RTOS fyp

Committer:
guilhemMBED
Date:
Mon Feb 03 13:41:14 2020 +0000
Revision:
0:a7c449cd2d5a
previous version;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
guilhemMBED 0:a7c449cd2d5a 1 /* mbed Microcontroller Library
guilhemMBED 0:a7c449cd2d5a 2 * Copyright (c) 2006-2012 ARM Limited
guilhemMBED 0:a7c449cd2d5a 3 *
guilhemMBED 0:a7c449cd2d5a 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
guilhemMBED 0:a7c449cd2d5a 5 * of this software and associated documentation files (the "Software"), to deal
guilhemMBED 0:a7c449cd2d5a 6 * in the Software without restriction, including without limitation the rights
guilhemMBED 0:a7c449cd2d5a 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
guilhemMBED 0:a7c449cd2d5a 8 * copies of the Software, and to permit persons to whom the Software is
guilhemMBED 0:a7c449cd2d5a 9 * furnished to do so, subject to the following conditions:
guilhemMBED 0:a7c449cd2d5a 10 *
guilhemMBED 0:a7c449cd2d5a 11 * The above copyright notice and this permission notice shall be included in
guilhemMBED 0:a7c449cd2d5a 12 * all copies or substantial portions of the Software.
guilhemMBED 0:a7c449cd2d5a 13 *
guilhemMBED 0:a7c449cd2d5a 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
guilhemMBED 0:a7c449cd2d5a 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
guilhemMBED 0:a7c449cd2d5a 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
guilhemMBED 0:a7c449cd2d5a 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
guilhemMBED 0:a7c449cd2d5a 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
guilhemMBED 0:a7c449cd2d5a 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
guilhemMBED 0:a7c449cd2d5a 20 * SOFTWARE.
guilhemMBED 0:a7c449cd2d5a 21 */
guilhemMBED 0:a7c449cd2d5a 22 #include "rtos/Thread.h"
guilhemMBED 0:a7c449cd2d5a 23
guilhemMBED 0:a7c449cd2d5a 24 #include "mbed.h"
guilhemMBED 0:a7c449cd2d5a 25 #include "rtos/rtos_idle.h"
guilhemMBED 0:a7c449cd2d5a 26
guilhemMBED 0:a7c449cd2d5a 27 // rt_tid2ptcb is an internal function which we exposed to get TCB for thread id
guilhemMBED 0:a7c449cd2d5a 28 #undef NULL //Workaround for conflicting macros in rt_TypeDef.h and stdio.h
guilhemMBED 0:a7c449cd2d5a 29 #include "rt_TypeDef.h"
guilhemMBED 0:a7c449cd2d5a 30
guilhemMBED 0:a7c449cd2d5a 31 extern "C" P_TCB rt_tid2ptcb(osThreadId thread_id);
guilhemMBED 0:a7c449cd2d5a 32
guilhemMBED 0:a7c449cd2d5a 33
guilhemMBED 0:a7c449cd2d5a 34 static void (*terminate_hook)(osThreadId id) = 0;
guilhemMBED 0:a7c449cd2d5a 35 extern "C" void thread_terminate_hook(osThreadId id)
guilhemMBED 0:a7c449cd2d5a 36 {
guilhemMBED 0:a7c449cd2d5a 37 if (terminate_hook != (void (*)(osThreadId))NULL) {
guilhemMBED 0:a7c449cd2d5a 38 terminate_hook(id);
guilhemMBED 0:a7c449cd2d5a 39 }
guilhemMBED 0:a7c449cd2d5a 40 }
guilhemMBED 0:a7c449cd2d5a 41
guilhemMBED 0:a7c449cd2d5a 42 namespace rtos {
guilhemMBED 0:a7c449cd2d5a 43
guilhemMBED 0:a7c449cd2d5a 44 void Thread::constructor(osPriority priority,
guilhemMBED 0:a7c449cd2d5a 45 uint32_t stack_size, unsigned char *stack_pointer) {
guilhemMBED 0:a7c449cd2d5a 46 _tid = 0;
guilhemMBED 0:a7c449cd2d5a 47 _dynamic_stack = (stack_pointer == NULL);
guilhemMBED 0:a7c449cd2d5a 48
guilhemMBED 0:a7c449cd2d5a 49 #if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
guilhemMBED 0:a7c449cd2d5a 50 _thread_def.tpriority = priority;
guilhemMBED 0:a7c449cd2d5a 51 _thread_def.stacksize = stack_size;
guilhemMBED 0:a7c449cd2d5a 52 _thread_def.stack_pointer = (uint32_t*)stack_pointer;
guilhemMBED 0:a7c449cd2d5a 53 #endif
guilhemMBED 0:a7c449cd2d5a 54 }
guilhemMBED 0:a7c449cd2d5a 55
guilhemMBED 0:a7c449cd2d5a 56 void Thread::constructor(Callback<void()> task,
guilhemMBED 0:a7c449cd2d5a 57 osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) {
guilhemMBED 0:a7c449cd2d5a 58 constructor(priority, stack_size, stack_pointer);
guilhemMBED 0:a7c449cd2d5a 59
guilhemMBED 0:a7c449cd2d5a 60 switch (start(task)) {
guilhemMBED 0:a7c449cd2d5a 61 case osErrorResource:
guilhemMBED 0:a7c449cd2d5a 62 error("OS ran out of threads!\n");
guilhemMBED 0:a7c449cd2d5a 63 break;
guilhemMBED 0:a7c449cd2d5a 64 case osErrorParameter:
guilhemMBED 0:a7c449cd2d5a 65 error("Thread already running!\n");
guilhemMBED 0:a7c449cd2d5a 66 break;
guilhemMBED 0:a7c449cd2d5a 67 case osErrorNoMemory:
guilhemMBED 0:a7c449cd2d5a 68 error("Error allocating the stack memory\n");
guilhemMBED 0:a7c449cd2d5a 69 default:
guilhemMBED 0:a7c449cd2d5a 70 break;
guilhemMBED 0:a7c449cd2d5a 71 }
guilhemMBED 0:a7c449cd2d5a 72 }
guilhemMBED 0:a7c449cd2d5a 73
guilhemMBED 0:a7c449cd2d5a 74 osStatus Thread::start(Callback<void()> task) {
guilhemMBED 0:a7c449cd2d5a 75 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 76
guilhemMBED 0:a7c449cd2d5a 77 if (_tid != 0) {
guilhemMBED 0:a7c449cd2d5a 78 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 79 return osErrorParameter;
guilhemMBED 0:a7c449cd2d5a 80 }
guilhemMBED 0:a7c449cd2d5a 81
guilhemMBED 0:a7c449cd2d5a 82 #if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
guilhemMBED 0:a7c449cd2d5a 83 _thread_def.pthread = Thread::_thunk;
guilhemMBED 0:a7c449cd2d5a 84 if (_thread_def.stack_pointer == NULL) {
guilhemMBED 0:a7c449cd2d5a 85 _thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)];
guilhemMBED 0:a7c449cd2d5a 86 MBED_ASSERT(_thread_def.stack_pointer != NULL);
guilhemMBED 0:a7c449cd2d5a 87 }
guilhemMBED 0:a7c449cd2d5a 88
guilhemMBED 0:a7c449cd2d5a 89 //Fill the stack with a magic word for maximum usage checking
guilhemMBED 0:a7c449cd2d5a 90 for (uint32_t i = 0; i < (_thread_def.stacksize / sizeof(uint32_t)); i++) {
guilhemMBED 0:a7c449cd2d5a 91 _thread_def.stack_pointer[i] = 0xE25A2EA5;
guilhemMBED 0:a7c449cd2d5a 92 }
guilhemMBED 0:a7c449cd2d5a 93 #endif
guilhemMBED 0:a7c449cd2d5a 94 _task = task;
guilhemMBED 0:a7c449cd2d5a 95 _tid = osThreadCreate(&_thread_def, this);
guilhemMBED 0:a7c449cd2d5a 96 if (_tid == NULL) {
guilhemMBED 0:a7c449cd2d5a 97 if (_dynamic_stack) {
guilhemMBED 0:a7c449cd2d5a 98 delete[] (_thread_def.stack_pointer);
guilhemMBED 0:a7c449cd2d5a 99 _thread_def.stack_pointer = (uint32_t*)NULL;
guilhemMBED 0:a7c449cd2d5a 100 }
guilhemMBED 0:a7c449cd2d5a 101 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 102 _join_sem.release();
guilhemMBED 0:a7c449cd2d5a 103 return osErrorResource;
guilhemMBED 0:a7c449cd2d5a 104 }
guilhemMBED 0:a7c449cd2d5a 105
guilhemMBED 0:a7c449cd2d5a 106 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 107 return osOK;
guilhemMBED 0:a7c449cd2d5a 108 }
guilhemMBED 0:a7c449cd2d5a 109
guilhemMBED 0:a7c449cd2d5a 110 osStatus Thread::terminate() {
guilhemMBED 0:a7c449cd2d5a 111 osStatus ret;
guilhemMBED 0:a7c449cd2d5a 112 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 113
guilhemMBED 0:a7c449cd2d5a 114 // Set the Thread's tid to NULL and
guilhemMBED 0:a7c449cd2d5a 115 // release the semaphore before terminating
guilhemMBED 0:a7c449cd2d5a 116 // since this thread could be terminating itself
guilhemMBED 0:a7c449cd2d5a 117 osThreadId local_id = _tid;
guilhemMBED 0:a7c449cd2d5a 118 _join_sem.release();
guilhemMBED 0:a7c449cd2d5a 119 _tid = (osThreadId)NULL;
guilhemMBED 0:a7c449cd2d5a 120
guilhemMBED 0:a7c449cd2d5a 121 ret = osThreadTerminate(local_id);
guilhemMBED 0:a7c449cd2d5a 122
guilhemMBED 0:a7c449cd2d5a 123 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 124 return ret;
guilhemMBED 0:a7c449cd2d5a 125 }
guilhemMBED 0:a7c449cd2d5a 126
guilhemMBED 0:a7c449cd2d5a 127 osStatus Thread::join() {
guilhemMBED 0:a7c449cd2d5a 128 int32_t ret = _join_sem.wait();
guilhemMBED 0:a7c449cd2d5a 129 if (ret < 0) {
guilhemMBED 0:a7c449cd2d5a 130 return osErrorOS;
guilhemMBED 0:a7c449cd2d5a 131 }
guilhemMBED 0:a7c449cd2d5a 132
guilhemMBED 0:a7c449cd2d5a 133 // The semaphore has been released so this thread is being
guilhemMBED 0:a7c449cd2d5a 134 // terminated or has been terminated. Once the mutex has
guilhemMBED 0:a7c449cd2d5a 135 // been locked it is ensured that the thread is deleted.
guilhemMBED 0:a7c449cd2d5a 136 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 137 MBED_ASSERT(NULL == _tid);
guilhemMBED 0:a7c449cd2d5a 138 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 139
guilhemMBED 0:a7c449cd2d5a 140 // Release sem so any other threads joining this thread wake up
guilhemMBED 0:a7c449cd2d5a 141 _join_sem.release();
guilhemMBED 0:a7c449cd2d5a 142 return osOK;
guilhemMBED 0:a7c449cd2d5a 143 }
guilhemMBED 0:a7c449cd2d5a 144
guilhemMBED 0:a7c449cd2d5a 145 osStatus Thread::set_priority(osPriority priority) {
guilhemMBED 0:a7c449cd2d5a 146 osStatus ret;
guilhemMBED 0:a7c449cd2d5a 147 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 148
guilhemMBED 0:a7c449cd2d5a 149 ret = osThreadSetPriority(_tid, priority);
guilhemMBED 0:a7c449cd2d5a 150
guilhemMBED 0:a7c449cd2d5a 151 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 152 return ret;
guilhemMBED 0:a7c449cd2d5a 153 }
guilhemMBED 0:a7c449cd2d5a 154
guilhemMBED 0:a7c449cd2d5a 155 osPriority Thread::get_priority() {
guilhemMBED 0:a7c449cd2d5a 156 osPriority ret;
guilhemMBED 0:a7c449cd2d5a 157 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 158
guilhemMBED 0:a7c449cd2d5a 159 ret = osThreadGetPriority(_tid);
guilhemMBED 0:a7c449cd2d5a 160
guilhemMBED 0:a7c449cd2d5a 161 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 162 return ret;
guilhemMBED 0:a7c449cd2d5a 163 }
guilhemMBED 0:a7c449cd2d5a 164
guilhemMBED 0:a7c449cd2d5a 165 int32_t Thread::signal_set(int32_t signals) {
guilhemMBED 0:a7c449cd2d5a 166 // osSignalSet is thread safe as long as the underlying
guilhemMBED 0:a7c449cd2d5a 167 // thread does not get terminated or return from main
guilhemMBED 0:a7c449cd2d5a 168 return osSignalSet(_tid, signals);
guilhemMBED 0:a7c449cd2d5a 169 }
guilhemMBED 0:a7c449cd2d5a 170
guilhemMBED 0:a7c449cd2d5a 171 int32_t Thread::signal_clr(int32_t signals) {
guilhemMBED 0:a7c449cd2d5a 172 // osSignalClear is thread safe as long as the underlying
guilhemMBED 0:a7c449cd2d5a 173 // thread does not get terminated or return from main
guilhemMBED 0:a7c449cd2d5a 174 return osSignalClear(_tid, signals);
guilhemMBED 0:a7c449cd2d5a 175 }
guilhemMBED 0:a7c449cd2d5a 176
guilhemMBED 0:a7c449cd2d5a 177 Thread::State Thread::get_state() {
guilhemMBED 0:a7c449cd2d5a 178 #if !defined(__MBED_CMSIS_RTOS_CA9) && !defined(__MBED_CMSIS_RTOS_CM)
guilhemMBED 0:a7c449cd2d5a 179 #ifdef CMSIS_OS_RTX
guilhemMBED 0:a7c449cd2d5a 180 State status = Deleted;
guilhemMBED 0:a7c449cd2d5a 181 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 182
guilhemMBED 0:a7c449cd2d5a 183 if (_tid != NULL) {
guilhemMBED 0:a7c449cd2d5a 184 status = (State)_thread_def.tcb.state;
guilhemMBED 0:a7c449cd2d5a 185 }
guilhemMBED 0:a7c449cd2d5a 186
guilhemMBED 0:a7c449cd2d5a 187 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 188 return status;
guilhemMBED 0:a7c449cd2d5a 189 #endif
guilhemMBED 0:a7c449cd2d5a 190 #else
guilhemMBED 0:a7c449cd2d5a 191 State status = Deleted;
guilhemMBED 0:a7c449cd2d5a 192 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 193
guilhemMBED 0:a7c449cd2d5a 194 if (_tid != NULL) {
guilhemMBED 0:a7c449cd2d5a 195 status = (State)osThreadGetState(_tid);
guilhemMBED 0:a7c449cd2d5a 196 }
guilhemMBED 0:a7c449cd2d5a 197
guilhemMBED 0:a7c449cd2d5a 198 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 199 return status;
guilhemMBED 0:a7c449cd2d5a 200 #endif
guilhemMBED 0:a7c449cd2d5a 201 }
guilhemMBED 0:a7c449cd2d5a 202
guilhemMBED 0:a7c449cd2d5a 203 uint32_t Thread::stack_size() {
guilhemMBED 0:a7c449cd2d5a 204 #ifndef __MBED_CMSIS_RTOS_CA9
guilhemMBED 0:a7c449cd2d5a 205 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
guilhemMBED 0:a7c449cd2d5a 206 uint32_t size = 0;
guilhemMBED 0:a7c449cd2d5a 207 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 208
guilhemMBED 0:a7c449cd2d5a 209 if (_tid != NULL) {
guilhemMBED 0:a7c449cd2d5a 210 size = _thread_def.tcb.priv_stack;
guilhemMBED 0:a7c449cd2d5a 211 }
guilhemMBED 0:a7c449cd2d5a 212
guilhemMBED 0:a7c449cd2d5a 213 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 214 return size;
guilhemMBED 0:a7c449cd2d5a 215 #else
guilhemMBED 0:a7c449cd2d5a 216 uint32_t size = 0;
guilhemMBED 0:a7c449cd2d5a 217 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 218
guilhemMBED 0:a7c449cd2d5a 219 if (_tid != NULL) {
guilhemMBED 0:a7c449cd2d5a 220 P_TCB tcb = rt_tid2ptcb(_tid);
guilhemMBED 0:a7c449cd2d5a 221 size = tcb->priv_stack;
guilhemMBED 0:a7c449cd2d5a 222 }
guilhemMBED 0:a7c449cd2d5a 223
guilhemMBED 0:a7c449cd2d5a 224 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 225 return size;
guilhemMBED 0:a7c449cd2d5a 226 #endif
guilhemMBED 0:a7c449cd2d5a 227 #else
guilhemMBED 0:a7c449cd2d5a 228 return 0;
guilhemMBED 0:a7c449cd2d5a 229 #endif
guilhemMBED 0:a7c449cd2d5a 230 }
guilhemMBED 0:a7c449cd2d5a 231
guilhemMBED 0:a7c449cd2d5a 232 uint32_t Thread::free_stack() {
guilhemMBED 0:a7c449cd2d5a 233 #ifndef __MBED_CMSIS_RTOS_CA9
guilhemMBED 0:a7c449cd2d5a 234 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
guilhemMBED 0:a7c449cd2d5a 235 uint32_t size = 0;
guilhemMBED 0:a7c449cd2d5a 236 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 237
guilhemMBED 0:a7c449cd2d5a 238 if (_tid != NULL) {
guilhemMBED 0:a7c449cd2d5a 239 uint32_t bottom = (uint32_t)_thread_def.tcb.stack;
guilhemMBED 0:a7c449cd2d5a 240 size = _thread_def.tcb.tsk_stack - bottom;
guilhemMBED 0:a7c449cd2d5a 241 }
guilhemMBED 0:a7c449cd2d5a 242
guilhemMBED 0:a7c449cd2d5a 243 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 244 return size;
guilhemMBED 0:a7c449cd2d5a 245 #else
guilhemMBED 0:a7c449cd2d5a 246 uint32_t size = 0;
guilhemMBED 0:a7c449cd2d5a 247 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 248
guilhemMBED 0:a7c449cd2d5a 249 if (_tid != NULL) {
guilhemMBED 0:a7c449cd2d5a 250 P_TCB tcb = rt_tid2ptcb(_tid);
guilhemMBED 0:a7c449cd2d5a 251 uint32_t bottom = (uint32_t)tcb->stack;
guilhemMBED 0:a7c449cd2d5a 252 size = tcb->tsk_stack - bottom;
guilhemMBED 0:a7c449cd2d5a 253 }
guilhemMBED 0:a7c449cd2d5a 254
guilhemMBED 0:a7c449cd2d5a 255 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 256 return size;
guilhemMBED 0:a7c449cd2d5a 257 #endif
guilhemMBED 0:a7c449cd2d5a 258 #else
guilhemMBED 0:a7c449cd2d5a 259 return 0;
guilhemMBED 0:a7c449cd2d5a 260 #endif
guilhemMBED 0:a7c449cd2d5a 261 }
guilhemMBED 0:a7c449cd2d5a 262
guilhemMBED 0:a7c449cd2d5a 263 uint32_t Thread::used_stack() {
guilhemMBED 0:a7c449cd2d5a 264 #ifndef __MBED_CMSIS_RTOS_CA9
guilhemMBED 0:a7c449cd2d5a 265 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
guilhemMBED 0:a7c449cd2d5a 266 uint32_t size = 0;
guilhemMBED 0:a7c449cd2d5a 267 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 268
guilhemMBED 0:a7c449cd2d5a 269 if (_tid != NULL) {
guilhemMBED 0:a7c449cd2d5a 270 uint32_t top = (uint32_t)_thread_def.tcb.stack + _thread_def.tcb.priv_stack;
guilhemMBED 0:a7c449cd2d5a 271 size = top - _thread_def.tcb.tsk_stack;
guilhemMBED 0:a7c449cd2d5a 272 }
guilhemMBED 0:a7c449cd2d5a 273
guilhemMBED 0:a7c449cd2d5a 274 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 275 return size;
guilhemMBED 0:a7c449cd2d5a 276 #else
guilhemMBED 0:a7c449cd2d5a 277 uint32_t size = 0;
guilhemMBED 0:a7c449cd2d5a 278 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 279
guilhemMBED 0:a7c449cd2d5a 280 if (_tid != NULL) {
guilhemMBED 0:a7c449cd2d5a 281 P_TCB tcb = rt_tid2ptcb(_tid);
guilhemMBED 0:a7c449cd2d5a 282 uint32_t top = (uint32_t)tcb->stack + tcb->priv_stack;
guilhemMBED 0:a7c449cd2d5a 283 size = top - tcb->tsk_stack;
guilhemMBED 0:a7c449cd2d5a 284 }
guilhemMBED 0:a7c449cd2d5a 285
guilhemMBED 0:a7c449cd2d5a 286 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 287 return size;
guilhemMBED 0:a7c449cd2d5a 288 #endif
guilhemMBED 0:a7c449cd2d5a 289 #else
guilhemMBED 0:a7c449cd2d5a 290 return 0;
guilhemMBED 0:a7c449cd2d5a 291 #endif
guilhemMBED 0:a7c449cd2d5a 292 }
guilhemMBED 0:a7c449cd2d5a 293
guilhemMBED 0:a7c449cd2d5a 294 uint32_t Thread::max_stack() {
guilhemMBED 0:a7c449cd2d5a 295 #ifndef __MBED_CMSIS_RTOS_CA9
guilhemMBED 0:a7c449cd2d5a 296 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
guilhemMBED 0:a7c449cd2d5a 297 uint32_t size = 0;
guilhemMBED 0:a7c449cd2d5a 298 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 299
guilhemMBED 0:a7c449cd2d5a 300 if (_tid != NULL) {
guilhemMBED 0:a7c449cd2d5a 301 uint32_t high_mark = 0;
guilhemMBED 0:a7c449cd2d5a 302 while (_thread_def.tcb.stack[high_mark] == 0xE25A2EA5)
guilhemMBED 0:a7c449cd2d5a 303 high_mark++;
guilhemMBED 0:a7c449cd2d5a 304 size = _thread_def.tcb.priv_stack - (high_mark * 4);
guilhemMBED 0:a7c449cd2d5a 305 }
guilhemMBED 0:a7c449cd2d5a 306
guilhemMBED 0:a7c449cd2d5a 307 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 308 return size;
guilhemMBED 0:a7c449cd2d5a 309 #else
guilhemMBED 0:a7c449cd2d5a 310 uint32_t size = 0;
guilhemMBED 0:a7c449cd2d5a 311 _mutex.lock();
guilhemMBED 0:a7c449cd2d5a 312
guilhemMBED 0:a7c449cd2d5a 313 if (_tid != NULL) {
guilhemMBED 0:a7c449cd2d5a 314 P_TCB tcb = rt_tid2ptcb(_tid);
guilhemMBED 0:a7c449cd2d5a 315 uint32_t high_mark = 0;
guilhemMBED 0:a7c449cd2d5a 316 while (tcb->stack[high_mark] == 0xE25A2EA5)
guilhemMBED 0:a7c449cd2d5a 317 high_mark++;
guilhemMBED 0:a7c449cd2d5a 318 size = tcb->priv_stack - (high_mark * 4);
guilhemMBED 0:a7c449cd2d5a 319 }
guilhemMBED 0:a7c449cd2d5a 320
guilhemMBED 0:a7c449cd2d5a 321 _mutex.unlock();
guilhemMBED 0:a7c449cd2d5a 322 return size;
guilhemMBED 0:a7c449cd2d5a 323 #endif
guilhemMBED 0:a7c449cd2d5a 324 #else
guilhemMBED 0:a7c449cd2d5a 325 return 0;
guilhemMBED 0:a7c449cd2d5a 326 #endif
guilhemMBED 0:a7c449cd2d5a 327 }
guilhemMBED 0:a7c449cd2d5a 328
guilhemMBED 0:a7c449cd2d5a 329 osEvent Thread::signal_wait(int32_t signals, uint32_t millisec) {
guilhemMBED 0:a7c449cd2d5a 330 return osSignalWait(signals, millisec);
guilhemMBED 0:a7c449cd2d5a 331 }
guilhemMBED 0:a7c449cd2d5a 332
guilhemMBED 0:a7c449cd2d5a 333 osStatus Thread::wait(uint32_t millisec) {
guilhemMBED 0:a7c449cd2d5a 334 return osDelay(millisec);
guilhemMBED 0:a7c449cd2d5a 335 }
guilhemMBED 0:a7c449cd2d5a 336
guilhemMBED 0:a7c449cd2d5a 337 osStatus Thread::yield() {
guilhemMBED 0:a7c449cd2d5a 338 return osThreadYield();
guilhemMBED 0:a7c449cd2d5a 339 }
guilhemMBED 0:a7c449cd2d5a 340
guilhemMBED 0:a7c449cd2d5a 341 osThreadId Thread::gettid() {
guilhemMBED 0:a7c449cd2d5a 342 return osThreadGetId();
guilhemMBED 0:a7c449cd2d5a 343 }
guilhemMBED 0:a7c449cd2d5a 344
guilhemMBED 0:a7c449cd2d5a 345 void Thread::attach_idle_hook(void (*fptr)(void)) {
guilhemMBED 0:a7c449cd2d5a 346 rtos_attach_idle_hook(fptr);
guilhemMBED 0:a7c449cd2d5a 347 }
guilhemMBED 0:a7c449cd2d5a 348
guilhemMBED 0:a7c449cd2d5a 349 void Thread::attach_terminate_hook(void (*fptr)(osThreadId id)) {
guilhemMBED 0:a7c449cd2d5a 350 terminate_hook = fptr;
guilhemMBED 0:a7c449cd2d5a 351 }
guilhemMBED 0:a7c449cd2d5a 352
guilhemMBED 0:a7c449cd2d5a 353 Thread::~Thread() {
guilhemMBED 0:a7c449cd2d5a 354 // terminate is thread safe
guilhemMBED 0:a7c449cd2d5a 355 terminate();
guilhemMBED 0:a7c449cd2d5a 356 #ifdef __MBED_CMSIS_RTOS_CM
guilhemMBED 0:a7c449cd2d5a 357 if (_dynamic_stack) {
guilhemMBED 0:a7c449cd2d5a 358 delete[] (_thread_def.stack_pointer);
guilhemMBED 0:a7c449cd2d5a 359 _thread_def.stack_pointer = (uint32_t*)NULL;
guilhemMBED 0:a7c449cd2d5a 360 }
guilhemMBED 0:a7c449cd2d5a 361 #endif
guilhemMBED 0:a7c449cd2d5a 362 }
guilhemMBED 0:a7c449cd2d5a 363
guilhemMBED 0:a7c449cd2d5a 364 void Thread::_thunk(const void * thread_ptr)
guilhemMBED 0:a7c449cd2d5a 365 {
guilhemMBED 0:a7c449cd2d5a 366 Thread *t = (Thread*)thread_ptr;
guilhemMBED 0:a7c449cd2d5a 367 t->_task();
guilhemMBED 0:a7c449cd2d5a 368 t->_mutex.lock();
guilhemMBED 0:a7c449cd2d5a 369 t->_tid = (osThreadId)NULL;
guilhemMBED 0:a7c449cd2d5a 370 t->_join_sem.release();
guilhemMBED 0:a7c449cd2d5a 371 // rtos will release the mutex automatically
guilhemMBED 0:a7c449cd2d5a 372 }
guilhemMBED 0:a7c449cd2d5a 373
guilhemMBED 0:a7c449cd2d5a 374 }