µ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++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2016-2025 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 */
11
12#if defined(OS_USE_OS_APP_CONFIG_H)
13#include <cmsis-plus/os-app-config.h>
14#endif
15
16#include <cmsis-plus/rtos/os.h>
17
18// ----------------------------------------------------------------------------
19
20#if defined(__clang__)
21#pragma clang diagnostic ignored "-Wc++98-compat"
22#endif
23
24// ----------------------------------------------------------------------------
25
26namespace os
27{
28 namespace rtos
29 {
30 // ------------------------------------------------------------------------
31
55 const timer::attributes timer::once_initializer;
56
61 const timer::attributes_periodic timer::periodic_initializer;
62
63 // ------------------------------------------------------------------------
64
108 // ========================================================================
135 timer::timer (func_t function, func_args_t args, const attributes& attr)
136 : timer{ nullptr, function, args, attr }
137 {
138 }
139
166 timer::timer (const char* name, func_t function, func_args_t args,
167 const attributes& attr)
168 : object_named_system{ name }
169 {
170#if defined(OS_TRACE_RTOS_TIMER)
171 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
172#endif
173
174 // Don't call this from interrupt handlers.
176 // Don't call this from critical regions.
177 os_assert_throw (function != nullptr, EINVAL);
178
179 type_ = attr.tm_type;
180 func_ = function;
181 func_args_ = args;
182
183#if !defined(OS_USE_RTOS_PORT_TIMER)
184 clock_ = attr.clock != nullptr ? attr.clock : &sysclock;
185#endif
186
187#if defined(OS_USE_RTOS_PORT_TIMER)
188
189 port::timer::create (this, function, args);
190
191#else
192
193 period_ = 0;
194
195#endif
196 state_ = state::initialized;
197 }
198
210 {
211#if defined(OS_TRACE_RTOS_TIMER)
212 trace::printf ("%s() @%p %s\n", __func__, this, name ());
213#endif
214
215#if defined(OS_USE_RTOS_PORT_TIMER)
216
217 port::timer::destroy (this);
218
219#else
220
221 {
222 // ----- Enter critical section ---------------------------------------
224
225 if (state_ == state::running)
226 {
227 timer_node_.unlink ();
228 }
229 // ----- Exit critical section ----------------------------------------
230 }
231
232#endif
233 state_ = state::destroyed;
234 }
235
244 {
245#if defined(OS_TRACE_RTOS_TIMER)
246#pragma GCC diagnostic push
247#if defined(__clang__)
248#elif defined(__GNUC__)
249#pragma GCC diagnostic ignored "-Wuseless-cast"
250#endif
251 trace::printf ("%s(%u) @%p %s\n", __func__,
252 static_cast<unsigned int> (period), this, name ());
253#pragma GCC diagnostic pop
254#endif
255
256 // Don't call this from interrupt handlers.
258
259 if (period == 0)
260 {
261 period = 1;
262 }
263
264 result_t res;
265
266#if defined(OS_USE_RTOS_PORT_TIMER)
267
268 res = port::timer::start (this, period);
269
270#else
271
272 period_ = period;
273
274 timer_node_.timestamp = clock_->steady_now () + period;
275
276 {
277 // ----- Enter critical section ---------------------------------------
279
280 // If started, stop.
281 timer_node_.unlink ();
282
283 clock_->steady_list ().link (timer_node_);
284 // ----- Exit critical section ----------------------------------------
285 }
286 res = result::ok;
287
288#endif
289
290 if (res == result::ok)
291 {
292 state_ = state::running;
293 }
294 return res;
295 }
296
308 {
309#if defined(OS_TRACE_RTOS_TIMER)
310 trace::printf ("%s() @%p %s\n", __func__, this, name ());
311#endif
312
313 // Don't call this from interrupt handlers.
315
316 if (state_ != state::running)
317 {
318 return EAGAIN;
319 }
320
321 result_t res;
322
323#if defined(OS_USE_RTOS_PORT_TIMER)
324
325 res = port::timer::stop (this);
326
327#else
328
329 {
330 // ----- Enter critical section ---------------------------------------
332
333 timer_node_.unlink ();
334 // ----- Exit critical section ----------------------------------------
335 }
336 res = result::ok;
337
338#endif
339
340 state_ = state::stopped;
341 return res;
342 }
343
344#if !defined(OS_USE_RTOS_PORT_TIMER)
345
350 void
351 timer::internal_interrupt_service_routine (void)
352 {
353
354 if (type_ == run::periodic)
355 {
356 // Re-arm the timer for the next period.
357 timer_node_.timestamp += period_;
358
359 // No need for critical section in ISR.
360 clock_->steady_list ().link (timer_node_);
361 }
362 else
363 {
364 state_ = state::completed;
365 }
366
367#if defined(OS_USE_RTOS_PORT_TIMER)
368 trace::puts (name ());
369#endif
370
371 // Call the user function.
372 func_ (func_args_);
373 }
374
379#endif
380
381 // ------------------------------------------------------------------------
382
383 } /* namespace rtos */
384} /* namespace os */
385
386// ----------------------------------------------------------------------------
rtos::clock * clock
Attribute with the address of the clock to be used for timeouts.
Definition os-decls.h:612
const char * name(void) const
Get object name.
Definition os-decls.h:753
Interrupts critical section RAII helper.
Definition os-sched.h:502
Timer attributes.
Definition os-timer.h:131
type_t tm_type
Timer type attribute.
Definition os-timer.h:187
User single-shot or periodic timer.
Definition os-timer.h:56
~timer()
Destruct the timer object instance.
Definition os-timer.cpp:209
timer(func_t function, func_args_t args, const attributes &attr=once_initializer)
Construct a timer object instance.
Definition os-timer.cpp:135
static const attributes once_initializer
Default one shot timer initialiser.
Definition os-timer.h:200
result_t stop(void)
Stop the timer.
Definition os-timer.cpp:307
result_t start(clock::duration_t period)
Start or restart the timer.
Definition os-timer.cpp:243
int puts(const char *s)
Write the string and a line terminator to the trace device.
Definition trace.cpp:102
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition os-clocks.h:78
clock_systick sysclock
The system clock object instance.
void * func_args_t
Timer call back function arguments.
Definition os-timer.h:62
void(*)(func_args_t args) func_t
Entry point of a timer call back function.
Definition os-timer.h:68
static const attributes_periodic periodic_initializer
Default periodic timer initialiser.
Definition os-timer.h:250
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition os-sched.h:1101
@ ok
Function completed; no errors or events occurred.
Definition os-decls.h:179
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:95
System namespace.
#define os_assert_throw(__e, __er)
Assert or throw a system error exception.
Definition os-decls.h:1122
#define os_assert_err(__e, __er)
Assert or return an error.
Definition os-decls.h:1101
Single file µOS++ RTOS definitions.
@ periodic
Run periodically.
Definition os-timer.h:92