This is a fork of the `events` subdirectory of https://github.com/ARMmbed/mbed-os
Dependents: HelloWorld_CCA01M1 HelloWorld_CCA02M1 CI-data-logger-server HelloWorld_CCA02M1 ... more
This is a fork of the events
subdirectory of https://github.com/ARMmbed/mbed-os.
Note, you must import this library with import name: events
!!!
equeue/equeue_mbed.cpp@16:e974c9c27619, 2017-02-15 (annotated)
- Committer:
- Christopher Haster
- Date:
- Wed Feb 15 10:04:11 2017 -0600
- Revision:
- 16:e974c9c27619
- Parent:
- 13:93ea03db7d46
- Child:
- 18:dba7bd0f39f3
- Child:
- 9820:245503c70134
events: Added better handling of desynchronized timers in platform layer
An odd bug (c0951c9) in the NCS36510 ticker code caused the timer/ticker
classes to become desynchronized. Updated the handling to not assume the
timers are perfectly in synch. This will increase the event's tolerance of
less robust platforms.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Bogdan Marinescu |
0:a792d4bf36c2 | 1 | /* |
Bogdan Marinescu |
0:a792d4bf36c2 | 2 | * Implementation for the mbed library |
Bogdan Marinescu |
0:a792d4bf36c2 | 3 | * https://github.com/mbedmicro/mbed |
Bogdan Marinescu |
0:a792d4bf36c2 | 4 | * |
Bogdan Marinescu |
0:a792d4bf36c2 | 5 | * Copyright (c) 2016 Christopher Haster |
Bogdan Marinescu |
0:a792d4bf36c2 | 6 | * |
Bogdan Marinescu |
0:a792d4bf36c2 | 7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
Bogdan Marinescu |
0:a792d4bf36c2 | 8 | * you may not use this file except in compliance with the License. |
Bogdan Marinescu |
0:a792d4bf36c2 | 9 | * You may obtain a copy of the License at |
Bogdan Marinescu |
0:a792d4bf36c2 | 10 | * |
Bogdan Marinescu |
0:a792d4bf36c2 | 11 | * http://www.apache.org/licenses/LICENSE-2.0 |
Bogdan Marinescu |
0:a792d4bf36c2 | 12 | * |
Bogdan Marinescu |
0:a792d4bf36c2 | 13 | * Unless required by applicable law or agreed to in writing, software |
Bogdan Marinescu |
0:a792d4bf36c2 | 14 | * distributed under the License is distributed on an "AS IS" BASIS, |
Bogdan Marinescu |
0:a792d4bf36c2 | 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
Bogdan Marinescu |
0:a792d4bf36c2 | 16 | * See the License for the specific language governing permissions and |
Bogdan Marinescu |
0:a792d4bf36c2 | 17 | * limitations under the License. |
Bogdan Marinescu |
0:a792d4bf36c2 | 18 | */ |
Sam Grove |
2:a60d8117d0e0 | 19 | #include "equeue/equeue_platform.h" |
Bogdan Marinescu |
0:a792d4bf36c2 | 20 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 21 | #if defined(EQUEUE_PLATFORM_MBED) |
Bogdan Marinescu |
0:a792d4bf36c2 | 22 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 23 | #include <stdbool.h> |
Bogdan Marinescu |
0:a792d4bf36c2 | 24 | #include "mbed.h" |
Bogdan Marinescu |
0:a792d4bf36c2 | 25 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 26 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 27 | // Ticker operations |
Bogdan Marinescu |
0:a792d4bf36c2 | 28 | static bool equeue_tick_inited = false; |
Christopher Haster |
16:e974c9c27619 | 29 | static volatile unsigned equeue_minutes = 0; |
Bogdan Marinescu |
0:a792d4bf36c2 | 30 | static unsigned equeue_timer[ |
Bogdan Marinescu |
0:a792d4bf36c2 | 31 | (sizeof(Timer)+sizeof(unsigned)-1)/sizeof(unsigned)]; |
Bogdan Marinescu |
0:a792d4bf36c2 | 32 | static unsigned equeue_ticker[ |
Bogdan Marinescu |
0:a792d4bf36c2 | 33 | (sizeof(Ticker)+sizeof(unsigned)-1)/sizeof(unsigned)]; |
Bogdan Marinescu |
0:a792d4bf36c2 | 34 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 35 | static void equeue_tick_update() { |
Christopher Haster |
16:e974c9c27619 | 36 | equeue_minutes += reinterpret_cast<Timer*>(equeue_timer)->read_ms(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 37 | reinterpret_cast<Timer*>(equeue_timer)->reset(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 38 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 39 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 40 | static void equeue_tick_init() { |
Christopher Haster |
9:a372bff82709 | 41 | MBED_STATIC_ASSERT(sizeof(equeue_timer) >= sizeof(Timer), |
Christopher Haster |
9:a372bff82709 | 42 | "The equeue_timer buffer must fit the class Timer"); |
Christopher Haster |
9:a372bff82709 | 43 | MBED_STATIC_ASSERT(sizeof(equeue_ticker) >= sizeof(Ticker), |
Christopher Haster |
9:a372bff82709 | 44 | "The equeue_ticker buffer must fit the class Ticker"); |
Bogdan Marinescu |
0:a792d4bf36c2 | 45 | new (equeue_timer) Timer; |
Bogdan Marinescu |
0:a792d4bf36c2 | 46 | new (equeue_ticker) Ticker; |
Bogdan Marinescu |
0:a792d4bf36c2 | 47 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 48 | equeue_minutes = 0; |
Bogdan Marinescu |
0:a792d4bf36c2 | 49 | reinterpret_cast<Timer*>(equeue_timer)->start(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 50 | reinterpret_cast<Ticker*>(equeue_ticker) |
Christopher Haster |
16:e974c9c27619 | 51 | ->attach_us(equeue_tick_update, 1000 << 16); |
Bogdan Marinescu |
0:a792d4bf36c2 | 52 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 53 | equeue_tick_inited = true; |
Bogdan Marinescu |
0:a792d4bf36c2 | 54 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 55 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 56 | unsigned equeue_tick() { |
Bogdan Marinescu |
0:a792d4bf36c2 | 57 | if (!equeue_tick_inited) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 58 | equeue_tick_init(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 59 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 60 | |
Christopher Haster |
16:e974c9c27619 | 61 | unsigned minutes; |
Christopher Haster |
16:e974c9c27619 | 62 | unsigned ms; |
Christopher Haster |
16:e974c9c27619 | 63 | |
Christopher Haster |
16:e974c9c27619 | 64 | do { |
Christopher Haster |
16:e974c9c27619 | 65 | minutes = equeue_minutes; |
Christopher Haster |
16:e974c9c27619 | 66 | ms = reinterpret_cast<Timer*>(equeue_timer)->read_ms(); |
Christopher Haster |
16:e974c9c27619 | 67 | } while (minutes != equeue_minutes); |
Christopher Haster |
16:e974c9c27619 | 68 | |
Christopher Haster |
16:e974c9c27619 | 69 | return minutes + ms; |
Bogdan Marinescu |
0:a792d4bf36c2 | 70 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 71 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 72 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 73 | // Mutex operations |
Bogdan Marinescu |
0:a792d4bf36c2 | 74 | int equeue_mutex_create(equeue_mutex_t *m) { return 0; } |
Bogdan Marinescu |
0:a792d4bf36c2 | 75 | void equeue_mutex_destroy(equeue_mutex_t *m) { } |
Bogdan Marinescu |
0:a792d4bf36c2 | 76 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 77 | void equeue_mutex_lock(equeue_mutex_t *m) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 78 | core_util_critical_section_enter(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 79 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 80 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 81 | void equeue_mutex_unlock(equeue_mutex_t *m) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 82 | core_util_critical_section_exit(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 83 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 84 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 85 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 86 | // Semaphore operations |
Bogdan Marinescu |
0:a792d4bf36c2 | 87 | #ifdef MBED_CONF_RTOS_PRESENT |
Bogdan Marinescu |
0:a792d4bf36c2 | 88 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 89 | int equeue_sema_create(equeue_sema_t *s) { |
Christopher Haster |
9:a372bff82709 | 90 | MBED_STATIC_ASSERT(sizeof(equeue_sema_t) >= sizeof(Semaphore), |
Christopher Haster |
9:a372bff82709 | 91 | "The equeue_sema_t must fit the class Semaphore"); |
Bogdan Marinescu |
0:a792d4bf36c2 | 92 | new (s) Semaphore(0); |
Bogdan Marinescu |
0:a792d4bf36c2 | 93 | return 0; |
Bogdan Marinescu |
0:a792d4bf36c2 | 94 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 95 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 96 | void equeue_sema_destroy(equeue_sema_t *s) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 97 | reinterpret_cast<Semaphore*>(s)->~Semaphore(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 98 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 99 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 100 | void equeue_sema_signal(equeue_sema_t *s) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 101 | reinterpret_cast<Semaphore*>(s)->release(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 102 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 103 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 104 | bool equeue_sema_wait(equeue_sema_t *s, int ms) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 105 | if (ms < 0) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 106 | ms = osWaitForever; |
Bogdan Marinescu |
0:a792d4bf36c2 | 107 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 108 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 109 | return (reinterpret_cast<Semaphore*>(s)->wait(ms) > 0); |
Bogdan Marinescu |
0:a792d4bf36c2 | 110 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 111 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 112 | #else |
Bogdan Marinescu |
0:a792d4bf36c2 | 113 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 114 | // Semaphore operations |
Bogdan Marinescu |
0:a792d4bf36c2 | 115 | int equeue_sema_create(equeue_sema_t *s) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 116 | *s = false; |
Bogdan Marinescu |
0:a792d4bf36c2 | 117 | return 0; |
Bogdan Marinescu |
0:a792d4bf36c2 | 118 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 119 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 120 | void equeue_sema_destroy(equeue_sema_t *s) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 121 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 122 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 123 | void equeue_sema_signal(equeue_sema_t *s) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 124 | *s = 1; |
Bogdan Marinescu |
0:a792d4bf36c2 | 125 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 126 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 127 | static void equeue_sema_timeout(equeue_sema_t *s) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 128 | *s = -1; |
Bogdan Marinescu |
0:a792d4bf36c2 | 129 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 130 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 131 | bool equeue_sema_wait(equeue_sema_t *s, int ms) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 132 | int signal = 0; |
Bogdan Marinescu |
0:a792d4bf36c2 | 133 | Timeout timeout; |
Christopher Haster |
13:93ea03db7d46 | 134 | if (ms > 0) { |
Christopher Haster |
13:93ea03db7d46 | 135 | timeout.attach_us(callback(equeue_sema_timeout, s), ms*1000); |
Christopher Haster |
13:93ea03db7d46 | 136 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 137 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 138 | core_util_critical_section_enter(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 139 | while (!*s) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 140 | sleep(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 141 | core_util_critical_section_exit(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 142 | core_util_critical_section_enter(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 143 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 144 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 145 | signal = *s; |
Bogdan Marinescu |
0:a792d4bf36c2 | 146 | *s = false; |
Bogdan Marinescu |
0:a792d4bf36c2 | 147 | core_util_critical_section_exit(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 148 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 149 | return (signal > 0); |
Bogdan Marinescu |
0:a792d4bf36c2 | 150 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 151 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 152 | #endif |
Bogdan Marinescu |
0:a792d4bf36c2 | 153 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 154 | #endif |