µ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-clocks.h
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#ifndef CMSIS_PLUS_RTOS_OS_CLOCKS_H_
29#define CMSIS_PLUS_RTOS_OS_CLOCKS_H_
30
31// ----------------------------------------------------------------------------
32
33#if defined(__cplusplus)
34
35// ----------------------------------------------------------------------------
36
38
39// ----------------------------------------------------------------------------
40
41#pragma GCC diagnostic push
42
43#if defined(__clang__)
44#pragma clang diagnostic ignored "-Wc++98-compat"
45#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
46#endif
47
48// ----------------------------------------------------------------------------
49
50namespace os
51{
52 namespace rtos
53 {
54
55 // ========================================================================
56
57#pragma GCC diagnostic push
58#pragma GCC diagnostic ignored "-Wpadded"
59
66 {
67 public:
68
69 // ----------------------------------------------------------------------
70
84
93
103
108 // ----------------------------------------------------------------------
114 protected:
115
124 clock (const char* name);
125
130 public:
131
136 // The rule of five.
137 clock (const clock&) = delete;
138 clock (clock&&) = delete;
139 clock&
140 operator= (const clock&) = delete;
141 clock&
142 operator= (clock&&) = delete;
143
151 virtual
152 ~clock ();
153
158 // ----------------------------------------------------------------------
159 public:
160
173 virtual void
174 start (void) = 0;
175
183 virtual timestamp_t
184 now (void);
185
193 steady_now (void);
194
204 sleep_for (duration_t duration);
205
213 virtual result_t
214 sleep_until (timestamp_t timestamp);
215
225 wait_for (duration_t timeout);
226
234
245 virtual offset_t
246 offset (void);
247
253 virtual offset_t
254 offset (offset_t value);
255
257 steady_list (void);
258
259 void
260 internal_increment_count (void);
261
262 void
263 internal_check_timestamps (void);
264
273 protected:
274
286 virtual result_t
287 internal_wait_until_ (timestamp_t timestamp,
289
294 // ----------------------------------------------------------------------
305 duration_t volatile sleep_count_ = 0;
306
310 timestamp_t volatile steady_count_ = 0;
311
319 };
320
321#pragma GCC diagnostic pop
322
323 // ========================================================================
324
330 class adjustable_clock : public clock
331 {
332 // ----------------------------------------------------------------------
338 protected:
339
349 adjustable_clock (const char* name);
350
355 public:
356
361 // The rule of five.
362 adjustable_clock (const adjustable_clock&) = delete;
365 operator= (const adjustable_clock&) = delete;
367 operator= (adjustable_clock&&) = delete;
368
376 virtual
377 ~adjustable_clock () override;
378
383 public:
384
397 virtual timestamp_t
398 now (void) override;
399
407 virtual result_t
408 sleep_until (timestamp_t timestamp) override;
409
416 virtual offset_t
417 offset (void) override;
418
424 virtual offset_t
425 offset (offset_t value) override;
426
427 void
429
434 protected:
435
448 offset_t volatile offset_ = 0;
449
450 internal::clock_timestamps_list adjusted_list_;
451
459 };
460
461 // ========================================================================
462
468 class clock_systick : public clock
469 {
470 public:
471
481
486 // ----------------------------------------------------------------------
495 clock_systick ();
496
501 // The rule of five.
502 clock_systick (const clock_systick&) = delete;
503 clock_systick (clock_systick&&) = delete;
505 operator= (const clock_systick&) = delete;
507 operator= (clock_systick&&) = delete;
508
516 virtual
517 ~clock_systick () override;
518
523 // ----------------------------------------------------------------------
529 virtual void
530 start (void) override;
531
538 template<typename Rep_T>
539 static constexpr clock::duration_t
540 ticks_cast (Rep_T microsec);
541
546 // ----------------------------------------------------------------------
547 protected:
548
558#if defined(OS_USE_RTOS_PORT_CLOCK_SYSTICK_WAIT_FOR)
559
569 virtual result_t
570 internal_wait_until_ (timestamp_t timestamp, internal::clock_timestamps_list& list);
571
572#endif /* defined(OS_USE_RTOS_PORT_CLOCK_SYSTICK_WAIT_FOR) */
573
582 };
583
589 extern clock_systick sysclock;
590
591 // ========================================================================
592
599 {
600 public:
601
610 static constexpr uint32_t frequency_hz = 1;
611
616 // ----------------------------------------------------------------------
625 clock_rtc ();
626
631 // The rule of five.
632 clock_rtc (const clock_rtc&) = delete;
633 clock_rtc (clock_rtc&&) = delete;
634 clock_rtc&
635 operator= (const clock_rtc&) = delete;
636 clock_rtc&
637 operator= (clock_rtc&&) = delete;
638
646 virtual
647 ~clock_rtc () override;
648
653 // ----------------------------------------------------------------------
666 virtual void
667 start (void) override;
668
677#if defined(OS_USE_RTOS_PORT_CLOCK_REALTIME_WAIT_FOR)
678
688 virtual result_t
689 internal_wait_until_ (timestamp_t timestamp, clock_timestamps_list& list);
690
691#endif
692
697 };
698
704 extern clock_rtc rtclock;
705
706 // ========================================================================
707
713 class clock_highres : public clock
714 {
715 public:
716
725 clock_highres ();
726
731 // The rule of five.
732 clock_highres (const clock_highres&) = delete;
733 clock_highres (clock_highres&&) = delete;
735 operator= (const clock_highres&) = delete;
737 operator= (clock_highres&&) = delete;
738
746 virtual
747 ~clock_highres () override;
748
753 // ----------------------------------------------------------------------
759 virtual void
760 start (void) override;
761
768 virtual timestamp_t
769 now (void) override;
770
771 uint32_t
773
774 void
776
781 // ----------------------------------------------------------------------
782 protected:
783
793 };
794
800 extern clock_highres hrclock;
801
802 } /* namespace rtos */
803} /* namespace os */
804
805// ===== Inline & template implementations ====================================
806
807namespace os
808{
809 namespace rtos
810 {
811
812 // ========================================================================
813
818 inline
819 clock::clock (const char* name) :
820 internal::object_named
821 { name }
822 {
823 ;
824 }
825
826 inline internal::clock_timestamps_list&
827 __attribute__((always_inline))
828 clock::steady_list (void)
829 {
830 return steady_list_;
831 }
832
833 inline void
834 __attribute__((always_inline))
835 clock::internal_increment_count (void)
836 {
837 // One more tick count passed.
838
839#pragma GCC diagnostic push
840#if defined(__clang__)
841#pragma clang diagnostic ignored "-Wdeprecated-volatile"
842#endif
843 ++steady_count_;
844#pragma GCC diagnostic pop
845 }
846
847 inline void
848 __attribute__((always_inline))
849 clock::internal_check_timestamps (void)
850 {
851 steady_list_.check_timestamp (steady_count_);
852 }
853
858 // ========================================================================
859
864 inline
865 adjustable_clock::adjustable_clock (const char* name) :
866 clock
867 { name }
868 {
869 ;
870 }
871
872 inline void
873 __attribute__((always_inline))
875 {
876 clock::internal_check_timestamps ();
877
878#pragma GCC diagnostic push
879#pragma GCC diagnostic ignored "-Wsign-conversion"
880 adjusted_list_.check_timestamp (steady_count_ + offset_);
881#pragma GCC diagnostic pop
882 }
883
888 // ========================================================================
898 template<typename Rep_T>
899 constexpr clock::duration_t
900 clock_systick::ticks_cast (Rep_T microsec)
901 {
902 // TODO: add some restrictions to match only numeric types
903 return static_cast<clock::duration_t> ((((microsec)
904 * (static_cast<Rep_T> (frequency_hz)))
905 + static_cast<Rep_T> (1000000ul) - 1)
906 / static_cast<Rep_T> (1000000ul));
907 }
908
909#pragma GCC diagnostic push
910#if defined(__clang__)
911#pragma clang diagnostic ignored "-Wc++98-compat"
912#endif
916#pragma GCC diagnostic pop
917
918 // ========================================================================
919 inline void
920 __attribute__((always_inline))
921 clock_highres::internal_increment_count (void)
922 {
923 // Increment the highres count by SysTick divisor.
924#pragma GCC diagnostic push
925#if defined(__clang__)
926#pragma clang diagnostic ignored "-Wdeprecated-volatile"
927#endif
928 steady_count_ += port::clock_highres::cycles_per_tick ();
929#pragma GCC diagnostic pop
930 }
931
932 inline uint32_t
933 __attribute__((always_inline))
934 clock_highres::input_clock_frequency_hz (void)
935 {
937 }
938
939 // ========================================================================
940
941 } /* namespace rtos */
942} /* namespace os */
943
944#pragma GCC diagnostic pop
945
946// ----------------------------------------------------------------------------
947
948#endif /* __cplusplus */
949
950// ----------------------------------------------------------------------------
951
952#endif /* CMSIS_PLUS_RTOS_OS_CLOCKS_H_ */
Adjustable (non-steady) clock.
Definition os-clocks.h:331
virtual ~adjustable_clock() override
Destruct the clock object instance.
virtual timestamp_t now(void) override
Tell the current time adjusted for epoch.
virtual result_t sleep_until(timestamp_t timestamp) override
Sleep until an absolute timestamp.
virtual offset_t offset(void) override
Get adjustment offset.
void internal_check_timestamps(void)
High Resolution derived clock.
Definition os-clocks.h:714
void internal_increment_count(void)
Definition os-clocks.h:921
virtual ~clock_highres() override
Destruct the SysTick clock object instance.
virtual void start(void) override
uint32_t input_clock_frequency_hz(void)
Definition os-clocks.h:934
clock_highres()
Construct a SysTick clock object instance.
virtual timestamp_t now(void) override
Tell the current time.
Real time clock.
Definition os-clocks.h:599
static constexpr uint32_t frequency_hz
Real time clock frequency in Hz.
Definition os-clocks.h:610
virtual void start(void) override
Initialise and make the RTC tick.
virtual ~clock_rtc() override
Destruct the real time clock object instance.
clock_rtc()
Construct a real time clock object instance.
SysTick derived clock.
Definition os-clocks.h:469
static constexpr uint32_t frequency_hz
SysTick frequency in Hz.
Definition os-clocks.h:480
virtual ~clock_systick() override
Destruct the SysTick clock object instance.
clock_systick()
Construct a SysTick clock object instance.
static constexpr clock::duration_t ticks_cast(Rep_T microsec)
Convert microseconds to ticks.
virtual void start(void) override
Generic clock.
Definition os-clocks.h:66
result_t wait_for(duration_t timeout)
Timed wait for an event.
virtual result_t sleep_until(timestamp_t timestamp)
Sleep until an absolute timestamp.
timestamp_t update_for_slept_time(duration_t duration)
Increase the internal count after a deep sleep.
timestamp_t steady_now(void)
Tell the current time since startup.
virtual timestamp_t now(void)
Tell the current time, possibly adjusted for epoch.
virtual void start(void)=0
Start the clock.
virtual ~clock()
Destruct the clock object instance.
result_t sleep_for(duration_t duration)
Sleep for a relative duration.
Ordered list of time stamp nodes.
Definition os-lists.h:671
Base class for named objects.
Definition os-decls.h:365
const char * name(void) const
Get object name.
Definition os-decls.h:774
static uint32_t input_clock_frequency_hz(void)
static uint32_t cycles_per_tick(void)
#define OS_INTEGER_SYSTICK_FREQUENCY_HZ
Define the scheduler frequency, in Hz.
clock_t clock(void)
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition os-clocks.h:83
clock_highres hrclock
The high resolution clock object instance.
clock_rtc rtclock
The real time clock object instance.
port::clock::timestamp_t timestamp_t
Type of variables holding clock time stamps.
Definition os-clocks.h:92
clock_systick sysclock
The system clock object instance.
port::clock::offset_t offset_t
Type of variables holding clock offsets.
Definition os-clocks.h:102
uint32_t duration_t
Type of variables holding timer durations.
Definition os-decls.h:838
uint64_t timestamp_t
Type of variables holding time stamps.
Definition os-decls.h:846
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:110
System namespace.