Toyomasa Watarai
/
Mbed-example-WS-W27
simple-mbed-cloud-client/mbed-cloud-client/sal-stack-nanostack-eventloop/source/system_timer.c@0:119624335925, 2018-06-30 (annotated)
- Committer:
- MACRUM
- Date:
- Sat Jun 30 01:40:30 2018 +0000
- Revision:
- 0:119624335925
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MACRUM | 0:119624335925 | 1 | /* |
MACRUM | 0:119624335925 | 2 | * Copyright (c) 2014-2015 ARM Limited. All rights reserved. |
MACRUM | 0:119624335925 | 3 | * SPDX-License-Identifier: Apache-2.0 |
MACRUM | 0:119624335925 | 4 | * Licensed under the Apache License, Version 2.0 (the License); you may |
MACRUM | 0:119624335925 | 5 | * not use this file except in compliance with the License. |
MACRUM | 0:119624335925 | 6 | * You may obtain a copy of the License at |
MACRUM | 0:119624335925 | 7 | * |
MACRUM | 0:119624335925 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
MACRUM | 0:119624335925 | 9 | * |
MACRUM | 0:119624335925 | 10 | * Unless required by applicable law or agreed to in writing, software |
MACRUM | 0:119624335925 | 11 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT |
MACRUM | 0:119624335925 | 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
MACRUM | 0:119624335925 | 13 | * See the License for the specific language governing permissions and |
MACRUM | 0:119624335925 | 14 | * limitations under the License. |
MACRUM | 0:119624335925 | 15 | */ |
MACRUM | 0:119624335925 | 16 | #include "ns_types.h" |
MACRUM | 0:119624335925 | 17 | #include "ns_list.h" |
MACRUM | 0:119624335925 | 18 | #include "timer_sys.h" |
MACRUM | 0:119624335925 | 19 | #include "platform/arm_hal_interrupt.h" |
MACRUM | 0:119624335925 | 20 | #include "platform/arm_hal_timer.h" |
MACRUM | 0:119624335925 | 21 | #include "nsdynmemLIB.h" |
MACRUM | 0:119624335925 | 22 | #include "eventOS_event.h" |
MACRUM | 0:119624335925 | 23 | #include "eventOS_event_timer.h" |
MACRUM | 0:119624335925 | 24 | #include "event.h" |
MACRUM | 0:119624335925 | 25 | #include "eventOS_callback_timer.h" |
MACRUM | 0:119624335925 | 26 | |
MACRUM | 0:119624335925 | 27 | #include "ns_timer.h" |
MACRUM | 0:119624335925 | 28 | |
MACRUM | 0:119624335925 | 29 | #ifndef ST_MAX |
MACRUM | 0:119624335925 | 30 | #define ST_MAX 6 |
MACRUM | 0:119624335925 | 31 | #endif |
MACRUM | 0:119624335925 | 32 | |
MACRUM | 0:119624335925 | 33 | static sys_timer_struct_s startup_sys_timer_pool[ST_MAX]; |
MACRUM | 0:119624335925 | 34 | |
MACRUM | 0:119624335925 | 35 | #define TIMER_SLOTS_PER_MS 20 |
MACRUM | 0:119624335925 | 36 | NS_STATIC_ASSERT(1000 % EVENTOS_EVENT_TIMER_HZ == 0, "Need whole number of ms per tick") |
MACRUM | 0:119624335925 | 37 | #define TIMER_SYS_TICK_PERIOD (1000 / EVENTOS_EVENT_TIMER_HZ) // milliseconds |
MACRUM | 0:119624335925 | 38 | |
MACRUM | 0:119624335925 | 39 | // timer_sys_ticks must be read in critical section to guarantee |
MACRUM | 0:119624335925 | 40 | // atomicity on 16-bit platforms |
MACRUM | 0:119624335925 | 41 | static volatile uint32_t timer_sys_ticks; |
MACRUM | 0:119624335925 | 42 | |
MACRUM | 0:119624335925 | 43 | static NS_LIST_DEFINE(system_timer_free, sys_timer_struct_s, event.link); |
MACRUM | 0:119624335925 | 44 | static NS_LIST_DEFINE(system_timer_list, sys_timer_struct_s, event.link); |
MACRUM | 0:119624335925 | 45 | |
MACRUM | 0:119624335925 | 46 | |
MACRUM | 0:119624335925 | 47 | static sys_timer_struct_s *sys_timer_dynamically_allocate(void); |
MACRUM | 0:119624335925 | 48 | static void timer_sys_interrupt(void); |
MACRUM | 0:119624335925 | 49 | static void timer_sys_add(sys_timer_struct_s *timer); |
MACRUM | 0:119624335925 | 50 | |
MACRUM | 0:119624335925 | 51 | #ifndef NS_EVENTLOOP_USE_TICK_TIMER |
MACRUM | 0:119624335925 | 52 | static int8_t platform_tick_timer_start(uint32_t period_ms); |
MACRUM | 0:119624335925 | 53 | /* Implement platform tick timer using eventOS timer */ |
MACRUM | 0:119624335925 | 54 | // platform tick timer callback function |
MACRUM | 0:119624335925 | 55 | static void (*tick_timer_callback)(void); |
MACRUM | 0:119624335925 | 56 | static int8_t tick_timer_id = -1; // eventOS timer id for tick timer |
MACRUM | 0:119624335925 | 57 | |
MACRUM | 0:119624335925 | 58 | // EventOS timer callback function |
MACRUM | 0:119624335925 | 59 | static void tick_timer_eventOS_callback(int8_t timer_id, uint16_t slots) |
MACRUM | 0:119624335925 | 60 | { |
MACRUM | 0:119624335925 | 61 | // Not interested in timer id or slots |
MACRUM | 0:119624335925 | 62 | (void)slots; |
MACRUM | 0:119624335925 | 63 | // Call the tick timer callback |
MACRUM | 0:119624335925 | 64 | if (tick_timer_callback != NULL && timer_id == tick_timer_id) { |
MACRUM | 0:119624335925 | 65 | platform_tick_timer_start(TIMER_SYS_TICK_PERIOD); |
MACRUM | 0:119624335925 | 66 | tick_timer_callback(); |
MACRUM | 0:119624335925 | 67 | } |
MACRUM | 0:119624335925 | 68 | } |
MACRUM | 0:119624335925 | 69 | |
MACRUM | 0:119624335925 | 70 | static int8_t platform_tick_timer_register(void (*tick_timer_cb)(void)) |
MACRUM | 0:119624335925 | 71 | { |
MACRUM | 0:119624335925 | 72 | tick_timer_callback = tick_timer_cb; |
MACRUM | 0:119624335925 | 73 | tick_timer_id = eventOS_callback_timer_register(tick_timer_eventOS_callback); |
MACRUM | 0:119624335925 | 74 | return tick_timer_id; |
MACRUM | 0:119624335925 | 75 | } |
MACRUM | 0:119624335925 | 76 | |
MACRUM | 0:119624335925 | 77 | static int8_t platform_tick_timer_start(uint32_t period_ms) |
MACRUM | 0:119624335925 | 78 | { |
MACRUM | 0:119624335925 | 79 | return eventOS_callback_timer_start(tick_timer_id, TIMER_SLOTS_PER_MS * period_ms); |
MACRUM | 0:119624335925 | 80 | } |
MACRUM | 0:119624335925 | 81 | |
MACRUM | 0:119624335925 | 82 | static int8_t platform_tick_timer_stop(void) |
MACRUM | 0:119624335925 | 83 | { |
MACRUM | 0:119624335925 | 84 | return eventOS_callback_timer_stop(tick_timer_id); |
MACRUM | 0:119624335925 | 85 | } |
MACRUM | 0:119624335925 | 86 | #endif // !NS_EVENTLOOP_USE_TICK_TIMER |
MACRUM | 0:119624335925 | 87 | |
MACRUM | 0:119624335925 | 88 | /* |
MACRUM | 0:119624335925 | 89 | * Initializes timers and starts system timer |
MACRUM | 0:119624335925 | 90 | */ |
MACRUM | 0:119624335925 | 91 | void timer_sys_init(void) |
MACRUM | 0:119624335925 | 92 | { |
MACRUM | 0:119624335925 | 93 | for (uint8_t i = 0; i < ST_MAX; i++) { |
MACRUM | 0:119624335925 | 94 | ns_list_add_to_start(&system_timer_free, &startup_sys_timer_pool[i]); |
MACRUM | 0:119624335925 | 95 | } |
MACRUM | 0:119624335925 | 96 | |
MACRUM | 0:119624335925 | 97 | platform_tick_timer_register(timer_sys_interrupt); |
MACRUM | 0:119624335925 | 98 | platform_tick_timer_start(TIMER_SYS_TICK_PERIOD); |
MACRUM | 0:119624335925 | 99 | } |
MACRUM | 0:119624335925 | 100 | |
MACRUM | 0:119624335925 | 101 | |
MACRUM | 0:119624335925 | 102 | |
MACRUM | 0:119624335925 | 103 | /*-------------------SYSTEM TIMER FUNCTIONS--------------------------*/ |
MACRUM | 0:119624335925 | 104 | void timer_sys_disable(void) |
MACRUM | 0:119624335925 | 105 | { |
MACRUM | 0:119624335925 | 106 | platform_tick_timer_stop(); |
MACRUM | 0:119624335925 | 107 | } |
MACRUM | 0:119624335925 | 108 | |
MACRUM | 0:119624335925 | 109 | /* |
MACRUM | 0:119624335925 | 110 | * Starts ticking system timer interrupts every 10ms |
MACRUM | 0:119624335925 | 111 | */ |
MACRUM | 0:119624335925 | 112 | int8_t timer_sys_wakeup(void) |
MACRUM | 0:119624335925 | 113 | { |
MACRUM | 0:119624335925 | 114 | return platform_tick_timer_start(TIMER_SYS_TICK_PERIOD); |
MACRUM | 0:119624335925 | 115 | } |
MACRUM | 0:119624335925 | 116 | |
MACRUM | 0:119624335925 | 117 | |
MACRUM | 0:119624335925 | 118 | static void timer_sys_interrupt(void) |
MACRUM | 0:119624335925 | 119 | { |
MACRUM | 0:119624335925 | 120 | system_timer_tick_update(1); |
MACRUM | 0:119624335925 | 121 | } |
MACRUM | 0:119624335925 | 122 | |
MACRUM | 0:119624335925 | 123 | |
MACRUM | 0:119624335925 | 124 | |
MACRUM | 0:119624335925 | 125 | /* * * * * * * * * */ |
MACRUM | 0:119624335925 | 126 | |
MACRUM | 0:119624335925 | 127 | static sys_timer_struct_s *sys_timer_dynamically_allocate(void) |
MACRUM | 0:119624335925 | 128 | { |
MACRUM | 0:119624335925 | 129 | return ns_dyn_mem_alloc(sizeof(sys_timer_struct_s)); |
MACRUM | 0:119624335925 | 130 | } |
MACRUM | 0:119624335925 | 131 | |
MACRUM | 0:119624335925 | 132 | static sys_timer_struct_s *timer_struct_get(void) |
MACRUM | 0:119624335925 | 133 | { |
MACRUM | 0:119624335925 | 134 | sys_timer_struct_s *timer; |
MACRUM | 0:119624335925 | 135 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 136 | timer = ns_list_get_first(&system_timer_free); |
MACRUM | 0:119624335925 | 137 | if (timer) { |
MACRUM | 0:119624335925 | 138 | ns_list_remove(&system_timer_free, timer); |
MACRUM | 0:119624335925 | 139 | } else { |
MACRUM | 0:119624335925 | 140 | timer = sys_timer_dynamically_allocate(); |
MACRUM | 0:119624335925 | 141 | } |
MACRUM | 0:119624335925 | 142 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 143 | return timer; |
MACRUM | 0:119624335925 | 144 | } |
MACRUM | 0:119624335925 | 145 | |
MACRUM | 0:119624335925 | 146 | void timer_sys_event_free(arm_event_storage_t *event) |
MACRUM | 0:119624335925 | 147 | { |
MACRUM | 0:119624335925 | 148 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 149 | sys_timer_struct_s *timer = NS_CONTAINER_OF(event, sys_timer_struct_s, event); |
MACRUM | 0:119624335925 | 150 | if (timer->period == 0) { |
MACRUM | 0:119624335925 | 151 | // Non-periodic - return to free list |
MACRUM | 0:119624335925 | 152 | ns_list_add_to_start(&system_timer_free, timer); |
MACRUM | 0:119624335925 | 153 | } else { |
MACRUM | 0:119624335925 | 154 | // Periodic - check due time of next launch |
MACRUM | 0:119624335925 | 155 | timer->launch_time += timer->period; |
MACRUM | 0:119624335925 | 156 | if (TICKS_BEFORE_OR_AT(timer->launch_time, timer_sys_ticks)) { |
MACRUM | 0:119624335925 | 157 | // next event is overdue - queue event now |
MACRUM | 0:119624335925 | 158 | eventOS_event_send_timer_allocated(&timer->event); |
MACRUM | 0:119624335925 | 159 | } else { |
MACRUM | 0:119624335925 | 160 | // add back to timer queue for the future |
MACRUM | 0:119624335925 | 161 | timer_sys_add(timer); |
MACRUM | 0:119624335925 | 162 | } |
MACRUM | 0:119624335925 | 163 | } |
MACRUM | 0:119624335925 | 164 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 165 | } |
MACRUM | 0:119624335925 | 166 | |
MACRUM | 0:119624335925 | 167 | void timer_sys_event_cancel_critical(struct arm_event_storage *event) |
MACRUM | 0:119624335925 | 168 | { |
MACRUM | 0:119624335925 | 169 | sys_timer_struct_s *timer = NS_CONTAINER_OF(event, sys_timer_struct_s, event); |
MACRUM | 0:119624335925 | 170 | timer->period = 0; |
MACRUM | 0:119624335925 | 171 | // If its unqueued it is on my timer list, otherwise it is in event-loop. |
MACRUM | 0:119624335925 | 172 | if (event->state == ARM_LIB_EVENT_UNQUEUED) { |
MACRUM | 0:119624335925 | 173 | ns_list_remove(&system_timer_list, timer); |
MACRUM | 0:119624335925 | 174 | } |
MACRUM | 0:119624335925 | 175 | } |
MACRUM | 0:119624335925 | 176 | |
MACRUM | 0:119624335925 | 177 | uint32_t eventOS_event_timer_ticks(void) |
MACRUM | 0:119624335925 | 178 | { |
MACRUM | 0:119624335925 | 179 | uint32_t ret_val; |
MACRUM | 0:119624335925 | 180 | // Enter/exit critical is a bit clunky, but necessary on 16-bit platforms, |
MACRUM | 0:119624335925 | 181 | // which won't be able to do an atomic 32-bit read. |
MACRUM | 0:119624335925 | 182 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 183 | ret_val = timer_sys_ticks; |
MACRUM | 0:119624335925 | 184 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 185 | return ret_val; |
MACRUM | 0:119624335925 | 186 | } |
MACRUM | 0:119624335925 | 187 | |
MACRUM | 0:119624335925 | 188 | /* Called internally with lock held */ |
MACRUM | 0:119624335925 | 189 | static void timer_sys_add(sys_timer_struct_s *timer) |
MACRUM | 0:119624335925 | 190 | { |
MACRUM | 0:119624335925 | 191 | uint32_t at = timer->launch_time; |
MACRUM | 0:119624335925 | 192 | |
MACRUM | 0:119624335925 | 193 | // Find first timer scheduled to run after us, and insert before it. |
MACRUM | 0:119624335925 | 194 | // (This means timers scheduled for same time run in order of request) |
MACRUM | 0:119624335925 | 195 | ns_list_foreach(sys_timer_struct_s, t, &system_timer_list) { |
MACRUM | 0:119624335925 | 196 | if (TICKS_BEFORE(at, t->launch_time)) { |
MACRUM | 0:119624335925 | 197 | ns_list_add_before(&system_timer_list, t, timer); |
MACRUM | 0:119624335925 | 198 | return; |
MACRUM | 0:119624335925 | 199 | } |
MACRUM | 0:119624335925 | 200 | } |
MACRUM | 0:119624335925 | 201 | |
MACRUM | 0:119624335925 | 202 | // Didn't insert before another timer, so must be last. |
MACRUM | 0:119624335925 | 203 | ns_list_add_to_end(&system_timer_list, timer); |
MACRUM | 0:119624335925 | 204 | } |
MACRUM | 0:119624335925 | 205 | |
MACRUM | 0:119624335925 | 206 | /* Called internally with lock held */ |
MACRUM | 0:119624335925 | 207 | static arm_event_storage_t *eventOS_event_timer_request_at_(const arm_event_t *event, uint32_t at, uint32_t period) |
MACRUM | 0:119624335925 | 208 | { |
MACRUM | 0:119624335925 | 209 | // Because we use user-allocated events, they must get delivered to avoid |
MACRUM | 0:119624335925 | 210 | // a leak. Previously this call queued timers for invalid tasks, then they |
MACRUM | 0:119624335925 | 211 | // would go undelivered. Now it returns an error. |
MACRUM | 0:119624335925 | 212 | if (!event_tasklet_handler_id_valid(event->receiver)) { |
MACRUM | 0:119624335925 | 213 | return NULL; |
MACRUM | 0:119624335925 | 214 | } |
MACRUM | 0:119624335925 | 215 | |
MACRUM | 0:119624335925 | 216 | sys_timer_struct_s *timer = timer_struct_get(); |
MACRUM | 0:119624335925 | 217 | if (!timer) { |
MACRUM | 0:119624335925 | 218 | return NULL; |
MACRUM | 0:119624335925 | 219 | } |
MACRUM | 0:119624335925 | 220 | |
MACRUM | 0:119624335925 | 221 | timer->event.data = *event; |
MACRUM | 0:119624335925 | 222 | timer->event.allocator = ARM_LIB_EVENT_TIMER; |
MACRUM | 0:119624335925 | 223 | timer->event.state = ARM_LIB_EVENT_UNQUEUED; |
MACRUM | 0:119624335925 | 224 | timer->launch_time = at; |
MACRUM | 0:119624335925 | 225 | timer->period = period; |
MACRUM | 0:119624335925 | 226 | |
MACRUM | 0:119624335925 | 227 | if (TICKS_BEFORE_OR_AT(at, timer_sys_ticks)) { |
MACRUM | 0:119624335925 | 228 | eventOS_event_send_timer_allocated(&timer->event); |
MACRUM | 0:119624335925 | 229 | } else { |
MACRUM | 0:119624335925 | 230 | timer_sys_add(timer); |
MACRUM | 0:119624335925 | 231 | } |
MACRUM | 0:119624335925 | 232 | |
MACRUM | 0:119624335925 | 233 | return &timer->event; |
MACRUM | 0:119624335925 | 234 | } |
MACRUM | 0:119624335925 | 235 | |
MACRUM | 0:119624335925 | 236 | arm_event_storage_t *eventOS_event_timer_request_at(const arm_event_t *event, uint32_t at) |
MACRUM | 0:119624335925 | 237 | { |
MACRUM | 0:119624335925 | 238 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 239 | |
MACRUM | 0:119624335925 | 240 | arm_event_storage_t *ret = eventOS_event_timer_request_at_(event, at, 0); |
MACRUM | 0:119624335925 | 241 | |
MACRUM | 0:119624335925 | 242 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 243 | |
MACRUM | 0:119624335925 | 244 | return ret; |
MACRUM | 0:119624335925 | 245 | } |
MACRUM | 0:119624335925 | 246 | |
MACRUM | 0:119624335925 | 247 | arm_event_storage_t *eventOS_event_timer_request_in(const arm_event_t *event, int32_t in) |
MACRUM | 0:119624335925 | 248 | { |
MACRUM | 0:119624335925 | 249 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 250 | |
MACRUM | 0:119624335925 | 251 | arm_event_storage_t *ret = eventOS_event_timer_request_at_(event, timer_sys_ticks + in, 0); |
MACRUM | 0:119624335925 | 252 | |
MACRUM | 0:119624335925 | 253 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 254 | |
MACRUM | 0:119624335925 | 255 | return ret; |
MACRUM | 0:119624335925 | 256 | |
MACRUM | 0:119624335925 | 257 | } |
MACRUM | 0:119624335925 | 258 | |
MACRUM | 0:119624335925 | 259 | arm_event_storage_t *eventOS_event_timer_request_every(const arm_event_t *event, int32_t period) |
MACRUM | 0:119624335925 | 260 | { |
MACRUM | 0:119624335925 | 261 | if (period <= 0) { |
MACRUM | 0:119624335925 | 262 | return NULL; |
MACRUM | 0:119624335925 | 263 | } |
MACRUM | 0:119624335925 | 264 | |
MACRUM | 0:119624335925 | 265 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 266 | |
MACRUM | 0:119624335925 | 267 | arm_event_storage_t *ret = eventOS_event_timer_request_at_(event, timer_sys_ticks + period, period); |
MACRUM | 0:119624335925 | 268 | |
MACRUM | 0:119624335925 | 269 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 270 | |
MACRUM | 0:119624335925 | 271 | return ret; |
MACRUM | 0:119624335925 | 272 | |
MACRUM | 0:119624335925 | 273 | } |
MACRUM | 0:119624335925 | 274 | |
MACRUM | 0:119624335925 | 275 | int8_t eventOS_event_timer_request(uint8_t event_id, uint8_t event_type, int8_t tasklet_id, uint32_t time) |
MACRUM | 0:119624335925 | 276 | { |
MACRUM | 0:119624335925 | 277 | const arm_event_t event = { |
MACRUM | 0:119624335925 | 278 | .event_id = event_id, |
MACRUM | 0:119624335925 | 279 | .event_type = event_type, |
MACRUM | 0:119624335925 | 280 | .receiver = tasklet_id, |
MACRUM | 0:119624335925 | 281 | .sender = 0, |
MACRUM | 0:119624335925 | 282 | .data_ptr = NULL, |
MACRUM | 0:119624335925 | 283 | .event_data = 0, |
MACRUM | 0:119624335925 | 284 | .priority = ARM_LIB_MED_PRIORITY_EVENT, |
MACRUM | 0:119624335925 | 285 | }; |
MACRUM | 0:119624335925 | 286 | |
MACRUM | 0:119624335925 | 287 | // Legacy time behaviour preserved |
MACRUM | 0:119624335925 | 288 | |
MACRUM | 0:119624335925 | 289 | // Note that someone wanting 20ms gets 2 ticks, thanks to this test. 30ms would be 4 ticks. |
MACRUM | 0:119624335925 | 290 | // And why shouldn't they be able to get a 1-tick callback? |
MACRUM | 0:119624335925 | 291 | if (time > 2 * TIMER_SYS_TICK_PERIOD) { |
MACRUM | 0:119624335925 | 292 | time /= TIMER_SYS_TICK_PERIOD; |
MACRUM | 0:119624335925 | 293 | // XXX Why this? Someone wanting 50ms shouldn't get 6 ticks. Round to nearest, maybe? |
MACRUM | 0:119624335925 | 294 | time++; |
MACRUM | 0:119624335925 | 295 | } else { |
MACRUM | 0:119624335925 | 296 | time = 2; |
MACRUM | 0:119624335925 | 297 | } |
MACRUM | 0:119624335925 | 298 | |
MACRUM | 0:119624335925 | 299 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 300 | arm_event_storage_t *ret = eventOS_event_timer_request_at_(&event, timer_sys_ticks + time, 0); |
MACRUM | 0:119624335925 | 301 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 302 | return ret?0:-1; |
MACRUM | 0:119624335925 | 303 | } |
MACRUM | 0:119624335925 | 304 | |
MACRUM | 0:119624335925 | 305 | int8_t eventOS_event_timer_cancel(uint8_t event_id, int8_t tasklet_id) |
MACRUM | 0:119624335925 | 306 | { |
MACRUM | 0:119624335925 | 307 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 308 | |
MACRUM | 0:119624335925 | 309 | /* First check pending timers */ |
MACRUM | 0:119624335925 | 310 | ns_list_foreach(sys_timer_struct_s, cur, &system_timer_list) { |
MACRUM | 0:119624335925 | 311 | if (cur->event.data.receiver == tasklet_id && cur->event.data.event_id == event_id) { |
MACRUM | 0:119624335925 | 312 | eventOS_cancel(&cur->event); |
MACRUM | 0:119624335925 | 313 | goto done; |
MACRUM | 0:119624335925 | 314 | } |
MACRUM | 0:119624335925 | 315 | } |
MACRUM | 0:119624335925 | 316 | |
MACRUM | 0:119624335925 | 317 | /* No pending timer, so check for already-pending event */ |
MACRUM | 0:119624335925 | 318 | arm_event_storage_t *event = eventOS_event_find_by_id_critical(tasklet_id, event_id); |
MACRUM | 0:119624335925 | 319 | if (event && event->allocator == ARM_LIB_EVENT_TIMER) { |
MACRUM | 0:119624335925 | 320 | eventOS_cancel(event); |
MACRUM | 0:119624335925 | 321 | goto done; |
MACRUM | 0:119624335925 | 322 | } |
MACRUM | 0:119624335925 | 323 | |
MACRUM | 0:119624335925 | 324 | /* No match found */ |
MACRUM | 0:119624335925 | 325 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 326 | return -1; |
MACRUM | 0:119624335925 | 327 | |
MACRUM | 0:119624335925 | 328 | done: |
MACRUM | 0:119624335925 | 329 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 330 | return 0; |
MACRUM | 0:119624335925 | 331 | } |
MACRUM | 0:119624335925 | 332 | |
MACRUM | 0:119624335925 | 333 | uint32_t eventOS_event_timer_shortest_active_timer(void) |
MACRUM | 0:119624335925 | 334 | { |
MACRUM | 0:119624335925 | 335 | uint32_t ret_val = 0; |
MACRUM | 0:119624335925 | 336 | |
MACRUM | 0:119624335925 | 337 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 338 | sys_timer_struct_s *first = ns_list_get_first(&system_timer_list); |
MACRUM | 0:119624335925 | 339 | if (first == NULL) { |
MACRUM | 0:119624335925 | 340 | // Weird API has 0 for "no events" |
MACRUM | 0:119624335925 | 341 | ret_val = 0; |
MACRUM | 0:119624335925 | 342 | } else if (TICKS_BEFORE_OR_AT(first->launch_time, timer_sys_ticks)) { |
MACRUM | 0:119624335925 | 343 | // Which means an immediate/overdue event has to be 1 |
MACRUM | 0:119624335925 | 344 | ret_val = 1; |
MACRUM | 0:119624335925 | 345 | } else { |
MACRUM | 0:119624335925 | 346 | ret_val = first->launch_time - timer_sys_ticks; |
MACRUM | 0:119624335925 | 347 | } |
MACRUM | 0:119624335925 | 348 | |
MACRUM | 0:119624335925 | 349 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 350 | return eventOS_event_timer_ticks_to_ms(ret_val); |
MACRUM | 0:119624335925 | 351 | } |
MACRUM | 0:119624335925 | 352 | |
MACRUM | 0:119624335925 | 353 | void system_timer_tick_update(uint32_t ticks) |
MACRUM | 0:119624335925 | 354 | { |
MACRUM | 0:119624335925 | 355 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 356 | //Keep runtime time |
MACRUM | 0:119624335925 | 357 | timer_sys_ticks += ticks; |
MACRUM | 0:119624335925 | 358 | ns_list_foreach_safe(sys_timer_struct_s, cur, &system_timer_list) { |
MACRUM | 0:119624335925 | 359 | if (TICKS_BEFORE_OR_AT(cur->launch_time, timer_sys_ticks)) { |
MACRUM | 0:119624335925 | 360 | // Unthread from our list |
MACRUM | 0:119624335925 | 361 | ns_list_remove(&system_timer_list, cur); |
MACRUM | 0:119624335925 | 362 | // Make it an event (can't fail - no allocation) |
MACRUM | 0:119624335925 | 363 | // event system will call our timer_sys_event_free on event delivery. |
MACRUM | 0:119624335925 | 364 | eventOS_event_send_timer_allocated(&cur->event); |
MACRUM | 0:119624335925 | 365 | } else { |
MACRUM | 0:119624335925 | 366 | // List is ordered, so as soon as we see a later event, we're done. |
MACRUM | 0:119624335925 | 367 | break; |
MACRUM | 0:119624335925 | 368 | } |
MACRUM | 0:119624335925 | 369 | } |
MACRUM | 0:119624335925 | 370 | |
MACRUM | 0:119624335925 | 371 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 372 | } |
MACRUM | 0:119624335925 | 373 |