BBR 1 Ebene

Committer:
borlanic
Date:
Mon May 14 11:29:06 2018 +0000
Revision:
0:fbdae7e6d805
BBR

Who changed what in which revision?

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