Rtos API example

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 #if MBED_CONF_EVENTS_USE_LOWPOWER_TIMER_TICKER
00027 #define ALIAS_TIMER      LowPowerTimer
00028 #define ALIAS_TICKER     LowPowerTicker
00029 #define ALIAS_TIMEOUT    LowPowerTimeout
00030 #else
00031 #define ALIAS_TIMER      Timer
00032 #define ALIAS_TICKER     Ticker
00033 #define ALIAS_TIMEOUT    Timeout
00034 #endif
00035 
00036 // Ticker operations
00037 static bool equeue_tick_inited = false;
00038 static volatile unsigned equeue_minutes = 0;
00039 static unsigned equeue_timer[
00040         (sizeof(ALIAS_TIMER)+sizeof(unsigned)-1)/sizeof(unsigned)];
00041 static unsigned equeue_ticker[
00042         (sizeof(ALIAS_TICKER)+sizeof(unsigned)-1)/sizeof(unsigned)];
00043 
00044 static void equeue_tick_update() {
00045     equeue_minutes += reinterpret_cast<ALIAS_TIMER*>(equeue_timer)->read_ms();
00046     reinterpret_cast<ALIAS_TIMER*>(equeue_timer)->reset();
00047 }
00048 
00049 static void equeue_tick_init() {
00050     MBED_STATIC_ASSERT(sizeof(equeue_timer) >= sizeof(ALIAS_TIMER),
00051             "The equeue_timer buffer must fit the class Timer");
00052     MBED_STATIC_ASSERT(sizeof(equeue_ticker) >= sizeof(ALIAS_TICKER),
00053             "The equeue_ticker buffer must fit the class Ticker");
00054     ALIAS_TIMER *timer = new (equeue_timer) ALIAS_TIMER;
00055     ALIAS_TICKER *ticker = new (equeue_ticker) ALIAS_TICKER;
00056 
00057     equeue_minutes = 0;
00058     timer->start();
00059     ticker->attach_us(equeue_tick_update, 1000 << 16);
00060 
00061     equeue_tick_inited = true;
00062 }
00063 
00064 unsigned equeue_tick() {
00065     if (!equeue_tick_inited) {
00066         equeue_tick_init();
00067     }
00068 
00069     unsigned minutes;
00070     unsigned ms;
00071 
00072     do {
00073         minutes = equeue_minutes;
00074         ms = reinterpret_cast<ALIAS_TIMER*>(equeue_timer)->read_ms();
00075     } while (minutes != equeue_minutes);
00076 
00077     return minutes + ms;
00078 }
00079 
00080 
00081 // Mutex operations
00082 int equeue_mutex_create(equeue_mutex_t *m) { return 0; }
00083 void equeue_mutex_destroy(equeue_mutex_t *m) { }
00084 
00085 void equeue_mutex_lock(equeue_mutex_t *m) {
00086     core_util_critical_section_enter();
00087 }
00088 
00089 void equeue_mutex_unlock(equeue_mutex_t *m) {
00090     core_util_critical_section_exit();
00091 }
00092 
00093 
00094 // Semaphore operations
00095 #ifdef MBED_CONF_RTOS_PRESENT
00096 
00097 int equeue_sema_create(equeue_sema_t *s) {
00098     osEventFlagsAttr_t attr;
00099     memset(&attr, 0, sizeof(attr));
00100     attr.cb_mem = &s->mem;
00101     attr.cb_size = sizeof(s->mem);
00102 
00103     s->id = osEventFlagsNew(&attr);
00104     return !s->id ? -1 : 0;
00105 }
00106 
00107 void equeue_sema_destroy(equeue_sema_t *s) {
00108     osEventFlagsDelete(s->id);
00109 }
00110 
00111 void equeue_sema_signal(equeue_sema_t *s) {
00112     osEventFlagsSet(s->id, 1);
00113 }
00114 
00115 bool equeue_sema_wait(equeue_sema_t *s, int ms) {
00116     if (ms < 0) {
00117         ms = osWaitForever;
00118     }
00119 
00120     return (osEventFlagsWait(s->id, 1, osFlagsWaitAny, ms) == 1);
00121 }
00122 
00123 #else
00124 
00125 // Semaphore operations
00126 int equeue_sema_create(equeue_sema_t *s) {
00127     *s = false;
00128     return 0;
00129 }
00130 
00131 void equeue_sema_destroy(equeue_sema_t *s) {
00132 }
00133 
00134 void equeue_sema_signal(equeue_sema_t *s) {
00135     *s = 1;
00136 }
00137 
00138 static void equeue_sema_timeout(equeue_sema_t *s) {
00139     *s = -1;
00140 }
00141 
00142 bool equeue_sema_wait(equeue_sema_t *s, int ms) {
00143     int signal = 0;
00144     ALIAS_TIMEOUT timeout;
00145     if (ms == 0) {
00146         return false;
00147     } else if (ms > 0) {
00148         timeout.attach_us(callback(equeue_sema_timeout, s), ms*1000);
00149     }
00150 
00151     core_util_critical_section_enter();
00152     while (!*s) {
00153         sleep();
00154         core_util_critical_section_exit();
00155         core_util_critical_section_enter();
00156     }
00157 
00158     signal = *s;
00159     *s = false;
00160     core_util_critical_section_exit();
00161 
00162     return (signal > 0);
00163 }
00164 
00165 #endif
00166 
00167 #endif