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@18:dba7bd0f39f3, 2017-03-22 (annotated)
- Committer:
- Christopher Haster
- Date:
- Wed Mar 22 10:55:36 2017 -0500
- Revision:
- 18:dba7bd0f39f3
- Parent:
- 16:e974c9c27619
- Child:
- 9821:b387aa0c25b4
events: Fixed zero wait condition in non-rtos semaphore
Before, if the semaphore recieved a wait of zero, the semaphore
would erronously drop the ticker event to wake up the device,
causing the device to go to sleep without any mechanism to wake
itself up.
During a dispatch operation, the event queue dispatches all events
that have expired, so the call to equeue_sema_wait very rarely
has a wait of zero. But this can happen when an event is posted
just after a dispatch has occured.
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 |
18:dba7bd0f39f3 | 134 | if (ms == 0) { |
Christopher Haster |
18:dba7bd0f39f3 | 135 | return false; |
Christopher Haster |
18:dba7bd0f39f3 | 136 | } else if (ms > 0) { |
Christopher Haster |
13:93ea03db7d46 | 137 | timeout.attach_us(callback(equeue_sema_timeout, s), ms*1000); |
Christopher Haster |
13:93ea03db7d46 | 138 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 139 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 140 | core_util_critical_section_enter(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 141 | while (!*s) { |
Bogdan Marinescu |
0:a792d4bf36c2 | 142 | sleep(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 143 | core_util_critical_section_exit(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 144 | core_util_critical_section_enter(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 145 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 146 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 147 | signal = *s; |
Bogdan Marinescu |
0:a792d4bf36c2 | 148 | *s = false; |
Bogdan Marinescu |
0:a792d4bf36c2 | 149 | core_util_critical_section_exit(); |
Bogdan Marinescu |
0:a792d4bf36c2 | 150 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 151 | return (signal > 0); |
Bogdan Marinescu |
0:a792d4bf36c2 | 152 | } |
Bogdan Marinescu |
0:a792d4bf36c2 | 153 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 154 | #endif |
Bogdan Marinescu |
0:a792d4bf36c2 | 155 | |
Bogdan Marinescu |
0:a792d4bf36c2 | 156 | #endif |