Nicolas Borla / Mbed OS BBR_1Ebene
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers equeue_mbed.cpp Source File

equeue_mbed.cpp

00001 /*
00002  * Implementation for the mbed library
00003  * https://github.com/mbedmicro/mbed
00004  *
00005  * Copyright (c) 2016 Christopher Haster
00006  *
00007  * Licensed under the Apache License, Version 2.0 (the "License");
00008  * you may not use this file except in compliance with the License.
00009  * You may obtain a copy of the License at
00010  *
00011  *     http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  * Unless required by applicable law or agreed to in writing, software
00014  * distributed under the License is distributed on an "AS IS" BASIS,
00015  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  * See the License for the specific language governing permissions and
00017  * limitations under the License.
00018  */
00019 #include "equeue/equeue_platform.h"
00020 
00021 #if defined(EQUEUE_PLATFORM_MBED)
00022 
00023 #include <stdbool.h>
00024 #include "mbed.h"
00025 
00026 // Ticker operations
00027 #if MBED_CONF_RTOS_PRESENT
00028 
00029 unsigned equeue_tick() {
00030     return osKernelGetTickCount();
00031 }
00032 
00033 #else
00034 
00035 #if MBED_CONF_EVENTS_USE_LOWPOWER_TIMER_TICKER
00036 #define ALIAS_TIMER      LowPowerTimer
00037 #define ALIAS_TICKER     LowPowerTicker
00038 #define ALIAS_TIMEOUT    LowPowerTimeout
00039 #else
00040 #define ALIAS_TIMER      Timer
00041 #define ALIAS_TICKER     Ticker
00042 #define ALIAS_TIMEOUT    Timeout
00043 #endif
00044 
00045 static bool equeue_tick_inited = false;
00046 static volatile unsigned equeue_minutes = 0;
00047 static unsigned equeue_timer[
00048         (sizeof(ALIAS_TIMER)+sizeof(unsigned)-1)/sizeof(unsigned)];
00049 static unsigned equeue_ticker[
00050         (sizeof(ALIAS_TICKER)+sizeof(unsigned)-1)/sizeof(unsigned)];
00051 
00052 static void equeue_tick_update() {
00053     equeue_minutes += reinterpret_cast<ALIAS_TIMER*>(equeue_timer)->read_ms();
00054     reinterpret_cast<ALIAS_TIMER*>(equeue_timer)->reset();
00055 }
00056 
00057 static void equeue_tick_init() {
00058     MBED_STATIC_ASSERT(sizeof(equeue_timer) >= sizeof(ALIAS_TIMER),
00059             "The equeue_timer buffer must fit the class Timer");
00060     MBED_STATIC_ASSERT(sizeof(equeue_ticker) >= sizeof(ALIAS_TICKER),
00061             "The equeue_ticker buffer must fit the class Ticker");
00062     ALIAS_TIMER *timer = new (equeue_timer) ALIAS_TIMER;
00063     ALIAS_TICKER *ticker = new (equeue_ticker) ALIAS_TICKER;
00064 
00065     equeue_minutes = 0;
00066     timer->start();
00067     ticker->attach_us(equeue_tick_update, 1000 << 16);
00068 
00069     equeue_tick_inited = true;
00070 }
00071 
00072 unsigned equeue_tick() {
00073     if (!equeue_tick_inited) {
00074         equeue_tick_init();
00075     }
00076 
00077     unsigned minutes;
00078     unsigned ms;
00079 
00080     do {
00081         minutes = equeue_minutes;
00082         ms = reinterpret_cast<ALIAS_TIMER*>(equeue_timer)->read_ms();
00083     } while (minutes != equeue_minutes);
00084 
00085     return minutes + ms;
00086 }
00087 
00088 #endif
00089 
00090 // Mutex operations
00091 int equeue_mutex_create(equeue_mutex_t *m) { return 0; }
00092 void equeue_mutex_destroy(equeue_mutex_t *m) { }
00093 
00094 void equeue_mutex_lock(equeue_mutex_t *m) {
00095     core_util_critical_section_enter();
00096 }
00097 
00098 void equeue_mutex_unlock(equeue_mutex_t *m) {
00099     core_util_critical_section_exit();
00100 }
00101 
00102 
00103 // Semaphore operations
00104 #ifdef MBED_CONF_RTOS_PRESENT
00105 
00106 int equeue_sema_create(equeue_sema_t *s) {
00107     osEventFlagsAttr_t attr;
00108     memset(&attr, 0, sizeof(attr));
00109     attr.cb_mem = &s->mem;
00110     attr.cb_size = sizeof(s->mem);
00111 
00112     s->id = osEventFlagsNew(&attr);
00113     return !s->id ? -1 : 0;
00114 }
00115 
00116 void equeue_sema_destroy(equeue_sema_t *s) {
00117     osEventFlagsDelete(s->id);
00118 }
00119 
00120 void equeue_sema_signal(equeue_sema_t *s) {
00121     osEventFlagsSet(s->id, 1);
00122 }
00123 
00124 bool equeue_sema_wait(equeue_sema_t *s, int ms) {
00125     if (ms < 0) {
00126         ms = osWaitForever;
00127     }
00128 
00129     return (osEventFlagsWait(s->id, 1, osFlagsWaitAny, ms) == 1);
00130 }
00131 
00132 #else
00133 
00134 // Semaphore operations
00135 int equeue_sema_create(equeue_sema_t *s) {
00136     *s = false;
00137     return 0;
00138 }
00139 
00140 void equeue_sema_destroy(equeue_sema_t *s) {
00141 }
00142 
00143 void equeue_sema_signal(equeue_sema_t *s) {
00144     *s = 1;
00145 }
00146 
00147 static void equeue_sema_timeout(equeue_sema_t *s) {
00148     *s = -1;
00149 }
00150 
00151 bool equeue_sema_wait(equeue_sema_t *s, int ms) {
00152     int signal = 0;
00153     ALIAS_TIMEOUT timeout;
00154     if (ms == 0) {
00155         return false;
00156     } else if (ms > 0) {
00157         timeout.attach_us(callback(equeue_sema_timeout, s), ms*1000);
00158     }
00159 
00160     core_util_critical_section_enter();
00161     while (!*s) {
00162         sleep();
00163         core_util_critical_section_exit();
00164         core_util_critical_section_enter();
00165     }
00166 
00167     signal = *s;
00168     *s = false;
00169     core_util_critical_section_exit();
00170 
00171     return (signal > 0);
00172 }
00173 
00174 #endif
00175 
00176 #endif