Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ns_event_loop.c Source File

ns_event_loop.c

00001 /*
00002  * Copyright (c) 2016 ARM Limited, All Rights Reserved
00003  */
00004 
00005 #include <mbed_assert.h>
00006 #include "cmsis.h"
00007 #include "cmsis_os2.h"
00008 #include "mbed_rtos_storage.h"
00009 #include "ns_trace.h"
00010 
00011 #include "eventOS_scheduler.h"
00012 
00013 #include "ns_event_loop.h"
00014 
00015 #define TRACE_GROUP "evlp"
00016 
00017 
00018 #if MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00019 
00020 static mbed_rtos_storage_event_flags_t event_flag_cb;
00021 static const osEventFlagsAttr_t event_flags_attr = {
00022     .name = "nanostack_event_flags",
00023     .cb_mem = &event_flag_cb,
00024     .cb_size = sizeof event_flag_cb
00025 };
00026 static osEventFlagsId_t event_flag_id;
00027 
00028 #else
00029 
00030 #ifndef MBED_TZ_DEFAULT_ACCESS
00031 #define MBED_TZ_DEFAULT_ACCESS   0
00032 #endif    
00033     
00034 static void event_loop_thread(void *arg);
00035 
00036 static uint64_t event_thread_stk[MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_THREAD_STACK_SIZE/8];
00037 static mbed_rtos_storage_thread_t event_thread_tcb;
00038 static const osThreadAttr_t event_thread_attr = {
00039     .name = "nanostack_event_thread",
00040     .priority = osPriorityNormal,
00041     .stack_mem = &event_thread_stk[0],
00042     .stack_size = sizeof event_thread_stk,
00043     .cb_mem = &event_thread_tcb,
00044     .cb_size = sizeof event_thread_tcb,
00045     .tz_module = MBED_TZ_DEFAULT_ACCESS,
00046 };
00047 #endif
00048 
00049 #if !MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00050 static osThreadId_t event_thread_id;
00051 #endif
00052 
00053 static mbed_rtos_storage_mutex_t event_mutex;
00054 static const osMutexAttr_t event_mutex_attr = {
00055   .name = "nanostack_event_mutex",
00056   .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
00057   .cb_mem = &event_mutex,
00058   .cb_size = sizeof event_mutex,
00059 };
00060 static osMutexId_t event_mutex_id;
00061 static osThreadId_t event_mutex_owner_id = NULL;
00062 static uint32_t owner_count = 0;
00063 
00064 void eventOS_scheduler_mutex_wait(void)
00065 {
00066     osMutexAcquire(event_mutex_id, osWaitForever);
00067     if (0 == owner_count) {
00068         event_mutex_owner_id = osThreadGetId();
00069     }
00070     owner_count++;
00071 }
00072 
00073 void eventOS_scheduler_mutex_release(void)
00074 {
00075     owner_count--;
00076     if (0 == owner_count) {
00077         event_mutex_owner_id = NULL;
00078     }
00079     osMutexRelease(event_mutex_id);
00080 }
00081 
00082 uint8_t eventOS_scheduler_mutex_is_owner(void)
00083 {
00084     return osThreadGetId() == event_mutex_owner_id ? 1 : 0;
00085 }
00086 
00087 void eventOS_scheduler_signal(void)
00088 {
00089     // XXX why does signal set lock if called with irqs disabled?
00090     //__enable_irq();
00091     //tr_debug("signal %p", (void*)event_thread_id);
00092 #if MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00093     osEventFlagsSet(event_flag_id, 1);
00094 #else
00095     osThreadFlagsSet(event_thread_id, 1);
00096 #endif
00097     //tr_debug("signalled %p", (void*)event_thread_id);
00098 }
00099 
00100 void eventOS_scheduler_idle(void)
00101 {
00102     //tr_debug("idle");
00103     eventOS_scheduler_mutex_release();
00104 
00105 #if MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00106     osEventFlagsWait(event_flag_id, 1, osFlagsWaitAny, osWaitForever);
00107 #else
00108     osThreadFlagsWait(1, 0, osWaitForever);
00109 #endif
00110 
00111     eventOS_scheduler_mutex_wait();
00112 }
00113 
00114 #if !MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00115 static void event_loop_thread(void *arg)
00116 {
00117     (void)arg;
00118     eventOS_scheduler_mutex_wait();
00119     eventOS_scheduler_run(); //Does not return
00120 }
00121 #endif
00122 
00123 // This is used to initialize the lock used by event loop even
00124 // if it is not ran in a separate thread.
00125 void ns_event_loop_init(void)
00126 {
00127     event_mutex_id = osMutexNew(&event_mutex_attr);
00128     MBED_ASSERT(event_mutex_id != NULL);
00129 
00130     // If a separate event loop thread is not used, the signaling
00131     // happens via event flags instead of thread flags. This allows one to
00132     // perform the initialization from any thread and removes need to know the id
00133     // of event loop dispatch thread.
00134 #if MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00135     event_flag_id  = osEventFlagsNew(&event_flags_attr);
00136     MBED_ASSERT(event_flag_id != NULL);
00137 #endif
00138 }
00139 
00140 #if !MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00141 void ns_event_loop_thread_create(void)
00142 {
00143     event_thread_id = osThreadNew(event_loop_thread, NULL, &event_thread_attr);
00144     MBED_ASSERT(event_thread_id != NULL);
00145 }
00146 
00147 void ns_event_loop_thread_start(void)
00148 {
00149 }
00150 #endif