µOS++ IIIe Reference  v6.3.15
“Perfekt ist nicht gut genug”
The third edition of µOS++, a POSIX inspired open source system, written in C++.
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 
36 
37 // ----------------------------------------------------------------------------
38 
39 namespace os
40 {
41  namespace rtos
42  {
43 
44  // ========================================================================
45 
46 #pragma GCC diagnostic push
47 #pragma GCC diagnostic ignored "-Wpadded"
48 
55  {
56  public:
57 
58  // ----------------------------------------------------------------------
59 
73 
82 
92 
97  // ----------------------------------------------------------------------
103  protected:
104 
113  clock (const char* name);
114 
119  public:
120 
125  // The rule of five.
126  clock (const clock&) = delete;
127  clock (clock&&) = delete;
128  clock&
129  operator= (const clock&) = delete;
130  clock&
131  operator= (clock&&) = delete;
132 
140  virtual
141  ~clock ();
142 
147  // ----------------------------------------------------------------------
148  public:
149 
162  virtual void
163  start (void) = 0;
164 
172  virtual timestamp_t
173  now (void);
174 
182  steady_now (void);
183 
192  result_t
193  sleep_for (duration_t duration);
194 
202  virtual result_t
203  sleep_until (timestamp_t timestamp);
204 
213  result_t
214  wait_for (duration_t timeout);
215 
223 
234  virtual offset_t
235  offset (void);
236 
242  virtual offset_t
243  offset (offset_t value);
244 
246  steady_list (void);
247 
248  void
249  internal_increment_count (void);
250 
251  void
252  internal_check_timestamps (void);
253 
262  protected:
263 
275  virtual result_t
276  internal_wait_until_ (timestamp_t timestamp,
278 
283  // ----------------------------------------------------------------------
293  internal::clock_timestamps_list steady_list_;
294  duration_t volatile sleep_count_ = 0;
295 
299  timestamp_t volatile steady_count_ = 0;
300 
308  };
309 
310 #pragma GCC diagnostic pop
311 
312  // ========================================================================
313 
319  class adjustable_clock : public clock
320  {
321  // ----------------------------------------------------------------------
327  protected:
328 
338  adjustable_clock (const char* name);
339 
344  public:
345 
350  // The rule of five.
351  adjustable_clock (const adjustable_clock&) = delete;
352  adjustable_clock (adjustable_clock&&) = delete;
354  operator= (const adjustable_clock&) = delete;
356  operator= (adjustable_clock&&) = delete;
357 
365  virtual
366  ~adjustable_clock () override;
367 
372  public:
373 
386  virtual timestamp_t
387  now (void) override;
388 
396  virtual result_t
397  sleep_until (timestamp_t timestamp) override;
398 
405  virtual offset_t
406  offset (void) override;
407 
413  virtual offset_t
414  offset (offset_t value) override;
415 
416  void
417  internal_check_timestamps (void);
418 
423  protected:
424 
437  offset_t volatile offset_ = 0;
438 
439  internal::clock_timestamps_list adjusted_list_;
440 
448  };
449 
450  // ========================================================================
451 
457  class clock_systick : public clock
458  {
459  public:
460 
469  static constexpr uint32_t frequency_hz = OS_INTEGER_SYSTICK_FREQUENCY_HZ;
470 
475  // ----------------------------------------------------------------------
484  clock_systick ();
485 
490  // The rule of five.
491  clock_systick (const clock_systick&) = delete;
492  clock_systick (clock_systick&&) = delete;
494  operator= (const clock_systick&) = delete;
496  operator= (clock_systick&&) = delete;
497 
505  virtual
506  ~clock_systick () override;
507 
512  // ----------------------------------------------------------------------
518  virtual void
519  start (void) override;
520 
527  template<typename Rep_T>
528  static constexpr clock::duration_t
529  ticks_cast (Rep_T microsec);
530 
535  // ----------------------------------------------------------------------
536  protected:
537 
547 #if defined(OS_USE_RTOS_PORT_CLOCK_SYSTICK_WAIT_FOR)
548 
558  virtual result_t
559  internal_wait_until_ (timestamp_t timestamp, internal::clock_timestamps_list& list);
560 
561 #endif /* defined(OS_USE_RTOS_PORT_CLOCK_SYSTICK_WAIT_FOR) */
562 
571  };
572 
578  extern clock_systick sysclock;
579 
580  // ========================================================================
581 
588  {
589  public:
590 
599  static constexpr uint32_t frequency_hz = 1;
600 
605  // ----------------------------------------------------------------------
614  clock_rtc ();
615 
620  // The rule of five.
621  clock_rtc (const clock_rtc&) = delete;
622  clock_rtc (clock_rtc&&) = delete;
623  clock_rtc&
624  operator= (const clock_rtc&) = delete;
625  clock_rtc&
626  operator= (clock_rtc&&) = delete;
627 
635  virtual
636  ~clock_rtc () override;
637 
642  // ----------------------------------------------------------------------
655  virtual void
656  start (void) override;
657 
666 #if defined(OS_USE_RTOS_PORT_CLOCK_REALTIME_WAIT_FOR)
667 
677  virtual result_t
678  internal_wait_until_ (timestamp_t timestamp, clock_timestamps_list& list);
679 
680 #endif
681 
686  };
687 
693  extern clock_rtc rtclock;
694 
695  // ========================================================================
696 
702  class clock_highres : public clock
703  {
704  public:
705 
714  clock_highres ();
715 
720  // The rule of five.
721  clock_highres (const clock_highres&) = delete;
722  clock_highres (clock_highres&&) = delete;
724  operator= (const clock_highres&) = delete;
726  operator= (clock_highres&&) = delete;
727 
735  virtual
736  ~clock_highres () override;
737 
742  // ----------------------------------------------------------------------
748  virtual void
749  start (void) override;
750 
757  virtual timestamp_t
758  now (void) override;
759 
760  uint32_t
761  input_clock_frequency_hz (void);
762 
763  void
764  internal_increment_count (void);
765 
770  // ----------------------------------------------------------------------
771  protected:
772 
782  };
783 
789  extern clock_highres hrclock;
790 
791  } /* namespace rtos */
792 } /* namespace os */
793 
794 // ===== Inline & template implementations ====================================
795 
796 namespace os
797 {
798  namespace rtos
799  {
800 
801  // ========================================================================
802 
807  inline
808  clock::clock (const char* name) :
810  { name }
811  {
812  ;
813  }
814 
816  __attribute__((always_inline))
817  clock::steady_list (void)
818  {
819  return steady_list_;
820  }
821 
822  inline void
823  __attribute__((always_inline))
824  clock::internal_increment_count (void)
825  {
826  // One more tick count passed.
827  ++steady_count_;
828  }
829 
830  inline void
831  __attribute__((always_inline))
832  clock::internal_check_timestamps (void)
833  {
834  steady_list_.check_timestamp (steady_count_);
835  }
836 
841  // ========================================================================
846  inline
847  adjustable_clock::adjustable_clock (const char* name) :
848  clock
849  { name }
850  {
851  ;
852  }
853 
854  inline void
855  __attribute__((always_inline))
857  {
858  clock::internal_check_timestamps ();
859 
860 #pragma GCC diagnostic push
861 #pragma GCC diagnostic ignored "-Wsign-conversion"
862  adjusted_list_.check_timestamp (steady_count_ + offset_);
863 #pragma GCC diagnostic pop
864  }
865 
870  // ========================================================================
880  template<typename Rep_T>
881  constexpr clock::duration_t
882  clock_systick::ticks_cast (Rep_T microsec)
883  {
884  // TODO: add some restrictions to match only numeric types
885  return static_cast<clock::duration_t> ((((microsec)
886  * (static_cast<Rep_T> (frequency_hz)))
887  + static_cast<Rep_T> (1000000ul) - 1)
888  / static_cast<Rep_T> (1000000ul));
889  }
890 
894  // ========================================================================
895  inline void
896  __attribute__((always_inline))
897  clock_highres::internal_increment_count (void)
898  {
899  // Increment the highres count by SysTick divisor.
900  steady_count_ += port::clock_highres::cycles_per_tick ();
901  }
902 
903  inline uint32_t
904  __attribute__((always_inline))
905  clock_highres::input_clock_frequency_hz (void)
906  {
908  }
909 
910  // ========================================================================
911 
912  } /* namespace rtos */
913 } /* namespace os */
914 
915 // ----------------------------------------------------------------------------
916 
917 #endif /* __cplusplus */
918 
919 #endif /* CMSIS_PLUS_RTOS_OS_CLOCKS_H_ */
virtual ~clock()
Destruct the clock object instance.
Definition: os-clocks.cpp:148
port::clock::timestamp_t timestamp_t
Type of variables holding clock time stamps.
Definition: os-clocks.h:81
High Resolution derived clock.
Definition: os-clocks.h:702
uint64_t timestamp_t
Type of variables holding time stamps.
Definition: os-decls.h:834
timestamp_t steady_now(void)
Tell the current time since startup.
Definition: os-clocks.cpp:185
port::clock::offset_t offset_t
Type of variables holding clock offsets.
Definition: os-clocks.h:91
virtual void start(void)=0
Start the clock.
Definition: os-clocks.cpp:158
System namespace.
clock_highres hrclock
The high resolution clock object instance.
Definition: os-clocks.cpp:717
Real time clock.
Definition: os-clocks.h:587
clock_rtc rtclock
The real time clock object instance.
Definition: os-clocks.cpp:660
static uint32_t input_clock_frequency_hz(void)
const char * name(void) const
Get object name.
Definition: os-decls.h:760
result_t sleep_for(duration_t duration)
Sleep for a relative duration.
Definition: os-clocks.cpp:201
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition: os-clocks.h:72
SysTick derived clock.
Definition: os-clocks.h:457
result_t wait_for(duration_t timeout)
Timed wait for an event.
Definition: os-clocks.cpp:286
Base class for named objects.
Definition: os-decls.h:350
clock_systick sysclock
The system clock object instance.
Definition: os-clocks.cpp:551
#define OS_INTEGER_SYSTICK_FREQUENCY_HZ
Define the scheduler frequency, in Hz.
static uint32_t cycles_per_tick(void)
clock_t clock(void)
virtual result_t sleep_until(timestamp_t timestamp)
Sleep until an absolute timestamp.
Definition: os-clocks.cpp:245
void check_timestamp(port::clock::timestamp_t now)
Check list time stamps.
Definition: os-lists.cpp:447
Adjustable (non-steady) clock.
Definition: os-clocks.h:319
Ordered list of time stamp nodes.
Definition: os-lists.h:657
Generic clock.
Definition: os-clocks.h:54
uint32_t duration_t
Type of variables holding timer durations.
Definition: os-decls.h:826
uint32_t result_t
Type of values returned by RTOS functions.
Definition: os-decls.h:96
timestamp_t update_for_slept_time(duration_t duration)
Increase the internal count after a deep sleep.
Definition: os-clocks.cpp:328
void internal_check_timestamps(void)
static constexpr clock::duration_t ticks_cast(Rep_T microsec)
Convert microseconds to ticks.
virtual timestamp_t now(void)
Tell the current time, possibly adjusted for epoch.
Definition: os-clocks.cpp:169