-
Notifications
You must be signed in to change notification settings - Fork 3
/
artClock.m
160 lines (139 loc) · 5.74 KB
/
artClock.m
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
(** artClock.m module provides access to the system clock.
Copyright (C) 2021 R. S. Doiel
Released under The 3-Clause BSD License.
See https://opensource.org/licenses/BSD-3-Clause
*)
MODULE artClock; (** NOT PORTABLE, Assumes Obc-3 rel 3.1.2 compiler *)
(* IMPORT SYSTEM; *)
TYPE
(** Clock and ClockDesc types holds a normalized presentation
of the system clock data structures. *)
Clock* = POINTER TO ClockDesc;
ClockDesc* = RECORD
(** this is what is used by clock_gettime(), clock_settime() and would be used to do time intervals. *)
seconds : INTEGER; (** Unix EPoch in seconds *)
nanoSeconds : INTEGER; (** nanoseconds *)
(** The following are based on C struct tm *)
year* : INTEGER; (** Normalized year *)
month* : INTEGER; (** 1 through 12, Jan. through Dec. *)
day* : INTEGER; (** 1 through 31 *)
hour* : INTEGER; (** 0 through 23 *)
minute* : INTEGER; (** 0 through 59 *)
second* : INTEGER; (** 0 through 59 *)
(** wDay is day of week 0 - 6, 6 = Saturday, 0 is Monday *)
wDay* : INTEGER;
(** yDay is a julian style date, days since start of year *)
yDay* : INTEGER;
(** isDST has three possible settings.
-1 (negative number) info unavailable,
zero if Standard Time, one if
Daylight Savings Time *)
isDST* : INTEGER;
(** utcOffset can be impacted by isDST state
and implementations on local system.
E.g. America/Los Angeles PST is -08:00 UTC,
America/Los Angeles PDT is -07:00 UTC *)
utcOffset* : INTEGER
END;
VAR
(** clock holds the values for the last call to either
Update() or Get(). *)
clock* : Clock;
(** clockError is TRUE if an error occurred on the last call
to the host's get_clocktime(), otherwise it is set to FALSE *)
clockError : BOOLEAN;
(** Interface into POSIX time, date infrastructure.
These procedures call into POSIX via OBNC's C interface. *)
(* GetRtcTime set the values of second,
minute, hour, day, month, year, wDay, yDay,
isDST and utcOffset based on the local time value returned
by C clock_gettime() and localtime() functions. The final
parameter "ok" will be TRUE if the call to clock_gettime()
was successful and FALSE otherwise.
NOTE: The values for year, month, day are normalized before
being updated. Year reflects the current year and month
is in the range of 1 through 12. *)
PROCEDURE GetRtcTime(VAR second, minute, hour, day, month, year, wDay, yDay, isDST, utcOffset, seconds, nanoSeconds : INTEGER; VAR ok : BOOLEAN) IS "get_rtc_time";
(* SetRtcTime sets the system clock using C clock_settime(). You
must of permission (e.g. root) for this to succeed. You provide
Year should be actual year (adjusting for 1900 happens in the C
level code) and month should be 1 to 12. If setting the system
time is successful then ok will be TRUE otherwise it will be
set to FALSE. *)
PROCEDURE SetRtcTime(second, minute, hour, day, month, year, wDay, yDay, isDST, utcOffset : INTEGER; VAR ok : BOOLEAN) IS "set_rtc_time";
(** Copy copies the values from source clock to destination *)
PROCEDURE Copy*(source : Clock; VAR dest : Clock);
BEGIN
dest.seconds := source.seconds;
dest.nanoSeconds := source.nanoSeconds;
dest.second := source.second;
dest.minute := source.minute;
dest.hour := source.hour;
dest.day := source.day;
dest.month := source.month;
dest.year := source.year;
dest.wDay := source.wDay;
dest.yDay := source.yDay;
dest.isDST := source.isDST;
dest.utcOffset := source.utcOffset;
END Copy;
(** Update populates Clock.clock based on what is
returned by host system clock.
NOTE: the year is normalized and month is in range 1 to 12
unlike the values return POSIX localtime(). *)
PROCEDURE Update*();
VAR second, minute, hour, day, month, year, wDay, yDay,
isDST, utcOffset, seconds, nanoSeconds : INTEGER;
ok : BOOLEAN;
BEGIN
GetRtcTime(second, minute, hour, day, month, year, wDay, yDay, isDST, utcOffset, seconds, nanoSeconds, ok);
(* Update the record requested, update the module's clock record *)
IF clock = NIL THEN
NEW(clock);
END;
clockError := ~ ok;
IF ok THEN
clock.seconds := seconds;
clock.nanoSeconds := nanoSeconds;
clock.year := year;
clock.month := month;
clock.day := day;
clock.hour := hour;
clock.minute := minute;
clock.second := second;
clock.wDay := wDay;
clock.yDay := yDay;
clock.isDST := isDST;
clock.utcOffset := utcOffset;
END;
END Update;
(** Get updates Clock.clock and sets the value of the
Clock from Clock.clock.
NOTE: the year is normalized and month is in range 1 to 12
unlike the values return POSIX localtime(). *)
PROCEDURE Get*(VAR c : Clock);
BEGIN
Update();
(* Update the record requested, update the module's clock record *)
IF c = NIL THEN
NEW(c);
END;
Copy(clock, c);
END Get;
(** Set attempts to set the host system clock. On most systems
this will require root level permissions. If successful
Clock.clock is updated and the value of
ok will be TRUE. If the host system clock isn't updated
(e.g. you don't have permission) then ok is set to FALSE.
NOTE: SetRtcTime() uses the C clock_settime() and localtime(). *)
PROCEDURE Set*(c : Clock; VAR ok : BOOLEAN);
BEGIN
SetRtcTime(c.second, c.minute, c.hour, c.day, c.month, c.year, c.wDay, c.yDay, c.isDST, c.utcOffset, ok);
IF ok THEN
Copy(c, clock);
END;
END Set;
BEGIN
(* SYSTEM.LOADLIB("./artClock.so"); *)
Update();
END artClock.