gnat_arm_elf_13.2.1_db1e9283/arm-eabi/lib/gnat/embedded-stm32f4/gnarl/s-bbtime.ads

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
------------------------------------------------------------------------------
--                                                                          --
--                  GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS                --
--                                                                          --
--                         S Y S T E M . B B . T I M E                      --
--                                                                          --
--                                  S p e c                                 --
--                                                                          --
--        Copyright (C) 1999-2002 Universidad Politecnica de Madrid         --
--             Copyright (C) 2003-2004 The European Space Agency            --
--                     Copyright (C) 2003-2023, AdaCore                     --
--                                                                          --
-- GNARL is free software; you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
-- GNARL was developed by the GNARL team at Florida State University.       --
-- Extensive contributions were provided by Ada Core Technologies, Inc.     --
--                                                                          --
-- The port of GNARL to bare board targets was initially developed by the   --
-- Real-Time Systems Group at the Technical University of Madrid.           --
--                                                                          --
------------------------------------------------------------------------------

--  Package in charge of implementing clock and timer functionalities

pragma Restrictions (No_Elaboration_Code);

with System.Multiprocessors;

package System.BB.Time is
   pragma Preelaborate;

   type Time is mod 2 ** 64;
   for Time'Size use 64;

   ------------------
   -- Time keeping --
   ------------------

   --  Time is represented at this level as a 64-bit unsigned number. We assume
   --  that the Board_Support.Read_Clock function provides access to a hardware
   --  clock with a resolution of 20 microseconds or better, counting from
   --  0 to Board_Support.Max_Timer_Interval over a period of at least 0.735
   --  seconds, and returning a value of the 32-bit Timer_Interval type. The
   --  clock resolution should be an integral number of nanoseconds between 1
   --  and 20_000.

   --  In addition, Board_Support provides an alarm facility, generating an
   --  alarm interrupt at up to Max_Timer_Interval clock ticks in the future.
   --  The clock frequency is the same as for Read_Clock, but it may or may not
   --  use the same timer. See the next section for more information.

   --  The Time package uses these facilities to keep a 64-bit clock that will
   --  allow a program to keep track of up to 50 years in the future without
   --  having the most significant bit set. This means it is always safe to
   --  subtract two Clock readings to determine a Time_Span without overflow.

   --  We need to support a clock running for 50 years, so this requires
   --  a hardware clock period of at least 1_577_880_000 / 2**31 or 0.735
   --  seconds. As comparison, a LEON2 at 80 MHz with 24-bit clock and the
   --  minimum prescale factor of 4, has a period of 2**24 / (80E6 / 4) = 0.839
   --  seconds, while a 200 MHz LEON3 has a period of 2**32 / (200E6 / 5) =
   --  107 seconds. For faster clocks or smaller clock width, higher prescaler
   --  values may be needed to achieve 50 year run time. The prescale factor
   --  should be chosen such that the period between clock ticks is an integral
   --  number of nanoseconds between 1 and 20_000.

   type Time_Span is range -2 ** 63 .. 2 ** 63 - 1;
   for Time_Span'Size use 64;
   --  Time_Span represents the length of time intervals, and it is defined as
   --  a 64-bit signed integer.

   ------------
   -- Alarms --
   ------------

   --  Alarms are used for two purposes:

   --    * Waking up tasks that sleep as result of Delay_Until

   --    * Clock updates, to prevent undetected wrap-around of the
   --      hardware clock

   --  Alarms use the same time unit as the clock used for time keeping,
   --  and need to be able to provide an alarm up to slightly less than
   --  Max_Timer_Interval ticks in the future; there always will be a pending
   --  alarm within this time frame because of required clock updates. A
   --  requirement is that an alarm always can be handled within 1/8th of the
   --  time it takes the hardware clock to wrap around. This gives an upper
   --  bound to how early we have to set the alarm to ensure timely clock
   --  updates. This will result in an interrupt rate 14% higher than
   --  absolutely necessary. However, as long as sleep-related alarms are
   --  sufficiently frequent, no extra clock-related interrupts are necessary.

   --------------------
   -- Execution time --
   --------------------

   --  System.BB.Execution_Time will set these hooks to enable execution time
   --  computation only when needed.

   Scheduling_Event_Hook : access procedure := null;
   --  This hooks must be called when the charged account change: in case of
   --  rescheduling and before and after the handling of interrupt.

   --------------------
   -- Initialization --
   --------------------

   procedure Initialize_Timers;
   --  Initialize this package (clock and alarm handlers). Must be called
   --  before any other functions.

   ----------------
   -- Operations --
   ----------------

   function Epoch return Time;
   --  Get the reference startup time

   function Clock return Time;
   --  Get the number of ticks elapsed since startup

   procedure Delay_Until (T : Time);
   --  Suspend the calling thread until the absolute time specified by T

   function Get_Next_Timeout (CPU_Id : System.Multiprocessors.CPU) return Time;
   --  Get the date of the next alarm or timing event

   procedure Update_Alarm (Alarm : Time);
   --  Re-configure the timer if "Alarm" is earlier than the Pending_Alarm.
   --  Update_Alarm is the only routine allowed to set an alarm.

   --  Execution time

   --  Ada allows reading the execution time of any task. To support that, we
   --  need to have exclusive access to the time (which is costly as it is not
   --  possible to atomically read that value without using a spin lock and
   --  masking interrupts). To avoid that cost, let's split that type in two
   --  parts (that can be read or written atomically by the processor). It
   --  is not possible to read atomically the whole value, but it is possible
   --  to read a coherent value: if the time has been changed from A to B
   --  while being read, the value read is between A and B. Because of the
   --  architecture of the runtime, the execution time is always written
   --  atomically (written by the processor executing the task, within the
   --  kernel).

   --  The type Composite_Execution_Time is declared here so that s-bbthre
   --  doesn't depend on s-bbtiev. But this type is used by s-bbtiev.

   type Word is mod 2 ** 32;

   type Composite_Execution_Time is record
      High : Word;
      pragma Atomic (High);
      --  High part of execution time

      Low : Word;
      pragma Atomic (Low);
      --  Low part of execution time
   end record;

   Initial_Composite_Execution_Time : constant Composite_Execution_Time :=
                                                                     (0, 0);
   --  The initial value for Composite_Execution_Time

private
   pragma Inline (Clock);
   pragma Inline (Epoch);

end System.BB.Time;