Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ns_event_loop.c Source File

ns_event_loop.c

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2016-2017 ARM Ltd.
00003 //
00004 // SPDX-License-Identifier: Apache-2.0
00005 //
00006 // Licensed under the Apache License, Version 2.0 (the "License");
00007 // you may not use this file except in compliance with the License.
00008 // You may obtain a copy of the License at
00009 //
00010 //     http://www.apache.org/licenses/LICENSE-2.0
00011 //
00012 // Unless required by applicable law or agreed to in writing, software
00013 // distributed under the License is distributed on an "AS IS" BASIS,
00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 // See the License for the specific language governing permissions and
00016 // limitations under the License.
00017 // ----------------------------------------------------------------------------
00018 
00019 #include "ns_event_loop.h"
00020 
00021 #include "pal.h"
00022 #include "ns_trace.h"
00023 
00024 #include "eventOS_scheduler.h"
00025 
00026 #include <assert.h>
00027 
00028 
00029 #define TRACE_GROUP "evlp"
00030 
00031 static void event_loop_thread(const void *arg);
00032 
00033 static palThreadID_t event_thread_id = 0;
00034 static palMutexID_t event_mutex_id = 0;
00035 static palSemaphoreID_t event_start_sema_id = 0;
00036 static palSemaphoreID_t event_signal_sema_id = 0;
00037 static palSemaphoreID_t event_stop_sema_id = 0;
00038 static volatile bool event_stop_loop;
00039 
00040 void eventOS_scheduler_mutex_wait(void)
00041 {
00042     palStatus_t status;
00043     status = pal_osMutexWait(event_mutex_id, UINT32_MAX);
00044     assert(PAL_SUCCESS == status);
00045 }
00046 
00047 void eventOS_scheduler_mutex_release(void)
00048 {
00049     palStatus_t status;
00050     status = pal_osMutexRelease(event_mutex_id);
00051     assert(PAL_SUCCESS == status);
00052 }
00053 
00054 void eventOS_scheduler_signal(void)
00055 {
00056     palStatus_t status;
00057     status = pal_osSemaphoreRelease(event_signal_sema_id);
00058     assert(PAL_SUCCESS == status);
00059 }
00060 
00061 void eventOS_scheduler_idle(void)
00062 {
00063     int32_t counters = 0;
00064     palStatus_t status;
00065 
00066     eventOS_scheduler_mutex_release();
00067 
00068     status = pal_osSemaphoreWait(event_signal_sema_id, UINT32_MAX, &counters);
00069     assert(PAL_SUCCESS == status);
00070 
00071     eventOS_scheduler_mutex_wait();
00072 }
00073 
00074 static void event_loop_thread(const void *arg)
00075 {
00076     int32_t counters = 0;
00077     palStatus_t status;
00078 
00079     tr_debug("event_loop_thread create");
00080 
00081     event_stop_loop = false;
00082 
00083     status = pal_osSemaphoreWait(event_start_sema_id, UINT32_MAX, &counters);
00084     assert(PAL_SUCCESS == status);
00085 
00086     // TODO: Delete start semaphore?
00087     eventOS_scheduler_mutex_wait();
00088     tr_debug("event_loop_thread loop start");
00089 
00090     // A stoppable version of eventOS_scheduler_run(void)
00091     while (event_stop_loop == false) {
00092         if (!eventOS_scheduler_dispatch_event()) {
00093             eventOS_scheduler_idle();
00094         }
00095     }
00096     tr_debug("event_loop_thread loop end");
00097 
00098     // cleanup the scheduler timer resources which are not needed anymore
00099     eventOS_scheduler_timer_stop();
00100 
00101     // signal the ns_event_loop_thread_stop() that it can continue 
00102     status = pal_osSemaphoreRelease(event_stop_sema_id);
00103     assert(PAL_SUCCESS == status);
00104 }
00105 
00106 void ns_event_loop_thread_create(void)
00107 {
00108     int32_t counters = 0;
00109     palStatus_t status;
00110 
00111     status = pal_osSemaphoreCreate(1, &event_start_sema_id);
00112     assert(PAL_SUCCESS == status);
00113 
00114     status = pal_osSemaphoreWait(event_start_sema_id, UINT32_MAX, &counters);
00115     assert(PAL_SUCCESS == status);
00116 
00117     status = pal_osSemaphoreCreate(0, &event_stop_sema_id);
00118     assert(PAL_SUCCESS == status);
00119 
00120     status = pal_osSemaphoreCreate(1, &event_signal_sema_id);
00121     assert(PAL_SUCCESS == status);
00122 
00123     status = pal_osMutexCreate(&event_mutex_id);
00124     assert(PAL_SUCCESS == status);
00125 
00126     status = pal_osThreadCreateWithAlloc(event_loop_thread, NULL, PAL_osPriorityNormal, MBED_CONF_NS_HAL_PAL_EVENT_LOOP_THREAD_STACK_SIZE, NULL, &event_thread_id);
00127     assert(PAL_SUCCESS == status);
00128 }
00129 
00130 void ns_event_loop_thread_start(void)
00131 {
00132     palStatus_t status;
00133     status = pal_osSemaphoreRelease(event_start_sema_id);
00134     assert(PAL_SUCCESS == status);
00135 }
00136 
00137 void ns_event_loop_thread_stop(void)
00138 {
00139     palStatus_t status;
00140 
00141     // request loop to stop
00142     event_stop_loop = true;
00143 
00144     // Ping the even loop at least once more so it will notice the flag and
00145     // hopefully end the loop soon.
00146     eventOS_scheduler_signal();
00147 
00148     // wait until the event loop has been stopped and the thread is shutting down.
00149     // Note: the PAL API does not have any better means to join with a thread termination. 
00150     status = pal_osSemaphoreWait(event_stop_sema_id, UINT32_MAX, NULL);
00151     assert(PAL_SUCCESS == status);
00152 
00153     pal_osSemaphoreDelete(&event_start_sema_id);
00154     pal_osSemaphoreDelete(&event_stop_sema_id);
00155 }