RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
Parent:
0:38ceb79fef03
2019-03-13

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevman 0:38ceb79fef03 1 /* mbed Microcontroller Library
kevman 0:38ceb79fef03 2 * Copyright (c) 2006-2012 ARM Limited
kevman 0:38ceb79fef03 3 *
kevman 0:38ceb79fef03 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
kevman 0:38ceb79fef03 5 * of this software and associated documentation files (the "Software"), to deal
kevman 0:38ceb79fef03 6 * in the Software without restriction, including without limitation the rights
kevman 0:38ceb79fef03 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
kevman 0:38ceb79fef03 8 * copies of the Software, and to permit persons to whom the Software is
kevman 0:38ceb79fef03 9 * furnished to do so, subject to the following conditions:
kevman 0:38ceb79fef03 10 *
kevman 0:38ceb79fef03 11 * The above copyright notice and this permission notice shall be included in
kevman 0:38ceb79fef03 12 * all copies or substantial portions of the Software.
kevman 0:38ceb79fef03 13 *
kevman 0:38ceb79fef03 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
kevman 0:38ceb79fef03 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
kevman 0:38ceb79fef03 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
kevman 0:38ceb79fef03 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
kevman 0:38ceb79fef03 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kevman 0:38ceb79fef03 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
kevman 0:38ceb79fef03 20 * SOFTWARE.
kevman 0:38ceb79fef03 21 */
kevman 0:38ceb79fef03 22 #include "rtos/Thread.h"
kevman 0:38ceb79fef03 23 #include "rtos/ThisThread.h"
kevman 0:38ceb79fef03 24
kevman 0:38ceb79fef03 25 #include "mbed.h"
kevman 0:38ceb79fef03 26 #include "rtos/rtos_idle.h"
kevman 0:38ceb79fef03 27 #include "rtos/rtos_handlers.h"
kevman 0:38ceb79fef03 28 #include "mbed_assert.h"
kevman 0:38ceb79fef03 29
kevman 0:38ceb79fef03 30 #define ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos))
kevman 0:38ceb79fef03 31 MBED_STATIC_ASSERT(ALIGN_UP(0, 8) == 0, "ALIGN_UP macro error");
kevman 0:38ceb79fef03 32 MBED_STATIC_ASSERT(ALIGN_UP(1, 8) == 8, "ALIGN_UP macro error");
kevman 0:38ceb79fef03 33
kevman 0:38ceb79fef03 34 #define ALIGN_DOWN(pos, align) ((pos) - ((pos) % (align)))
kevman 0:38ceb79fef03 35 MBED_STATIC_ASSERT(ALIGN_DOWN(7, 8) == 0, "ALIGN_DOWN macro error");
kevman 0:38ceb79fef03 36 MBED_STATIC_ASSERT(ALIGN_DOWN(8, 8) == 8, "ALIGN_DOWN macro error");
kevman 0:38ceb79fef03 37
kevman 0:38ceb79fef03 38 namespace rtos {
kevman 0:38ceb79fef03 39
kevman 0:38ceb79fef03 40 #ifndef MBED_TZ_DEFAULT_ACCESS
kevman 0:38ceb79fef03 41 #define MBED_TZ_DEFAULT_ACCESS 0
kevman 0:38ceb79fef03 42 #endif
kevman 0:38ceb79fef03 43
kevman 0:38ceb79fef03 44 void Thread::constructor(uint32_t tz_module, osPriority priority,
kevman 0:38ceb79fef03 45 uint32_t stack_size, unsigned char *stack_mem, const char *name)
kevman 0:38ceb79fef03 46 {
kevman 0:38ceb79fef03 47
kevman 0:38ceb79fef03 48 const uintptr_t unaligned_mem = reinterpret_cast<uintptr_t>(stack_mem);
kevman 0:38ceb79fef03 49 const uintptr_t aligned_mem = ALIGN_UP(unaligned_mem, 8);
kevman 0:38ceb79fef03 50 const uint32_t offset = aligned_mem - unaligned_mem;
kevman 0:38ceb79fef03 51 const uint32_t aligned_size = ALIGN_DOWN(stack_size - offset, 8);
kevman 0:38ceb79fef03 52
kevman 0:38ceb79fef03 53 _tid = 0;
kevman 0:38ceb79fef03 54 _dynamic_stack = (stack_mem == NULL);
kevman 0:38ceb79fef03 55 _finished = false;
kevman 0:38ceb79fef03 56 memset(&_obj_mem, 0, sizeof(_obj_mem));
kevman 0:38ceb79fef03 57 memset(&_attr, 0, sizeof(_attr));
kevman 0:38ceb79fef03 58 _attr.priority = priority;
kevman 0:38ceb79fef03 59 _attr.stack_size = aligned_size;
kevman 0:38ceb79fef03 60 _attr.name = name ? name : "application_unnamed_thread";
kevman 0:38ceb79fef03 61 _attr.stack_mem = reinterpret_cast<uint32_t *>(aligned_mem);
kevman 0:38ceb79fef03 62 _attr.tz_module = tz_module;
kevman 0:38ceb79fef03 63 }
kevman 0:38ceb79fef03 64
kevman 0:38ceb79fef03 65 void Thread::constructor(osPriority priority,
kevman 0:38ceb79fef03 66 uint32_t stack_size, unsigned char *stack_mem, const char *name)
kevman 0:38ceb79fef03 67 {
kevman 0:38ceb79fef03 68 constructor(MBED_TZ_DEFAULT_ACCESS, priority, stack_size, stack_mem, name);
kevman 0:38ceb79fef03 69 }
kevman 0:38ceb79fef03 70
kevman 0:38ceb79fef03 71 void Thread::constructor(Callback<void()> task,
kevman 0:38ceb79fef03 72 osPriority priority, uint32_t stack_size, unsigned char *stack_mem, const char *name)
kevman 0:38ceb79fef03 73 {
kevman 0:38ceb79fef03 74 constructor(MBED_TZ_DEFAULT_ACCESS, priority, stack_size, stack_mem, name);
kevman 0:38ceb79fef03 75
kevman 0:38ceb79fef03 76 switch (start(task)) {
kevman 0:38ceb79fef03 77 case osErrorResource:
kevman 0:38ceb79fef03 78 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OUT_OF_RESOURCES), "OS ran out of threads!\n", task);
kevman 0:38ceb79fef03 79 break;
kevman 0:38ceb79fef03 80 case osErrorParameter:
kevman 0:38ceb79fef03 81 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_ALREADY_IN_USE), "Thread already running!\n", task);
kevman 0:38ceb79fef03 82 break;
kevman 0:38ceb79fef03 83 case osErrorNoMemory:
kevman 0:38ceb79fef03 84 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OUT_OF_MEMORY), "Error allocating the stack memory\n", task);
kevman 0:38ceb79fef03 85 default:
kevman 0:38ceb79fef03 86 break;
kevman 0:38ceb79fef03 87 }
kevman 0:38ceb79fef03 88 }
kevman 0:38ceb79fef03 89
kevman 0:38ceb79fef03 90 osStatus Thread::start(Callback<void()> task)
kevman 0:38ceb79fef03 91 {
kevman 0:38ceb79fef03 92 _mutex.lock();
kevman 0:38ceb79fef03 93
kevman 0:38ceb79fef03 94 if ((_tid != 0) || _finished) {
kevman 0:38ceb79fef03 95 _mutex.unlock();
kevman 0:38ceb79fef03 96 return osErrorParameter;
kevman 0:38ceb79fef03 97 }
kevman 0:38ceb79fef03 98
kevman 0:38ceb79fef03 99 if (_attr.stack_mem == NULL) {
kevman 0:38ceb79fef03 100 _attr.stack_mem = new uint32_t[_attr.stack_size / sizeof(uint32_t)];
kevman 0:38ceb79fef03 101 MBED_ASSERT(_attr.stack_mem != NULL);
kevman 0:38ceb79fef03 102 }
kevman 0:38ceb79fef03 103
kevman 0:38ceb79fef03 104 //Fill the stack with a magic word for maximum usage checking
kevman 0:38ceb79fef03 105 for (uint32_t i = 0; i < (_attr.stack_size / sizeof(uint32_t)); i++) {
kevman 0:38ceb79fef03 106 ((uint32_t *)_attr.stack_mem)[i] = osRtxStackMagicWord;
kevman 0:38ceb79fef03 107 }
kevman 0:38ceb79fef03 108
kevman 0:38ceb79fef03 109 memset(&_obj_mem, 0, sizeof(_obj_mem));
kevman 0:38ceb79fef03 110 _attr.cb_size = sizeof(_obj_mem);
kevman 0:38ceb79fef03 111 _attr.cb_mem = &_obj_mem;
kevman 0:38ceb79fef03 112 _task = task;
kevman 0:38ceb79fef03 113 _tid = osThreadNew(Thread::_thunk, this, &_attr);
kevman 0:38ceb79fef03 114 if (_tid == NULL) {
kevman 0:38ceb79fef03 115 if (_dynamic_stack) {
kevman 0:38ceb79fef03 116 delete[](uint32_t *)(_attr.stack_mem);
kevman 0:38ceb79fef03 117 _attr.stack_mem = (uint32_t *)NULL;
kevman 0:38ceb79fef03 118 }
kevman 0:38ceb79fef03 119 _mutex.unlock();
kevman 0:38ceb79fef03 120 _join_sem.release();
kevman 0:38ceb79fef03 121 return osErrorResource;
kevman 0:38ceb79fef03 122 }
kevman 0:38ceb79fef03 123
kevman 0:38ceb79fef03 124 _mutex.unlock();
kevman 0:38ceb79fef03 125 return osOK;
kevman 0:38ceb79fef03 126 }
kevman 0:38ceb79fef03 127
kevman 0:38ceb79fef03 128 osStatus Thread::terminate()
kevman 0:38ceb79fef03 129 {
kevman 0:38ceb79fef03 130 osStatus_t ret = osOK;
kevman 0:38ceb79fef03 131 _mutex.lock();
kevman 0:38ceb79fef03 132
kevman 0:38ceb79fef03 133 // Set the Thread's tid to NULL and
kevman 0:38ceb79fef03 134 // release the semaphore before terminating
kevman 0:38ceb79fef03 135 // since this thread could be terminating itself
kevman 0:38ceb79fef03 136 osThreadId_t local_id = _tid;
kevman 0:38ceb79fef03 137 _join_sem.release();
kevman 0:38ceb79fef03 138 _tid = (osThreadId_t)NULL;
kevman 0:38ceb79fef03 139 if (!_finished) {
kevman 0:38ceb79fef03 140 _finished = true;
kevman 0:38ceb79fef03 141 // if local_id == 0 Thread was not started in first place
kevman 0:38ceb79fef03 142 // and does not have to be terminated
kevman 0:38ceb79fef03 143 if (local_id != 0) {
kevman 0:38ceb79fef03 144 ret = osThreadTerminate(local_id);
kevman 0:38ceb79fef03 145 }
kevman 0:38ceb79fef03 146 }
kevman 0:38ceb79fef03 147 _mutex.unlock();
kevman 0:38ceb79fef03 148 return ret;
kevman 0:38ceb79fef03 149 }
kevman 0:38ceb79fef03 150
kevman 0:38ceb79fef03 151 osStatus Thread::join()
kevman 0:38ceb79fef03 152 {
kevman 0:38ceb79fef03 153 int32_t ret = _join_sem.wait();
kevman 0:38ceb79fef03 154 if (ret < 0) {
kevman 0:38ceb79fef03 155 return osError;
kevman 0:38ceb79fef03 156 }
kevman 0:38ceb79fef03 157
kevman 0:38ceb79fef03 158 // The semaphore has been released so this thread is being
kevman 0:38ceb79fef03 159 // terminated or has been terminated. Once the mutex has
kevman 0:38ceb79fef03 160 // been locked it is ensured that the thread is deleted.
kevman 0:38ceb79fef03 161 _mutex.lock();
kevman 0:38ceb79fef03 162 MBED_ASSERT(NULL == _tid);
kevman 0:38ceb79fef03 163 _mutex.unlock();
kevman 0:38ceb79fef03 164
kevman 0:38ceb79fef03 165 // Release sem so any other threads joining this thread wake up
kevman 0:38ceb79fef03 166 _join_sem.release();
kevman 0:38ceb79fef03 167 return osOK;
kevman 0:38ceb79fef03 168 }
kevman 0:38ceb79fef03 169
kevman 0:38ceb79fef03 170 osStatus Thread::set_priority(osPriority priority)
kevman 0:38ceb79fef03 171 {
kevman 0:38ceb79fef03 172 osStatus_t ret;
kevman 0:38ceb79fef03 173 _mutex.lock();
kevman 0:38ceb79fef03 174
kevman 0:38ceb79fef03 175 ret = osThreadSetPriority(_tid, priority);
kevman 0:38ceb79fef03 176
kevman 0:38ceb79fef03 177 _mutex.unlock();
kevman 0:38ceb79fef03 178 return ret;
kevman 0:38ceb79fef03 179 }
kevman 0:38ceb79fef03 180
kevman 0:38ceb79fef03 181 osPriority Thread::get_priority() const
kevman 0:38ceb79fef03 182 {
kevman 0:38ceb79fef03 183 osPriority_t ret;
kevman 0:38ceb79fef03 184 _mutex.lock();
kevman 0:38ceb79fef03 185
kevman 0:38ceb79fef03 186 ret = osThreadGetPriority(_tid);
kevman 0:38ceb79fef03 187
kevman 0:38ceb79fef03 188 _mutex.unlock();
kevman 0:38ceb79fef03 189 return ret;
kevman 0:38ceb79fef03 190 }
kevman 0:38ceb79fef03 191
kevman 0:38ceb79fef03 192 uint32_t Thread::flags_set(uint32_t flags)
kevman 0:38ceb79fef03 193 {
kevman 0:38ceb79fef03 194 flags = osThreadFlagsSet(_tid, flags);
kevman 0:38ceb79fef03 195 MBED_ASSERT(!(flags & osFlagsError));
kevman 0:38ceb79fef03 196 return flags;
kevman 0:38ceb79fef03 197 }
kevman 0:38ceb79fef03 198
kevman 0:38ceb79fef03 199 int32_t Thread::signal_set(int32_t flags)
kevman 0:38ceb79fef03 200 {
kevman 0:38ceb79fef03 201 return osThreadFlagsSet(_tid, flags);
kevman 0:38ceb79fef03 202 }
kevman 0:38ceb79fef03 203
kevman 0:38ceb79fef03 204 Thread::State Thread::get_state() const
kevman 0:38ceb79fef03 205 {
kevman 0:38ceb79fef03 206 uint8_t state = osThreadTerminated;
kevman 0:38ceb79fef03 207
kevman 0:38ceb79fef03 208 _mutex.lock();
kevman 0:38ceb79fef03 209
kevman 0:38ceb79fef03 210 if (_tid != NULL) {
kevman 0:38ceb79fef03 211 #if defined(MBED_OS_BACKEND_RTX5)
kevman 0:38ceb79fef03 212 state = _obj_mem.state;
kevman 0:38ceb79fef03 213 #else
kevman 0:38ceb79fef03 214 state = osThreadGetState(_tid);
kevman 0:38ceb79fef03 215 #endif
kevman 0:38ceb79fef03 216 }
kevman 0:38ceb79fef03 217
kevman 0:38ceb79fef03 218 _mutex.unlock();
kevman 0:38ceb79fef03 219
kevman 0:38ceb79fef03 220 State user_state;
kevman 0:38ceb79fef03 221
kevman 0:38ceb79fef03 222 switch (state) {
kevman 0:38ceb79fef03 223 case osThreadInactive:
kevman 0:38ceb79fef03 224 user_state = Inactive;
kevman 0:38ceb79fef03 225 break;
kevman 0:38ceb79fef03 226 case osThreadReady:
kevman 0:38ceb79fef03 227 user_state = Ready;
kevman 0:38ceb79fef03 228 break;
kevman 0:38ceb79fef03 229 case osThreadRunning:
kevman 0:38ceb79fef03 230 user_state = Running;
kevman 0:38ceb79fef03 231 break;
kevman 0:38ceb79fef03 232 #if defined(MBED_OS_BACKEND_RTX5)
kevman 0:38ceb79fef03 233 case osRtxThreadWaitingDelay:
kevman 0:38ceb79fef03 234 user_state = WaitingDelay;
kevman 0:38ceb79fef03 235 break;
kevman 0:38ceb79fef03 236 case osRtxThreadWaitingJoin:
kevman 0:38ceb79fef03 237 user_state = WaitingJoin;
kevman 0:38ceb79fef03 238 break;
kevman 0:38ceb79fef03 239 case osRtxThreadWaitingThreadFlags:
kevman 0:38ceb79fef03 240 user_state = WaitingThreadFlag;
kevman 0:38ceb79fef03 241 break;
kevman 0:38ceb79fef03 242 case osRtxThreadWaitingEventFlags:
kevman 0:38ceb79fef03 243 user_state = WaitingEventFlag;
kevman 0:38ceb79fef03 244 break;
kevman 0:38ceb79fef03 245 case osRtxThreadWaitingMutex:
kevman 0:38ceb79fef03 246 user_state = WaitingMutex;
kevman 0:38ceb79fef03 247 break;
kevman 0:38ceb79fef03 248 case osRtxThreadWaitingSemaphore:
kevman 0:38ceb79fef03 249 user_state = WaitingSemaphore;
kevman 0:38ceb79fef03 250 break;
kevman 0:38ceb79fef03 251 case osRtxThreadWaitingMemoryPool:
kevman 0:38ceb79fef03 252 user_state = WaitingMemoryPool;
kevman 0:38ceb79fef03 253 break;
kevman 0:38ceb79fef03 254 case osRtxThreadWaitingMessageGet:
kevman 0:38ceb79fef03 255 user_state = WaitingMessageGet;
kevman 0:38ceb79fef03 256 break;
kevman 0:38ceb79fef03 257 case osRtxThreadWaitingMessagePut:
kevman 0:38ceb79fef03 258 user_state = WaitingMessagePut;
kevman 0:38ceb79fef03 259 break;
kevman 0:38ceb79fef03 260 #endif
kevman 0:38ceb79fef03 261 case osThreadTerminated:
kevman 0:38ceb79fef03 262 default:
kevman 0:38ceb79fef03 263 user_state = Deleted;
kevman 0:38ceb79fef03 264 break;
kevman 0:38ceb79fef03 265 }
kevman 0:38ceb79fef03 266
kevman 0:38ceb79fef03 267 return user_state;
kevman 0:38ceb79fef03 268 }
kevman 0:38ceb79fef03 269
kevman 0:38ceb79fef03 270 uint32_t Thread::stack_size() const
kevman 0:38ceb79fef03 271 {
kevman 0:38ceb79fef03 272 uint32_t size = 0;
kevman 0:38ceb79fef03 273 _mutex.lock();
kevman 0:38ceb79fef03 274
kevman 0:38ceb79fef03 275 if (_tid != NULL) {
kevman 0:38ceb79fef03 276 size = osThreadGetStackSize(_tid);
kevman 0:38ceb79fef03 277 }
kevman 0:38ceb79fef03 278
kevman 0:38ceb79fef03 279 _mutex.unlock();
kevman 0:38ceb79fef03 280 return size;
kevman 0:38ceb79fef03 281 }
kevman 0:38ceb79fef03 282
kevman 0:38ceb79fef03 283 uint32_t Thread::free_stack() const
kevman 0:38ceb79fef03 284 {
kevman 0:38ceb79fef03 285 uint32_t size = 0;
kevman 0:38ceb79fef03 286 _mutex.lock();
kevman 0:38ceb79fef03 287
kevman 0:38ceb79fef03 288 #if defined(MBED_OS_BACKEND_RTX5)
kevman 0:38ceb79fef03 289 if (_tid != NULL) {
kevman 0:38ceb79fef03 290 mbed_rtos_storage_thread_t *thread = (mbed_rtos_storage_thread_t *)_tid;
kevman 0:38ceb79fef03 291 size = (uint32_t)thread->sp - (uint32_t)thread->stack_mem;
kevman 0:38ceb79fef03 292 }
kevman 0:38ceb79fef03 293 #endif
kevman 0:38ceb79fef03 294
kevman 0:38ceb79fef03 295 _mutex.unlock();
kevman 0:38ceb79fef03 296 return size;
kevman 0:38ceb79fef03 297 }
kevman 0:38ceb79fef03 298
kevman 0:38ceb79fef03 299 uint32_t Thread::used_stack() const
kevman 0:38ceb79fef03 300 {
kevman 0:38ceb79fef03 301 uint32_t size = 0;
kevman 0:38ceb79fef03 302 _mutex.lock();
kevman 0:38ceb79fef03 303
kevman 0:38ceb79fef03 304 #if defined(MBED_OS_BACKEND_RTX5)
kevman 0:38ceb79fef03 305 if (_tid != NULL) {
kevman 0:38ceb79fef03 306 mbed_rtos_storage_thread_t *thread = (mbed_rtos_storage_thread_t *)_tid;
kevman 0:38ceb79fef03 307 size = ((uint32_t)thread->stack_mem + thread->stack_size) - thread->sp;
kevman 0:38ceb79fef03 308 }
kevman 0:38ceb79fef03 309 #endif
kevman 0:38ceb79fef03 310
kevman 0:38ceb79fef03 311 _mutex.unlock();
kevman 0:38ceb79fef03 312 return size;
kevman 0:38ceb79fef03 313 }
kevman 0:38ceb79fef03 314
kevman 0:38ceb79fef03 315 uint32_t Thread::max_stack() const
kevman 0:38ceb79fef03 316 {
kevman 0:38ceb79fef03 317 uint32_t size = 0;
kevman 0:38ceb79fef03 318 _mutex.lock();
kevman 0:38ceb79fef03 319
kevman 0:38ceb79fef03 320 if (_tid != NULL) {
kevman 0:38ceb79fef03 321 #if defined(MBED_OS_BACKEND_RTX5)
kevman 0:38ceb79fef03 322 mbed_rtos_storage_thread_t *thread = (mbed_rtos_storage_thread_t *)_tid;
kevman 0:38ceb79fef03 323 uint32_t high_mark = 0;
kevman 0:38ceb79fef03 324 while ((((uint32_t *)(thread->stack_mem))[high_mark] == osRtxStackMagicWord) || (((uint32_t *)(thread->stack_mem))[high_mark] == osRtxStackFillPattern)) {
kevman 0:38ceb79fef03 325 high_mark++;
kevman 0:38ceb79fef03 326 }
kevman 0:38ceb79fef03 327 size = thread->stack_size - (high_mark * sizeof(uint32_t));
kevman 0:38ceb79fef03 328 #else
kevman 0:38ceb79fef03 329 size = osThreadGetStackSize(_tid) - osThreadGetStackSpace(_tid);
kevman 0:38ceb79fef03 330 #endif
kevman 0:38ceb79fef03 331 }
kevman 0:38ceb79fef03 332
kevman 0:38ceb79fef03 333 _mutex.unlock();
kevman 0:38ceb79fef03 334 return size;
kevman 0:38ceb79fef03 335 }
kevman 0:38ceb79fef03 336
kevman 0:38ceb79fef03 337 const char *Thread::get_name() const
kevman 0:38ceb79fef03 338 {
kevman 0:38ceb79fef03 339 return _attr.name;
kevman 0:38ceb79fef03 340 }
kevman 0:38ceb79fef03 341
kevman 0:38ceb79fef03 342 osThreadId_t Thread::get_id() const
kevman 0:38ceb79fef03 343 {
kevman 0:38ceb79fef03 344 return _tid;
kevman 0:38ceb79fef03 345 }
kevman 0:38ceb79fef03 346
kevman 0:38ceb79fef03 347 int32_t Thread::signal_clr(int32_t flags)
kevman 0:38ceb79fef03 348 {
kevman 0:38ceb79fef03 349 return osThreadFlagsClear(flags);
kevman 0:38ceb79fef03 350 }
kevman 0:38ceb79fef03 351
kevman 0:38ceb79fef03 352 osEvent Thread::signal_wait(int32_t signals, uint32_t millisec)
kevman 0:38ceb79fef03 353 {
kevman 0:38ceb79fef03 354 uint32_t res;
kevman 0:38ceb79fef03 355 osEvent evt;
kevman 0:38ceb79fef03 356 uint32_t options = osFlagsWaitAll;
kevman 0:38ceb79fef03 357 if (signals == 0) {
kevman 0:38ceb79fef03 358 options = osFlagsWaitAny;
kevman 0:38ceb79fef03 359 signals = 0x7FFFFFFF;
kevman 0:38ceb79fef03 360 }
kevman 0:38ceb79fef03 361 res = osThreadFlagsWait(signals, options, millisec);
kevman 0:38ceb79fef03 362 if (res & osFlagsError) {
kevman 0:38ceb79fef03 363 switch (res) {
kevman 0:38ceb79fef03 364 case osFlagsErrorISR:
kevman 0:38ceb79fef03 365 evt.status = osErrorISR;
kevman 0:38ceb79fef03 366 break;
kevman 0:38ceb79fef03 367 case osFlagsErrorResource:
kevman 0:38ceb79fef03 368 evt.status = osOK;
kevman 0:38ceb79fef03 369 break;
kevman 0:38ceb79fef03 370 case osFlagsErrorTimeout:
kevman 0:38ceb79fef03 371 evt.status = (osStatus)osEventTimeout;
kevman 0:38ceb79fef03 372 break;
kevman 0:38ceb79fef03 373 case osFlagsErrorParameter:
kevman 0:38ceb79fef03 374 default:
kevman 0:38ceb79fef03 375 evt.status = (osStatus)osErrorValue;
kevman 0:38ceb79fef03 376 break;
kevman 0:38ceb79fef03 377 }
kevman 0:38ceb79fef03 378 } else {
kevman 0:38ceb79fef03 379 evt.status = (osStatus)osEventSignal;
kevman 0:38ceb79fef03 380 evt.value.signals = res;
kevman 0:38ceb79fef03 381 }
kevman 0:38ceb79fef03 382
kevman 0:38ceb79fef03 383 return evt;
kevman 0:38ceb79fef03 384 }
kevman 0:38ceb79fef03 385
kevman 0:38ceb79fef03 386 osStatus Thread::wait(uint32_t millisec)
kevman 0:38ceb79fef03 387 {
kevman 0:38ceb79fef03 388 ThisThread::sleep_for(millisec);
kevman 0:38ceb79fef03 389 return osOK;
kevman 0:38ceb79fef03 390 }
kevman 0:38ceb79fef03 391
kevman 0:38ceb79fef03 392 osStatus Thread::wait_until(uint64_t millisec)
kevman 0:38ceb79fef03 393 {
kevman 0:38ceb79fef03 394 ThisThread::sleep_until(millisec);
kevman 0:38ceb79fef03 395 return osOK;
kevman 0:38ceb79fef03 396 }
kevman 0:38ceb79fef03 397
kevman 0:38ceb79fef03 398 osStatus Thread::yield()
kevman 0:38ceb79fef03 399 {
kevman 0:38ceb79fef03 400 return osThreadYield();
kevman 0:38ceb79fef03 401 }
kevman 0:38ceb79fef03 402
kevman 0:38ceb79fef03 403 osThreadId Thread::gettid()
kevman 0:38ceb79fef03 404 {
kevman 0:38ceb79fef03 405 return osThreadGetId();
kevman 0:38ceb79fef03 406 }
kevman 0:38ceb79fef03 407
kevman 0:38ceb79fef03 408 void Thread::attach_idle_hook(void (*fptr)(void))
kevman 0:38ceb79fef03 409 {
kevman 0:38ceb79fef03 410 rtos_attach_idle_hook(fptr);
kevman 0:38ceb79fef03 411 }
kevman 0:38ceb79fef03 412
kevman 0:38ceb79fef03 413 void Thread::attach_terminate_hook(void (*fptr)(osThreadId_t id))
kevman 0:38ceb79fef03 414 {
kevman 0:38ceb79fef03 415 rtos_attach_thread_terminate_hook(fptr);
kevman 0:38ceb79fef03 416 }
kevman 0:38ceb79fef03 417
kevman 0:38ceb79fef03 418 Thread::~Thread()
kevman 0:38ceb79fef03 419 {
kevman 0:38ceb79fef03 420 // terminate is thread safe
kevman 0:38ceb79fef03 421 terminate();
kevman 0:38ceb79fef03 422 if (_dynamic_stack) {
kevman 0:38ceb79fef03 423 delete[](uint32_t *)(_attr.stack_mem);
kevman 0:38ceb79fef03 424 _attr.stack_mem = (uint32_t *)NULL;
kevman 0:38ceb79fef03 425 }
kevman 0:38ceb79fef03 426 }
kevman 0:38ceb79fef03 427
kevman 0:38ceb79fef03 428 void Thread::_thunk(void *thread_ptr)
kevman 0:38ceb79fef03 429 {
kevman 0:38ceb79fef03 430 Thread *t = (Thread *)thread_ptr;
kevman 0:38ceb79fef03 431 t->_task();
kevman 0:38ceb79fef03 432 t->_mutex.lock();
kevman 0:38ceb79fef03 433 t->_tid = (osThreadId)NULL;
kevman 0:38ceb79fef03 434 t->_finished = true;
kevman 0:38ceb79fef03 435 t->_join_sem.release();
kevman 0:38ceb79fef03 436 // rtos will release the mutex automatically
kevman 0:38ceb79fef03 437 }
kevman 0:38ceb79fef03 438
kevman 0:38ceb79fef03 439 }