Toyomasa Watarai
/
Mbed-example-WS-W27
simple-mbed-cloud-client/mbed-cloud-client/sal-stack-nanostack-eventloop/source/event.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 <string.h> |
MACRUM | 0:119624335925 | 17 | #include "ns_types.h" |
MACRUM | 0:119624335925 | 18 | #include "ns_list.h" |
MACRUM | 0:119624335925 | 19 | #include "eventOS_event.h" |
MACRUM | 0:119624335925 | 20 | #include "eventOS_scheduler.h" |
MACRUM | 0:119624335925 | 21 | #include "timer_sys.h" |
MACRUM | 0:119624335925 | 22 | #include "nsdynmemLIB.h" |
MACRUM | 0:119624335925 | 23 | #include "ns_timer.h" |
MACRUM | 0:119624335925 | 24 | #include "event.h" |
MACRUM | 0:119624335925 | 25 | #include "platform/arm_hal_interrupt.h" |
MACRUM | 0:119624335925 | 26 | |
MACRUM | 0:119624335925 | 27 | |
MACRUM | 0:119624335925 | 28 | typedef struct arm_core_tasklet { |
MACRUM | 0:119624335925 | 29 | int8_t id; /**< Event handler Tasklet ID */ |
MACRUM | 0:119624335925 | 30 | void (*func_ptr)(arm_event_s *); |
MACRUM | 0:119624335925 | 31 | ns_list_link_t link; |
MACRUM | 0:119624335925 | 32 | } arm_core_tasklet_t; |
MACRUM | 0:119624335925 | 33 | |
MACRUM | 0:119624335925 | 34 | static NS_LIST_DEFINE(arm_core_tasklet_list, arm_core_tasklet_t, link); |
MACRUM | 0:119624335925 | 35 | static NS_LIST_DEFINE(event_queue_active, arm_event_storage_t, link); |
MACRUM | 0:119624335925 | 36 | static NS_LIST_DEFINE(free_event_entry, arm_event_storage_t, link); |
MACRUM | 0:119624335925 | 37 | |
MACRUM | 0:119624335925 | 38 | // Statically allocate initial pool of events. |
MACRUM | 0:119624335925 | 39 | #define STARTUP_EVENT_POOL_SIZE 10 |
MACRUM | 0:119624335925 | 40 | static arm_event_storage_t startup_event_pool[STARTUP_EVENT_POOL_SIZE]; |
MACRUM | 0:119624335925 | 41 | |
MACRUM | 0:119624335925 | 42 | /** Curr_tasklet tell to core and platform which task_let is active, Core Update this automatic when switch Tasklet. */ |
MACRUM | 0:119624335925 | 43 | int8_t curr_tasklet = 0; |
MACRUM | 0:119624335925 | 44 | |
MACRUM | 0:119624335925 | 45 | |
MACRUM | 0:119624335925 | 46 | static arm_core_tasklet_t *tasklet_dynamically_allocate(void); |
MACRUM | 0:119624335925 | 47 | static arm_event_storage_t *event_dynamically_allocate(void); |
MACRUM | 0:119624335925 | 48 | static arm_event_storage_t *event_core_get(void); |
MACRUM | 0:119624335925 | 49 | static void event_core_write(arm_event_storage_t *event); |
MACRUM | 0:119624335925 | 50 | |
MACRUM | 0:119624335925 | 51 | static arm_core_tasklet_t *event_tasklet_handler_get(uint8_t tasklet_id) |
MACRUM | 0:119624335925 | 52 | { |
MACRUM | 0:119624335925 | 53 | ns_list_foreach(arm_core_tasklet_t, cur, &arm_core_tasklet_list) { |
MACRUM | 0:119624335925 | 54 | if (cur->id == tasklet_id) { |
MACRUM | 0:119624335925 | 55 | return cur; |
MACRUM | 0:119624335925 | 56 | } |
MACRUM | 0:119624335925 | 57 | } |
MACRUM | 0:119624335925 | 58 | return NULL; |
MACRUM | 0:119624335925 | 59 | } |
MACRUM | 0:119624335925 | 60 | |
MACRUM | 0:119624335925 | 61 | bool event_tasklet_handler_id_valid(uint8_t tasklet_id) |
MACRUM | 0:119624335925 | 62 | { |
MACRUM | 0:119624335925 | 63 | return event_tasklet_handler_get(tasklet_id); |
MACRUM | 0:119624335925 | 64 | } |
MACRUM | 0:119624335925 | 65 | |
MACRUM | 0:119624335925 | 66 | // XXX this can return 0, but 0 seems to mean "none" elsewhere? Or at least |
MACRUM | 0:119624335925 | 67 | // curr_tasklet is reset to 0 in various places. |
MACRUM | 0:119624335925 | 68 | static int8_t tasklet_get_free_id(void) |
MACRUM | 0:119624335925 | 69 | { |
MACRUM | 0:119624335925 | 70 | /*(Note use of uint8_t to avoid overflow if we reach 0x7F)*/ |
MACRUM | 0:119624335925 | 71 | for (uint8_t i = 0; i <= INT8_MAX; i++) { |
MACRUM | 0:119624335925 | 72 | if (!event_tasklet_handler_get(i)) { |
MACRUM | 0:119624335925 | 73 | return i; |
MACRUM | 0:119624335925 | 74 | } |
MACRUM | 0:119624335925 | 75 | } |
MACRUM | 0:119624335925 | 76 | return -1; |
MACRUM | 0:119624335925 | 77 | } |
MACRUM | 0:119624335925 | 78 | |
MACRUM | 0:119624335925 | 79 | |
MACRUM | 0:119624335925 | 80 | int8_t eventOS_event_handler_create(void (*handler_func_ptr)(arm_event_s *), uint8_t init_event_type) |
MACRUM | 0:119624335925 | 81 | { |
MACRUM | 0:119624335925 | 82 | arm_event_storage_t *event_tmp; |
MACRUM | 0:119624335925 | 83 | |
MACRUM | 0:119624335925 | 84 | // XXX Do we really want to prevent multiple tasklets with same function? |
MACRUM | 0:119624335925 | 85 | ns_list_foreach(arm_core_tasklet_t, cur, &arm_core_tasklet_list) { |
MACRUM | 0:119624335925 | 86 | if (cur->func_ptr == handler_func_ptr) { |
MACRUM | 0:119624335925 | 87 | return -1; |
MACRUM | 0:119624335925 | 88 | } |
MACRUM | 0:119624335925 | 89 | } |
MACRUM | 0:119624335925 | 90 | |
MACRUM | 0:119624335925 | 91 | //Allocate new |
MACRUM | 0:119624335925 | 92 | arm_core_tasklet_t *new = tasklet_dynamically_allocate(); |
MACRUM | 0:119624335925 | 93 | if (!new) { |
MACRUM | 0:119624335925 | 94 | return -2; |
MACRUM | 0:119624335925 | 95 | } |
MACRUM | 0:119624335925 | 96 | |
MACRUM | 0:119624335925 | 97 | event_tmp = event_core_get(); |
MACRUM | 0:119624335925 | 98 | if (!event_tmp) { |
MACRUM | 0:119624335925 | 99 | ns_dyn_mem_free(new); |
MACRUM | 0:119624335925 | 100 | return -2; |
MACRUM | 0:119624335925 | 101 | } |
MACRUM | 0:119624335925 | 102 | |
MACRUM | 0:119624335925 | 103 | //Fill in tasklet; add to list |
MACRUM | 0:119624335925 | 104 | new->id = tasklet_get_free_id(); |
MACRUM | 0:119624335925 | 105 | new->func_ptr = handler_func_ptr; |
MACRUM | 0:119624335925 | 106 | ns_list_add_to_end(&arm_core_tasklet_list, new); |
MACRUM | 0:119624335925 | 107 | |
MACRUM | 0:119624335925 | 108 | //Queue "init" event for the new task |
MACRUM | 0:119624335925 | 109 | event_tmp->data.receiver = new->id; |
MACRUM | 0:119624335925 | 110 | event_tmp->data.sender = 0; |
MACRUM | 0:119624335925 | 111 | event_tmp->data.event_type = init_event_type; |
MACRUM | 0:119624335925 | 112 | event_tmp->data.event_data = 0; |
MACRUM | 0:119624335925 | 113 | event_core_write(event_tmp); |
MACRUM | 0:119624335925 | 114 | |
MACRUM | 0:119624335925 | 115 | return new->id; |
MACRUM | 0:119624335925 | 116 | } |
MACRUM | 0:119624335925 | 117 | |
MACRUM | 0:119624335925 | 118 | int8_t eventOS_event_send(const arm_event_t *event) |
MACRUM | 0:119624335925 | 119 | { |
MACRUM | 0:119624335925 | 120 | if (event_tasklet_handler_get(event->receiver)) { |
MACRUM | 0:119624335925 | 121 | arm_event_storage_t *event_tmp = event_core_get(); |
MACRUM | 0:119624335925 | 122 | if (event_tmp) { |
MACRUM | 0:119624335925 | 123 | event_tmp->data = *event; |
MACRUM | 0:119624335925 | 124 | event_core_write(event_tmp); |
MACRUM | 0:119624335925 | 125 | return 0; |
MACRUM | 0:119624335925 | 126 | } |
MACRUM | 0:119624335925 | 127 | } |
MACRUM | 0:119624335925 | 128 | return -1; |
MACRUM | 0:119624335925 | 129 | } |
MACRUM | 0:119624335925 | 130 | |
MACRUM | 0:119624335925 | 131 | void eventOS_event_send_user_allocated(arm_event_storage_t *event) |
MACRUM | 0:119624335925 | 132 | { |
MACRUM | 0:119624335925 | 133 | event->allocator = ARM_LIB_EVENT_USER; |
MACRUM | 0:119624335925 | 134 | event_core_write(event); |
MACRUM | 0:119624335925 | 135 | } |
MACRUM | 0:119624335925 | 136 | |
MACRUM | 0:119624335925 | 137 | void eventOS_event_send_timer_allocated(arm_event_storage_t *event) |
MACRUM | 0:119624335925 | 138 | { |
MACRUM | 0:119624335925 | 139 | event->allocator = ARM_LIB_EVENT_TIMER; |
MACRUM | 0:119624335925 | 140 | event_core_write(event); |
MACRUM | 0:119624335925 | 141 | } |
MACRUM | 0:119624335925 | 142 | |
MACRUM | 0:119624335925 | 143 | void eventOS_event_cancel_critical(arm_event_storage_t *event) |
MACRUM | 0:119624335925 | 144 | { |
MACRUM | 0:119624335925 | 145 | ns_list_remove(&event_queue_active, event); |
MACRUM | 0:119624335925 | 146 | } |
MACRUM | 0:119624335925 | 147 | |
MACRUM | 0:119624335925 | 148 | static arm_event_storage_t *event_dynamically_allocate(void) |
MACRUM | 0:119624335925 | 149 | { |
MACRUM | 0:119624335925 | 150 | arm_event_storage_t *event = ns_dyn_mem_temporary_alloc(sizeof(arm_event_storage_t)); |
MACRUM | 0:119624335925 | 151 | if (event) { |
MACRUM | 0:119624335925 | 152 | event->allocator = ARM_LIB_EVENT_DYNAMIC; |
MACRUM | 0:119624335925 | 153 | } |
MACRUM | 0:119624335925 | 154 | return event; |
MACRUM | 0:119624335925 | 155 | } |
MACRUM | 0:119624335925 | 156 | |
MACRUM | 0:119624335925 | 157 | static arm_core_tasklet_t *tasklet_dynamically_allocate(void) |
MACRUM | 0:119624335925 | 158 | { |
MACRUM | 0:119624335925 | 159 | return ns_dyn_mem_alloc(sizeof(arm_core_tasklet_t)); |
MACRUM | 0:119624335925 | 160 | } |
MACRUM | 0:119624335925 | 161 | |
MACRUM | 0:119624335925 | 162 | arm_event_storage_t *event_core_get(void) |
MACRUM | 0:119624335925 | 163 | { |
MACRUM | 0:119624335925 | 164 | arm_event_storage_t *event; |
MACRUM | 0:119624335925 | 165 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 166 | event = ns_list_get_first(&free_event_entry); |
MACRUM | 0:119624335925 | 167 | if (event) { |
MACRUM | 0:119624335925 | 168 | ns_list_remove(&free_event_entry, event); |
MACRUM | 0:119624335925 | 169 | } else { |
MACRUM | 0:119624335925 | 170 | event = event_dynamically_allocate(); |
MACRUM | 0:119624335925 | 171 | } |
MACRUM | 0:119624335925 | 172 | if (event) { |
MACRUM | 0:119624335925 | 173 | event->data.data_ptr = NULL; |
MACRUM | 0:119624335925 | 174 | event->data.priority = ARM_LIB_LOW_PRIORITY_EVENT; |
MACRUM | 0:119624335925 | 175 | } |
MACRUM | 0:119624335925 | 176 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 177 | return event; |
MACRUM | 0:119624335925 | 178 | } |
MACRUM | 0:119624335925 | 179 | |
MACRUM | 0:119624335925 | 180 | void event_core_free_push(arm_event_storage_t *free) |
MACRUM | 0:119624335925 | 181 | { |
MACRUM | 0:119624335925 | 182 | free->state = ARM_LIB_EVENT_UNQUEUED; |
MACRUM | 0:119624335925 | 183 | |
MACRUM | 0:119624335925 | 184 | switch (free->allocator) { |
MACRUM | 0:119624335925 | 185 | case ARM_LIB_EVENT_STARTUP_POOL: |
MACRUM | 0:119624335925 | 186 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 187 | ns_list_add_to_start(&free_event_entry, free); |
MACRUM | 0:119624335925 | 188 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 189 | break; |
MACRUM | 0:119624335925 | 190 | case ARM_LIB_EVENT_DYNAMIC: |
MACRUM | 0:119624335925 | 191 | // Free all dynamically allocated events. |
MACRUM | 0:119624335925 | 192 | ns_dyn_mem_free(free); |
MACRUM | 0:119624335925 | 193 | break; |
MACRUM | 0:119624335925 | 194 | case ARM_LIB_EVENT_TIMER: |
MACRUM | 0:119624335925 | 195 | // Hand it back to the timer system |
MACRUM | 0:119624335925 | 196 | timer_sys_event_free(free); |
MACRUM | 0:119624335925 | 197 | break; |
MACRUM | 0:119624335925 | 198 | case ARM_LIB_EVENT_USER: |
MACRUM | 0:119624335925 | 199 | default: |
MACRUM | 0:119624335925 | 200 | break; |
MACRUM | 0:119624335925 | 201 | } |
MACRUM | 0:119624335925 | 202 | } |
MACRUM | 0:119624335925 | 203 | |
MACRUM | 0:119624335925 | 204 | |
MACRUM | 0:119624335925 | 205 | static arm_event_storage_t *event_core_read(void) |
MACRUM | 0:119624335925 | 206 | { |
MACRUM | 0:119624335925 | 207 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 208 | arm_event_storage_t *event = ns_list_get_first(&event_queue_active); |
MACRUM | 0:119624335925 | 209 | if (event) { |
MACRUM | 0:119624335925 | 210 | event->state = ARM_LIB_EVENT_RUNNING; |
MACRUM | 0:119624335925 | 211 | ns_list_remove(&event_queue_active, event); |
MACRUM | 0:119624335925 | 212 | } |
MACRUM | 0:119624335925 | 213 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 214 | return event; |
MACRUM | 0:119624335925 | 215 | } |
MACRUM | 0:119624335925 | 216 | |
MACRUM | 0:119624335925 | 217 | void event_core_write(arm_event_storage_t *event) |
MACRUM | 0:119624335925 | 218 | { |
MACRUM | 0:119624335925 | 219 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 220 | bool added = false; |
MACRUM | 0:119624335925 | 221 | ns_list_foreach(arm_event_storage_t, event_tmp, &event_queue_active) { |
MACRUM | 0:119624335925 | 222 | // note enum ordering means we're checking if event_tmp is LOWER priority than event |
MACRUM | 0:119624335925 | 223 | if (event_tmp->data.priority > event->data.priority) { |
MACRUM | 0:119624335925 | 224 | ns_list_add_before(&event_queue_active, event_tmp, event); |
MACRUM | 0:119624335925 | 225 | added = true; |
MACRUM | 0:119624335925 | 226 | break; |
MACRUM | 0:119624335925 | 227 | } |
MACRUM | 0:119624335925 | 228 | } |
MACRUM | 0:119624335925 | 229 | if (!added) { |
MACRUM | 0:119624335925 | 230 | ns_list_add_to_end(&event_queue_active, event); |
MACRUM | 0:119624335925 | 231 | } |
MACRUM | 0:119624335925 | 232 | event->state = ARM_LIB_EVENT_QUEUED; |
MACRUM | 0:119624335925 | 233 | |
MACRUM | 0:119624335925 | 234 | /* Wake From Idle */ |
MACRUM | 0:119624335925 | 235 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 236 | eventOS_scheduler_signal(); |
MACRUM | 0:119624335925 | 237 | } |
MACRUM | 0:119624335925 | 238 | |
MACRUM | 0:119624335925 | 239 | // Requires lock to be held |
MACRUM | 0:119624335925 | 240 | arm_event_storage_t *eventOS_event_find_by_id_critical(uint8_t tasklet_id, uint8_t event_id) |
MACRUM | 0:119624335925 | 241 | { |
MACRUM | 0:119624335925 | 242 | ns_list_foreach(arm_event_storage_t, cur, &event_queue_active) { |
MACRUM | 0:119624335925 | 243 | if (cur->data.receiver == tasklet_id && cur->data.event_id == event_id) { |
MACRUM | 0:119624335925 | 244 | return cur; |
MACRUM | 0:119624335925 | 245 | } |
MACRUM | 0:119624335925 | 246 | } |
MACRUM | 0:119624335925 | 247 | |
MACRUM | 0:119624335925 | 248 | return NULL; |
MACRUM | 0:119624335925 | 249 | } |
MACRUM | 0:119624335925 | 250 | |
MACRUM | 0:119624335925 | 251 | /** |
MACRUM | 0:119624335925 | 252 | * |
MACRUM | 0:119624335925 | 253 | * \brief Initialize Nanostack Core. |
MACRUM | 0:119624335925 | 254 | * |
MACRUM | 0:119624335925 | 255 | * Function Initialize Nanostack Core, Socket Interface,Buffer memory and Send Init event to all Tasklett which are Defined. |
MACRUM | 0:119624335925 | 256 | * |
MACRUM | 0:119624335925 | 257 | */ |
MACRUM | 0:119624335925 | 258 | void eventOS_scheduler_init(void) |
MACRUM | 0:119624335925 | 259 | { |
MACRUM | 0:119624335925 | 260 | /* Reset Event List variables */ |
MACRUM | 0:119624335925 | 261 | ns_list_init(&free_event_entry); |
MACRUM | 0:119624335925 | 262 | ns_list_init(&event_queue_active); |
MACRUM | 0:119624335925 | 263 | ns_list_init(&arm_core_tasklet_list); |
MACRUM | 0:119624335925 | 264 | |
MACRUM | 0:119624335925 | 265 | //Add first 10 entries to "free" list |
MACRUM | 0:119624335925 | 266 | for (unsigned i = 0; i < (sizeof(startup_event_pool) / sizeof(startup_event_pool[0])); i++) { |
MACRUM | 0:119624335925 | 267 | startup_event_pool[i].allocator = ARM_LIB_EVENT_STARTUP_POOL; |
MACRUM | 0:119624335925 | 268 | ns_list_add_to_start(&free_event_entry, &startup_event_pool[i]); |
MACRUM | 0:119624335925 | 269 | } |
MACRUM | 0:119624335925 | 270 | |
MACRUM | 0:119624335925 | 271 | /* Init Generic timer module */ |
MACRUM | 0:119624335925 | 272 | timer_sys_init(); //initialize timer |
MACRUM | 0:119624335925 | 273 | /* Set Tasklett switcher to Idle */ |
MACRUM | 0:119624335925 | 274 | curr_tasklet = 0; |
MACRUM | 0:119624335925 | 275 | |
MACRUM | 0:119624335925 | 276 | } |
MACRUM | 0:119624335925 | 277 | |
MACRUM | 0:119624335925 | 278 | int8_t eventOS_scheduler_get_active_tasklet(void) |
MACRUM | 0:119624335925 | 279 | { |
MACRUM | 0:119624335925 | 280 | return curr_tasklet; |
MACRUM | 0:119624335925 | 281 | } |
MACRUM | 0:119624335925 | 282 | |
MACRUM | 0:119624335925 | 283 | void eventOS_scheduler_set_active_tasklet(int8_t tasklet) |
MACRUM | 0:119624335925 | 284 | { |
MACRUM | 0:119624335925 | 285 | curr_tasklet = tasklet; |
MACRUM | 0:119624335925 | 286 | } |
MACRUM | 0:119624335925 | 287 | |
MACRUM | 0:119624335925 | 288 | int eventOS_scheduler_timer_stop(void) |
MACRUM | 0:119624335925 | 289 | { |
MACRUM | 0:119624335925 | 290 | timer_sys_disable(); |
MACRUM | 0:119624335925 | 291 | if (ns_timer_sleep() != 0) { |
MACRUM | 0:119624335925 | 292 | return 1; |
MACRUM | 0:119624335925 | 293 | } |
MACRUM | 0:119624335925 | 294 | return 0; |
MACRUM | 0:119624335925 | 295 | } |
MACRUM | 0:119624335925 | 296 | |
MACRUM | 0:119624335925 | 297 | int eventOS_scheduler_timer_synch_after_sleep(uint32_t sleep_ticks) |
MACRUM | 0:119624335925 | 298 | { |
MACRUM | 0:119624335925 | 299 | //Update MS to 10ms ticks |
MACRUM | 0:119624335925 | 300 | sleep_ticks /= 10; |
MACRUM | 0:119624335925 | 301 | sleep_ticks++; |
MACRUM | 0:119624335925 | 302 | system_timer_tick_update(sleep_ticks); |
MACRUM | 0:119624335925 | 303 | if (timer_sys_wakeup() == 0) { |
MACRUM | 0:119624335925 | 304 | return 0; |
MACRUM | 0:119624335925 | 305 | } |
MACRUM | 0:119624335925 | 306 | return -1; |
MACRUM | 0:119624335925 | 307 | } |
MACRUM | 0:119624335925 | 308 | |
MACRUM | 0:119624335925 | 309 | /** |
MACRUM | 0:119624335925 | 310 | * |
MACRUM | 0:119624335925 | 311 | * \brief Infinite Event Read Loop. |
MACRUM | 0:119624335925 | 312 | * |
MACRUM | 0:119624335925 | 313 | * Function Read and handle Cores Event and switch/enable tasklet which are event receiver. WhenEvent queue is empty it goes to sleep |
MACRUM | 0:119624335925 | 314 | * |
MACRUM | 0:119624335925 | 315 | */ |
MACRUM | 0:119624335925 | 316 | bool eventOS_scheduler_dispatch_event(void) |
MACRUM | 0:119624335925 | 317 | { |
MACRUM | 0:119624335925 | 318 | curr_tasklet = 0; |
MACRUM | 0:119624335925 | 319 | |
MACRUM | 0:119624335925 | 320 | arm_event_storage_t *cur_event = event_core_read(); |
MACRUM | 0:119624335925 | 321 | if (!cur_event) { |
MACRUM | 0:119624335925 | 322 | return false; |
MACRUM | 0:119624335925 | 323 | } |
MACRUM | 0:119624335925 | 324 | |
MACRUM | 0:119624335925 | 325 | curr_tasklet = cur_event->data.receiver; |
MACRUM | 0:119624335925 | 326 | |
MACRUM | 0:119624335925 | 327 | arm_core_tasklet_t *tasklet = event_tasklet_handler_get(curr_tasklet); |
MACRUM | 0:119624335925 | 328 | /* Do not bother with check for NULL - tasklets cannot be deleted, |
MACRUM | 0:119624335925 | 329 | * and user-facing API eventOS_event_send() has already checked the tasklet |
MACRUM | 0:119624335925 | 330 | * exists, so there is no possible issue there. |
MACRUM | 0:119624335925 | 331 | * |
MACRUM | 0:119624335925 | 332 | * For eventOS_event_send_user_allocated(), it would be a non-recoverable |
MACRUM | 0:119624335925 | 333 | * error to not deliver the message - we have to have a receiver to pass |
MACRUM | 0:119624335925 | 334 | * ownership to. If the lookup fails, let it crash. We want the send call |
MACRUM | 0:119624335925 | 335 | * itself to return void to simplify logic. |
MACRUM | 0:119624335925 | 336 | */ |
MACRUM | 0:119624335925 | 337 | |
MACRUM | 0:119624335925 | 338 | /* Tasklet Scheduler Call */ |
MACRUM | 0:119624335925 | 339 | tasklet->func_ptr(&cur_event->data); |
MACRUM | 0:119624335925 | 340 | event_core_free_push(cur_event); |
MACRUM | 0:119624335925 | 341 | |
MACRUM | 0:119624335925 | 342 | /* Set Current Tasklet to Idle state */ |
MACRUM | 0:119624335925 | 343 | curr_tasklet = 0; |
MACRUM | 0:119624335925 | 344 | |
MACRUM | 0:119624335925 | 345 | return true; |
MACRUM | 0:119624335925 | 346 | } |
MACRUM | 0:119624335925 | 347 | |
MACRUM | 0:119624335925 | 348 | void eventOS_scheduler_run_until_idle(void) |
MACRUM | 0:119624335925 | 349 | { |
MACRUM | 0:119624335925 | 350 | while (eventOS_scheduler_dispatch_event()); |
MACRUM | 0:119624335925 | 351 | } |
MACRUM | 0:119624335925 | 352 | |
MACRUM | 0:119624335925 | 353 | /** |
MACRUM | 0:119624335925 | 354 | * |
MACRUM | 0:119624335925 | 355 | * \brief Infinite Event Read Loop. |
MACRUM | 0:119624335925 | 356 | * |
MACRUM | 0:119624335925 | 357 | * Function Read and handle Cores Event and switch/enable tasklet which are event receiver. WhenEvent queue is empty it goes to sleep |
MACRUM | 0:119624335925 | 358 | * |
MACRUM | 0:119624335925 | 359 | */ |
MACRUM | 0:119624335925 | 360 | NS_NORETURN void eventOS_scheduler_run(void) |
MACRUM | 0:119624335925 | 361 | { |
MACRUM | 0:119624335925 | 362 | while (1) { |
MACRUM | 0:119624335925 | 363 | if (!eventOS_scheduler_dispatch_event()) { |
MACRUM | 0:119624335925 | 364 | eventOS_scheduler_idle(); |
MACRUM | 0:119624335925 | 365 | } |
MACRUM | 0:119624335925 | 366 | } |
MACRUM | 0:119624335925 | 367 | } |
MACRUM | 0:119624335925 | 368 | |
MACRUM | 0:119624335925 | 369 | void eventOS_cancel(arm_event_storage_t *event) |
MACRUM | 0:119624335925 | 370 | { |
MACRUM | 0:119624335925 | 371 | if (!event) { |
MACRUM | 0:119624335925 | 372 | return; |
MACRUM | 0:119624335925 | 373 | } |
MACRUM | 0:119624335925 | 374 | |
MACRUM | 0:119624335925 | 375 | platform_enter_critical(); |
MACRUM | 0:119624335925 | 376 | |
MACRUM | 0:119624335925 | 377 | /* |
MACRUM | 0:119624335925 | 378 | * Notify timer of cancellation. |
MACRUM | 0:119624335925 | 379 | */ |
MACRUM | 0:119624335925 | 380 | if (event->allocator == ARM_LIB_EVENT_TIMER) { |
MACRUM | 0:119624335925 | 381 | timer_sys_event_cancel_critical(event); |
MACRUM | 0:119624335925 | 382 | } |
MACRUM | 0:119624335925 | 383 | |
MACRUM | 0:119624335925 | 384 | /* |
MACRUM | 0:119624335925 | 385 | * Remove event from the list, |
MACRUM | 0:119624335925 | 386 | * Only queued can be removed, unqued are either timers or stale pointers |
MACRUM | 0:119624335925 | 387 | * RUNNING cannot be removed, we are currenly "in" that event. |
MACRUM | 0:119624335925 | 388 | */ |
MACRUM | 0:119624335925 | 389 | if (event->state == ARM_LIB_EVENT_QUEUED) { |
MACRUM | 0:119624335925 | 390 | eventOS_event_cancel_critical(event); |
MACRUM | 0:119624335925 | 391 | } |
MACRUM | 0:119624335925 | 392 | |
MACRUM | 0:119624335925 | 393 | /* |
MACRUM | 0:119624335925 | 394 | * Push back to "free" state |
MACRUM | 0:119624335925 | 395 | */ |
MACRUM | 0:119624335925 | 396 | if (event->state != ARM_LIB_EVENT_RUNNING) { |
MACRUM | 0:119624335925 | 397 | event_core_free_push(event); |
MACRUM | 0:119624335925 | 398 | } |
MACRUM | 0:119624335925 | 399 | |
MACRUM | 0:119624335925 | 400 | platform_exit_critical(); |
MACRUM | 0:119624335925 | 401 | } |