µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
os-timer.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ distribution.
3 * (https://github.com/micro-os-plus)
4 * Copyright (c) 2016 Liviu Ionescu.
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following
13 * conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28#include <cmsis-plus/rtos/os.h>
29
30// ----------------------------------------------------------------------------
31
32#if defined(__clang__)
33#pragma clang diagnostic ignored "-Wc++98-compat"
34#endif
35
36// ----------------------------------------------------------------------------
37
38namespace os
39{
40 namespace rtos
41 {
42 // ------------------------------------------------------------------------
43
65 const timer::attributes timer::once_initializer;
66
77 const timer::attributes_periodic timer::periodic_initializer;
78
79 // ------------------------------------------------------------------------
80
123 // ========================================================================
150 timer::timer (func_t function, func_args_t args, const attributes& attr) :
151 timer
152 { nullptr, function, args, attr }
153 {
154 ;
155 }
156
183 timer::timer (const char* name, func_t function, func_args_t args,
184 const attributes& attr) :
185 object_named_system
186 { name }
187 {
188#if defined(OS_TRACE_RTOS_TIMER)
189 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
190#endif
191
192 // Don't call this from interrupt handlers.
194 // Don't call this from critical regions.
195 os_assert_throw(function != nullptr, EINVAL);
196
197 type_ = attr.tm_type;
198 func_ = function;
199 func_args_ = args;
200
201#if !defined(OS_USE_RTOS_PORT_TIMER)
202 clock_ = attr.clock != nullptr ? attr.clock : &sysclock;
203#endif
204
205#if defined(OS_USE_RTOS_PORT_TIMER)
206
207 port::timer::create (this, function, args);
208
209#else
210
211 period_ = 0;
212
213#endif
214 state_ = state::initialized;
215 }
216
228 {
229#if defined(OS_TRACE_RTOS_TIMER)
230 trace::printf ("%s() @%p %s\n", __func__, this, name ());
231#endif
232
233#if defined(OS_USE_RTOS_PORT_TIMER)
234
235 port::timer::destroy (this);
236
237#else
238
239 {
240 // ----- Enter critical section -------------------------------------
242
243 if (state_ == state::running)
244 {
245 timer_node_.unlink ();
246 }
247 // ----- Exit critical section --------------------------------------
248 }
249
250#endif
251 state_ = state::destroyed;
252 }
253
262 {
263#if defined(OS_TRACE_RTOS_TIMER)
264 trace::printf ("%s(%u) @%p %s\n", __func__,
265 static_cast<unsigned int> (period), this, name ());
266#endif
267
268 // Don't call this from interrupt handlers.
270
271 if (period == 0)
272 {
273 period = 1;
274 }
275
276 result_t res;
277
278#if defined(OS_USE_RTOS_PORT_TIMER)
279
280 res = port::timer::start (this, period);
281
282#else
283
284 period_ = period;
285
286 timer_node_.timestamp = clock_->steady_now () + period;
287
288 {
289 // ----- Enter critical section -------------------------------------
291
292 // If started, stop.
293 timer_node_.unlink ();
294
295 clock_->steady_list ().link (timer_node_);
296 // ----- Exit critical section --------------------------------------
297 }
298 res = result::ok;
299
300#endif
301
302 if (res == result::ok)
303 {
304 state_ = state::running;
305 }
306 return res;
307 }
308
320 {
321#if defined(OS_TRACE_RTOS_TIMER)
322 trace::printf ("%s() @%p %s\n", __func__, this, name ());
323#endif
324
325 // Don't call this from interrupt handlers.
327
328 if (state_ != state::running)
329 {
330 return EAGAIN;
331 }
332
333 result_t res;
334
335#if defined(OS_USE_RTOS_PORT_TIMER)
336
337 res = port::timer::stop (this);
338
339#else
340
341 {
342 // ----- Enter critical section -------------------------------------
344
345 timer_node_.unlink ();
346 // ----- Exit critical section --------------------------------------
347 }
348 res = result::ok;
349
350#endif
351
352 state_ = state::stopped;
353 return res;
354 }
355
356#if !defined(OS_USE_RTOS_PORT_TIMER)
357
362 void
363 timer::internal_interrupt_service_routine (void)
364 {
365
366 if (type_ == run::periodic)
367 {
368 // Re-arm the timer for the next period.
369 timer_node_.timestamp += period_;
370
371 // No need for critical section in ISR.
372 clock_->steady_list ().link (timer_node_);
373 }
374 else
375 {
376 state_ = state::completed;
377 }
378
379#if defined(OS_USE_RTOS_PORT_TIMER)
380 trace::puts (name ());
381#endif
382
383 // Call the user function.
384 func_ (func_args_);
385 }
386
391#endif
392
393 // --------------------------------------------------------------------------
394
395 } /* namespace rtos */
396} /* namespace os */
397
398// ----------------------------------------------------------------------------
const char * name(void) const
Get object name.
Definition os-decls.h:774
Interrupts critical section RAII helper.
Definition os-sched.h:524
Timer attributes.
Definition os-timer.h:143
User single-shot or periodic timer.
Definition os-timer.h:65
~timer()
Destruct the timer object instance.
Definition os-timer.cpp:227
timer(func_t function, func_args_t args, const attributes &attr=once_initializer)
Construct a timer object instance.
Definition os-timer.cpp:150
static const attributes once_initializer
Default one shot timer initialiser.
Definition os-timer.h:216
result_t stop(void)
Stop the timer.
Definition os-timer.cpp:319
result_t start(clock::duration_t period)
Start or restart the timer.
Definition os-timer.cpp:261
int puts(const char *s)
Write the string and a line terminator to the trace device.
Definition trace.cpp:108
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition os-clocks.h:83
clock_systick sysclock
The system clock object instance.
void * func_args_t
Timer call back function arguments.
Definition os-timer.h:72
void(*)(func_args_t args) func_t
Entry point of a timer call back function.
Definition os-timer.h:78
static const attributes_periodic periodic_initializer
Default periodic timer initialiser.
Definition os-timer.h:263
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition os-sched.h:1136
@ ok
Function completed; no errors or events occurred.
Definition os-decls.h:195
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:110
System namespace.
#define os_assert_throw(__e, __er)
Assert or throw a system error exception.
Definition os-decls.h:1141
#define os_assert_err(__e, __er)
Assert or return an error.
Definition os-decls.h:1126
Single file µOS++ RTOS definitions.
@ periodic
Run periodically.
Definition os-timer.h:103