Entrega 3er corte - sistemas embebidos

Committer:
Bethory
Date:
Wed May 30 04:46:28 2018 +0000
Revision:
1:fcdb45ee95b9
Parent:
0:6ad07c9019fd
Entrega Final

Who changed what in which revision?

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