Daniel Vizcaya / Mbed OS 04_RTOS_Embebidos
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 static void event_loop_thread(void *arg);
00031 
00032 static uint64_t event_thread_stk[MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_THREAD_STACK_SIZE/8];
00033 static mbed_rtos_storage_thread_t event_thread_tcb;
00034 static const osThreadAttr_t event_thread_attr = {
00035     .name = "nanostack_event_thread",
00036     .priority = osPriorityNormal,
00037     .stack_mem = &event_thread_stk[0],
00038     .stack_size = sizeof event_thread_stk,
00039     .cb_mem = &event_thread_tcb,
00040     .cb_size = sizeof event_thread_tcb,
00041 };
00042 #endif
00043 
00044 #if !MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00045 static osThreadId_t event_thread_id;
00046 #endif
00047 
00048 static mbed_rtos_storage_mutex_t event_mutex;
00049 static const osMutexAttr_t event_mutex_attr = {
00050   .name = "nanostack_event_mutex",
00051   .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
00052   .cb_mem = &event_mutex,
00053   .cb_size = sizeof event_mutex,
00054 };
00055 static osMutexId_t event_mutex_id;
00056 static osThreadId_t event_mutex_owner_id = NULL;
00057 static uint32_t owner_count = 0;
00058 
00059 void eventOS_scheduler_mutex_wait(void)
00060 {
00061     osMutexAcquire(event_mutex_id, osWaitForever);
00062     if (0 == owner_count) {
00063         event_mutex_owner_id = osThreadGetId();
00064     }
00065     owner_count++;
00066 }
00067 
00068 void eventOS_scheduler_mutex_release(void)
00069 {
00070     owner_count--;
00071     if (0 == owner_count) {
00072         event_mutex_owner_id = NULL;
00073     }
00074     osMutexRelease(event_mutex_id);
00075 }
00076 
00077 uint8_t eventOS_scheduler_mutex_is_owner(void)
00078 {
00079     return osThreadGetId() == event_mutex_owner_id ? 1 : 0;
00080 }
00081 
00082 void eventOS_scheduler_signal(void)
00083 {
00084     // XXX why does signal set lock if called with irqs disabled?
00085     //__enable_irq();
00086     //tr_debug("signal %p", (void*)event_thread_id);
00087 #if MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00088     osEventFlagsSet(event_flag_id, 1);
00089 #else
00090     osThreadFlagsSet(event_thread_id, 1);
00091 #endif
00092     //tr_debug("signalled %p", (void*)event_thread_id);
00093 }
00094 
00095 void eventOS_scheduler_idle(void)
00096 {
00097     //tr_debug("idle");
00098     eventOS_scheduler_mutex_release();
00099 
00100 #if MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00101     osEventFlagsWait(event_flag_id, 1, osFlagsWaitAny, osWaitForever);
00102 #else
00103     osThreadFlagsWait(1, 0, osWaitForever);
00104 #endif
00105 
00106     eventOS_scheduler_mutex_wait();
00107 }
00108 
00109 #if !MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00110 static void event_loop_thread(void *arg)
00111 {
00112     (void)arg;
00113     eventOS_scheduler_mutex_wait();
00114     eventOS_scheduler_run(); //Does not return
00115 }
00116 #endif
00117 
00118 // This is used to initialize the lock used by event loop even
00119 // if it is not ran in a separate thread.
00120 void ns_event_loop_init(void)
00121 {
00122     event_mutex_id = osMutexNew(&event_mutex_attr);
00123     MBED_ASSERT(event_mutex_id != NULL);
00124 
00125     // If a separate event loop thread is not used, the signaling
00126     // happens via event flags instead of thread flags. This allows one to
00127     // perform the initialization from any thread and removes need to know the id
00128     // of event loop dispatch thread.
00129 #if MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00130     event_flag_id  = osEventFlagsNew(&event_flags_attr);
00131     MBED_ASSERT(event_flag_id != NULL);
00132 #endif
00133 }
00134 
00135 #if !MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION
00136 void ns_event_loop_thread_create(void)
00137 {
00138     event_thread_id = osThreadNew(event_loop_thread, NULL, &event_thread_attr);
00139     MBED_ASSERT(event_thread_id != NULL);
00140 }
00141 
00142 void ns_event_loop_thread_start(void)
00143 {
00144 }
00145 #endif