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