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.
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 13:05:13 by
1.7.2