Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
m2mtimerpimpl.cpp
00001 /* 00002 * Copyright (c) 2015-2016 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include <assert.h> 00018 #include <time.h> 00019 00020 #include "mbed-client-classic/m2mtimerpimpl.h" 00021 #include "mbed-client/m2mtimerobserver.h" 00022 #include "mbed-client/m2mvector.h" 00023 00024 #include "eventOS_event.h" 00025 #include "eventOS_event_timer.h" 00026 #include "eventOS_scheduler.h" 00027 #include "ns_hal_init.h" 00028 #include "mbed-trace/mbed_trace.h" 00029 00030 #define TRACE_GROUP "mClt" 00031 00032 #define MBED_CLIENT_TIMER_EVENT 10 00033 00034 #ifdef MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE 00035 #define MBED_CLIENT_EVENT_LOOP_SIZE MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE 00036 #else 00037 #define MBED_CLIENT_EVENT_LOOP_SIZE 1024 00038 #endif 00039 00040 int8_t M2MTimerPimpl::_tasklet_id = -1; 00041 00042 int8_t M2MTimerPimpl::_next_timer_id = 1; 00043 00044 static m2m::Vector<M2MTimerPimpl*> timer_impl_list; 00045 00046 extern "C" void tasklet_func(arm_event_s *event) 00047 { 00048 // skip the init event as there will be a timer event after 00049 if (event->event_type == MBED_CLIENT_TIMER_EVENT) { 00050 00051 bool timer_found = false; 00052 eventOS_scheduler_mutex_wait(); 00053 int timer_count = timer_impl_list.size(); 00054 for (int index = 0; index < timer_count; index++) { 00055 M2MTimerPimpl* timer = timer_impl_list[index]; 00056 if (timer->get_timer_id() == event->event_id) { 00057 eventOS_scheduler_mutex_release(); 00058 timer_found = true; 00059 timer->timer_expired(); 00060 break; 00061 } 00062 } 00063 if(!timer_found) { 00064 eventOS_scheduler_mutex_release(); 00065 } 00066 } 00067 } 00068 00069 M2MTimerPimpl::M2MTimerPimpl(M2MTimerObserver& observer) 00070 : _observer(observer), 00071 _single_shot(true), 00072 _interval(0), 00073 _type(M2MTimerObserver::Notdefined), 00074 _intermediate_interval(0), 00075 _total_interval(0), 00076 _status(0), 00077 _dtls_type(false) 00078 { 00079 ns_hal_init(NULL, MBED_CLIENT_EVENT_LOOP_SIZE, NULL, NULL); 00080 eventOS_scheduler_mutex_wait(); 00081 if (_tasklet_id < 0) { 00082 _tasklet_id = eventOS_event_handler_create(tasklet_func, MBED_CLIENT_TIMER_EVENT); 00083 assert(_tasklet_id >= 0); 00084 } 00085 00086 // XXX: this wraps over quite soon 00087 _timer_id = M2MTimerPimpl::_next_timer_id++; 00088 00089 timer_impl_list.push_back(this); 00090 eventOS_scheduler_mutex_release(); 00091 } 00092 00093 M2MTimerPimpl::~M2MTimerPimpl() 00094 { 00095 // cancel the timer request, if any is pending 00096 cancel(); 00097 00098 // there is no turning back, event os does not have eventOS_event_handler_delete() or similar, 00099 // so the tasklet is lost forever. Same goes with timer_impl_list, which leaks now memory. 00100 00101 // remove the timer from object list 00102 eventOS_scheduler_mutex_wait(); 00103 int timer_count = timer_impl_list.size(); 00104 for (int index = 0; index < timer_count; index++) { 00105 00106 const M2MTimerPimpl* timer = timer_impl_list[index]; 00107 if (timer->get_timer_id() == _timer_id) { 00108 00109 timer_impl_list.erase(index); 00110 break; 00111 } 00112 } 00113 eventOS_scheduler_mutex_release(); 00114 } 00115 00116 void M2MTimerPimpl::start_timer( uint64_t interval, 00117 M2MTimerObserver::Type type, 00118 bool single_shot) 00119 { 00120 assert(interval <= INT32_MAX); 00121 00122 _dtls_type = false; 00123 _intermediate_interval = 0; 00124 _total_interval = 0; 00125 _status = 0; 00126 _single_shot = single_shot; 00127 _interval = interval; 00128 _type = type; 00129 start(); 00130 } 00131 00132 void M2MTimerPimpl::start_dtls_timer(uint64_t intermediate_interval, uint64_t total_interval, M2MTimerObserver::Type type) 00133 { 00134 assert(intermediate_interval <= INT32_MAX); 00135 assert(intermediate_interval <= total_interval); 00136 00137 _dtls_type = true; 00138 _intermediate_interval = intermediate_interval; 00139 _total_interval = total_interval; 00140 _interval = _intermediate_interval; 00141 _status = 0; 00142 _single_shot = false; 00143 _type = type; 00144 start(); 00145 } 00146 00147 void M2MTimerPimpl::start() 00148 { 00149 int status; 00150 00151 status = eventOS_event_timer_request(_timer_id, MBED_CLIENT_TIMER_EVENT, 00152 M2MTimerPimpl::_tasklet_id, 00153 _interval); 00154 assert(status == 0); 00155 } 00156 00157 void M2MTimerPimpl::cancel() 00158 { 00159 eventOS_event_timer_cancel(_timer_id, M2MTimerPimpl::_tasklet_id); 00160 } 00161 00162 void M2MTimerPimpl::stop_timer() 00163 { 00164 _interval = 0; 00165 _single_shot = true; 00166 cancel(); 00167 } 00168 00169 void M2MTimerPimpl::timer_expired() 00170 { 00171 _status++; 00172 _observer.timer_expired(_type); 00173 00174 if ((!_dtls_type) && (!_single_shot)) { 00175 // start next round of periodic timer 00176 start(); 00177 } else if ((_dtls_type) && (!is_total_interval_passed())) { 00178 // if only the intermediate time has passed, we need still wait up to total time 00179 _interval = _total_interval - _intermediate_interval; 00180 start(); 00181 } 00182 } 00183 00184 bool M2MTimerPimpl::is_intermediate_interval_passed() 00185 { 00186 if (_status > 0) { 00187 return true; 00188 } 00189 return false; 00190 } 00191 00192 bool M2MTimerPimpl::is_total_interval_passed() 00193 { 00194 if (_status > 1) { 00195 return true; 00196 } 00197 return false; 00198 }
Generated on Tue Jul 12 2022 12:28:39 by
1.7.2
