Erste version der Software für der Prototyp

Committer:
borlanic
Date:
Fri Mar 30 14:07:05 2018 +0000
Revision:
4:75df35ef4fb6
Parent:
0:380207fcb5c1
commentar

Who changed what in which revision?

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