leo hendrickson / Mbed OS example-Ethernet-mbed-Cloud-connect
Committer:
leothedragon
Date:
Tue May 04 08:55:12 2021 +0000
Revision:
0:8f0bb79ddd48
nmn

Who changed what in which revision?

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