File Coverage

blib/lib/Linux/RTC/Ioctl.pm
Criterion Covered Total %
statement 66 69 95.6
branch 21 32 65.6
condition 3 5 60.0
subroutine 12 13 92.3
pod 5 5 100.0
total 107 124 86.2


line stmt bran cond sub pod time code
1             package Linux::RTC::Ioctl;
2              
3 3     3   48834 use 5.006;
  3         7  
4 3     3   9 use strict;
  3         3  
  3         53  
5 3     3   9 use warnings FATAL => 'all';
  3         6  
  3         100  
6 3     3   10 use Carp;
  3         5  
  3         165  
7 3     3   11 use Cwd "realpath";
  3         6  
  3         1939  
8              
9             require Exporter;
10             # use AutoLoader;
11              
12             our @ISA = qw(Exporter);
13              
14             =head1 NAME
15              
16             Linux::RTC::Ioctl - Real Time Clock access using the Linux driver ioctl interface.
17              
18             =head1 VERSION
19              
20             Version 0.08
21              
22             =cut
23              
24             our $VERSION = '0.08';
25              
26              
27             =head1 SYNOPSIS
28              
29             Provides access to the Linux RTC driver (Real Time Clock), using one of
30             the RTC device files in a Linux system:
31              
32             - /dev/rtc
33             - /dev/rtc0
34             - /dev/rtc1
35             - ...
36              
37             Note F is now usually a symlink to F.
38              
39             Usage:
40              
41             use Linux::RTC::Ioctl;
42              
43             my $rtc = Linux::RTC::Ioctl->new($device) // die "Error: $!";
44              
45             $sec, $min, $hour, $mday, $mon, $year = $rtc->read_time;
46              
47             # or:
48             $rtc->read_time // die "Failed to read RTC device: $!";
49             $sec, $min, $hour = $rtc->{sec}, $rtc->{min}, $rtc->{hour};
50              
51             $rtc->{year} += 1;
52             $rtc->set_time; # Set RTC time one year in the future
53             $rtc->set_time($sec, $min, $hour, $mday, $mon, $year+1);
54              
55             $enable = !0;
56              
57             $rtc->update_interrupt($enable);
58              
59             $freq = 20;
60             $rtc->periodic_frequency($freq) // die "Access to RTC device failed: $!";
61             $freq = $rtc->periodic_frequency;
62             $rtc->periodic_interrupt($enable);
63              
64             $rtc->read_alarm // die "Access to RTC device ${\$rtc->nodename} failed: $!";
65             $rtc->set_alarm($sec, $min, $hour, $mday, $mon, $year);
66             $rtc->read_wakup_alarm
67             $rtc->set_wakeup_alarm($sec, $min, $hour, $mday, $mon, $year);
68             $rtc->alarm_interrupt($enable);
69              
70             =head1 DESCRIPTION
71              
72             C<$device> can be an open file handle, a device file name, a device number
73             (0, 1, 2..) or empty (C), in which case F is used.
74              
75             The Linux driver has built-in locking so that only one process can have the
76             F interface open at a time. You must be root or must have permissions
77             to access the device file, according to the usual file owner and group. User
78             processes than can access the device, still need to have the CAP_SYS_TIME
79             capability in order to use the C<< $rtc->set_time >> method.
80              
81             Beware the RTC time runs in the RTC time zone, which is not the same as the
82             local time zone of the system, as it can also be GMT. To prevent problems with
83             the transition to and from DST (daylight saving time), the RTC should run in the
84             GMT time zone, which is usually the default for the Linux setup. Note there is no
85             why to retrieve this time zone from the RTC device, the system stores this
86             information elsewhere (see the manual page for the `hwclock` command for more
87             details). Even if you know the RTC time zone, the RTC time will not accurately
88             match the system time. Linux OS learns how fast the RTC time is running compared
89             to real time, and if it is not accurate, Linux will constantly adjust the RTC
90             (every 11 min) to keep it close to the real time.
91              
92             Any functionality described here is present only when supported by the RTC
93             hardware. Methods that access the device return C in case of error,
94             in which case you can read the system error variable C<$!>. Methods are
95             defined only if the corresponding ioctl request is defined for the platform,
96             you can check for example C.
97              
98             All methods can take the date-time components from:
99              
100             =over 4
101              
102             =item * the argument list (if arguments are passed)
103              
104             =item * the C<$rtc> object fields (empty arguments list)
105              
106             =back
107              
108             All methods can return the date-time components as:
109              
110             =over 4
111              
112             =item * function result (if called in list context)
113              
114             =item * the C<$rtc> object fields (in scalar or void context)
115              
116             =back
117              
118             All information here is taken from:
119              
120             =over 4
121              
122             =item * the documentation for Linux RTC driver provided with the kernel at:
123             L
124              
125             =item * the 'rtc' manual page
126              
127             =item * the C header file >
128              
129             =back
130              
131             See your platform documentation for more information.
132              
133             =cut
134              
135             # This allows declaration use Linux::RTC::Ioctl ':all';
136             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
137             # will save memory.
138             our %EXPORT_TAGS = ( 'all' => [ qw(
139             RTC_AF
140             RTC_AIE_OFF
141             RTC_AIE_ON
142             RTC_ALM_READ
143             RTC_ALM_SET
144             RTC_EPOCH_READ
145             RTC_EPOCH_SET
146             RTC_IRQF
147             RTC_IRQP_READ
148             RTC_IRQP_SET
149             RTC_MAX_FREQ
150             RTC_PF
151             RTC_PIE_OFF
152             RTC_PIE_ON
153             RTC_PLL_GET
154             RTC_PLL_SET
155             RTC_RD_TIME
156             RTC_SET_TIME
157             RTC_UF
158             RTC_UIE_OFF
159             RTC_UIE_ON
160             RTC_VL_CLR
161             RTC_VL_READ
162             RTC_WIE_OFF
163             RTC_WIE_ON
164             RTC_WKALM_RD
165             RTC_WKALM_SET
166             RTC_RECORD_SIZE
167             ) ] );
168              
169             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
170              
171             =head1 METHODS
172              
173             =head2 my $rtc = Linux::RTC::Ioctl->new($device)
174              
175             Creates an RTC object from given open file handle, device file name, device index, or C by default.
176              
177             If an open file handle is given, it must represent a device file on the platform, that supportes the RTC ioctl requests.
178             Binary mode will be turned on for the open handle
179              
180             Only one process can open the same RTC device at a time. Returns C if opening fails, in which case you can read
181             the C<$!> variable.
182              
183             =cut
184              
185             sub new($;$)
186             {
187 5     5 1 556 my $self = bless
188             {
189             enabled => 0,
190             pending => 0,
191             sec => -1, min => -1, hour => -1, mday => -1, mon => -1, year => -1, wday => -1, yday => -1, isdst => -1
192             }, shift;
193              
194 5   50     14 my $device = (shift // '/dev/rtc');
195              
196 5         13 my $fd = fileno($device);
197              
198 5 100 66     18 if (defined($fd) && $fd >= 0)
199             {
200 2         3 binmode $device;
201              
202 2         3 $self->{device} = $device;
203              
204             # poor attempt to get a file name from the file handle, Linux only
205 2         7 $self->{nodename} = "/proc/$$/fd/$fd";
206 2 50       37 if (-e $self->{nodename})
207             {
208 2         72 $self->{nodename} = Cwd::realpath $self->{"nodename"};
209             }
210             else
211             {
212 0         0 $self->{nodename} = undef;
213             }
214             }
215             else
216             {
217            
218 3 50       10 $device = '/dev/rtc' . $device if ($device =~ m/^\d+$/);
219              
220 3 100       193 if (open $$self{'device'}, '<:unix:raw', $device)
221             {
222 2         5 binmode $self->{'device'};
223              
224 2         3 $self->{nodename} = $device;
225             }
226             else
227             {
228 1         220 carp "Failed to open real time clock device $device: $!";
229 1         3 $self = undef;
230             }
231             }
232              
233 5         14 return $self;
234             }
235              
236             =head2 $rtc->nodename
237              
238             The name of the device file that is used by this C<$rtc> object. This is given (or implied) by the argument passed to the C constructor.
239              
240             If the C constructor is given an open file handle (no file name), the nodename will be C, unless (on most Linux platforms) the file
241             name can still be found using procfs at a path of the form: C<< /proc//fd/ >>.
242              
243             Might be usefull to show error messages when C<$rtc> methods fail.
244              
245             =cut
246              
247             sub nodename(\%)
248             {
249 2     2 1 25 return $_[0]->{nodename};
250             }
251              
252             =head2 $rtc->device
253              
254             An open file handle for the RTC device file represented by this C<$rtc> object. This is a read-only character device that will block on read
255             until the next timer event occurs (either a time update interrupt, a periodic timer interrupt, or an alarm interrupt; timers use IRQ 8).
256             Usually you need to enable the timer interrupts before you can read from this file.
257              
258             When the event occurs, a block of fixed size (given by C, which is the size of an unsigned long on the native platform) can
259             be read, of which the low order byte is a bitmask of flags choosen from C (for periodic interrupt), C (time update interrupt) and
260             C (alarm interrupt), and the remaining bytes are a count of interrupts that occurred since the last read.
261              
262             You can also use the file handle in calls to C to avoid blocking the current thread on the RTC device only.
263              
264             Example for reading the device file:
265              
266             my $rtc_record = pack 'L!', 0;
267             my $record_size = length $rtc_record; # length also given as the package constant RTC_RECORD_SIZE
268             my $size = sysread $rtc->device, $rtc_record, $record_size; # blocks until next timer event occurs
269              
270             defined $size or die("Access to real time clock device failed: $!");
271             $size == $record_size or die("Unexpected end of file reading RTC device.");
272              
273             $rtc_record = unpack 'L!', $rtc_record;
274              
275             # Event flags and the interrupt count are now available
276             $timer_flags = $rtc_record & 0xFF;
277             $timer_count = $rtc_record >> 8;
278              
279             Or you can use the $rtc->wait_for_timer() method, which natively does about the same as the above.
280              
281             =cut
282              
283             sub device(\%)
284             {
285 2     2 1 9 return $_[0]->{device};
286             }
287              
288             =head2 $rtc->rtctime
289              
290             $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst = $rtc->rtctime
291             $rtc->rtctime($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
292              
293             Similar to C and C, C<< $rtc->rtctime >> returns a list of the the broken-down time components stored in the C<$rtc> object.
294             You can also pass such a list to this method, to populate the C<$rtc> object.
295              
296             There is no calendar time alternative to these components, measured as seconds from the begining of the Unix epoch. To build one you would need to
297             know the RTC time zone (either GMT or the local time zone), which the RTC device does not.
298              
299             The time components stored in the C<$rtc> object are used by the C, C and C methods when they are called
300             without any arguments. The time components are also populated by the C, C and C methods when they
301             are called in void or scalar context. When such methods are called in list context, the time components are returned as usual and are NOT stored
302             in the C<$rtc> object.
303              
304              
305             Note the RTC device does not use the last 3 time components: C<$wday>, C<$yday>, C<$isdst>. They are included here to match the platform C-language
306             API, but it f needed please exclude them with a sublist like C<< @{[ $rtc->rtctime ]}[0..5] >>.
307              
308             =cut
309              
310             sub rtctime(\%;$$$$$$$$$)
311             {
312 6     6 1 11 my $self = shift;
313              
314 6 100       13 if (scalar(@_) > 0)
315             {
316 2         2 $self->{sec} = shift;
317              
318 2 50       4 if (scalar(@_) > 0)
319             {
320 2         3 $self->{min} = shift;
321              
322 2 50       3 if (scalar(@_) > 0)
323             {
324 2         2 $self->{hour} = shift;
325              
326 2 50       4 if (scalar(@_) > 0)
327             {
328 2         2 $self->{mday} = shift;
329              
330 2 50       3 if (scalar(@_) > 0)
331             {
332 2         2 $self->{mon} = shift;
333              
334 2 50       4 if (scalar(@_) > 0)
335             {
336 2         2 $self->{year} = shift;
337              
338 2 100       4 if (scalar(@_) > 0)
339             {
340 1         2 $self->{wday} = shift;
341              
342 1 50       2 if (scalar(@_) > 0)
343             {
344 1         2 $self->{yday} = shift;
345              
346 1 50       2 if (scalar(@_) > 0)
347             {
348 1         2 $self->{isdst} = shift;
349             }
350             }
351             }
352             }
353             }
354             }
355             }
356             }
357             }
358              
359 6 100       14 if (wantarray())
360             {
361 4         27 return $self->{sec}, $self->{min}, $self->{hour}, $self->{mday}, $self->{mon}, $self->{year}, $self->{wday}, $self->{yday}, $self->{isdst};
362             }
363             }
364              
365             =head2 $rtc->wait_for_timer
366              
367             $event_flags, $event_count = $rtc->wait_for_timer();
368              
369             Wait for the next timer event.
370              
371             Will issue a read from this RTC device. Blocks the current thread, so only use if you set up the alarm or timer events, and/or
372             you know it is going to ring soon enough. To avoid blocking the thread for just the RTC device, you can use the $rtc->device
373             in a call to C.
374              
375             Returns a bitmask of flags indicating what timer events have occurred, and a count of all the events since the last read.
376             See the RTC_PF, RTC_UP, RTC_AF, RTC_IRQF falgs. If read failes returns C, in which case you can read the C<$!> variable.
377              
378              
379             =head2 $rtc->periodic_frequency
380              
381             $rtc->periodic_frequency($frequncy);
382             $frequency = $rtc->periodic_frequency;
383              
384             Sets up the the requency for periodic RTC events (interrupts). The frequency must be a power of 2 between 2 and C.
385             After setting the frequency you should also enable the periodic interrupt. Maximum frequency for a non-root user (usually 64)
386             can be read from file C. Returns C if the underlaying ioctl call failes, in which case
387             you can read the C<$!> variable.
388              
389             =head2 $rtc->periodic_interrupt($enable)
390              
391             Sets up the RTC device to emit or not periodic (frequncy) timer events (IRQ 8 interrupts). Enable or disable the periodic interrupts.
392             Returns C on failure from the underlaying ioctl call, read C<$!> variable.
393              
394             =head2 $rtc->update_interrupt($enable)
395              
396             Sets up the RTC device to emit or not update timer events (whenever the current time changes). Enable or disable the update interrupts.
397             Returns C on failure from the underlaying ioctl call, read C<$!> variable.
398              
399             =head2 $rtc->alarm_interrupt($enable)
400              
401             Sets up the RTC device to emit or not timer events (IRQ 8 interrupts). Enable or disable the alarm interrupts.
402             Returns C on failure from the underlaying ioctl call, read C<$!> variable.
403              
404             =head2 $rtc->read_time
405              
406             =head2 $rtc->set_time
407              
408             $rtc->read_time;
409             $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst = $rtc->read_time;
410            
411             $rtc->set_time;
412             $rtc->set_time($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
413              
414             Sets or reads the RTC date and time in the RTC time zone. Uses the members in C<$rtc>: C<< $rtc->{sec} >>, C<< $rtc->{min} >>
415             C<< $rtc->{hour} >>, C<< $rtc->{mday} >>, C<< $rtc->{mon} >>, C<< $rtc->year >>, C<< $rtc->{wday} >> (not used), C<< $rtc->{yday} >>
416             (not used), C<< $rtc->isdst >> (not used). These fields are similar to the components return from C or C: mon begins
417             with 0 for january, year begins with 0 for 1900. For non-root users, even if you can read the device, you still need CAP_SYS_TIME capability
418             to set the real time clock. Returns C on error, when you can read the C<$!> variable.
419              
420             =head2 $rtc->read_alarm
421              
422             =head2 $rtc->set_alarm
423              
424             $rtc->read_alarm;
425             $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst = $rtc->read_alarm;
426            
427             $rtc->set_alarm;
428             $rtc->set_alarm($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
429              
430             Sets or reads the RTC alarm time in the RTC time zone. Can use the members in C<$rtc>: C<< $rtc->{sec} >>, C<< $rtc->{min} >>
431             C<< $rtc->{hour} >>, C<< $rtc->{mday} >>, C<< $rtc->{mon} >>, C<< $rtc->year >>, C<< $rtc->{wday} >> (not used), C<< $rtc->{yday} >>
432             (not used), C<< $rtc->isdst >> (not used). The Linux documentation describes only the time components (sec, min, hour) as being used here,
433             and not the date components. These fields are similar to the components returned from C or C. Returns C on error,
434             when you can read the C<$!> variable.
435              
436             =head2 $rtc->read_wakeup_alarm
437              
438             =head2 $rtc->set_wakeup_alarm
439              
440             $rtc->read_wakup_alarm // die "Access to real time clock device ${\$rtc->nodename} failed: $!";
441             $enabled, $pending, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst = $rtc->read_wakeup_alarm;
442              
443             $rtc->set_wakeup_alarm // die "Access failed";
444             $rtc->set_wakeup_alarm($enabled, $pending, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) // die "Error";
445              
446             Some RTCs support these methods as improved (and preferred) versions of C<< $rtc->read_alarm >> and C<< $rtc->set_alarm >>.
447             The C<$enabled> argument or return is used to enable or disable the alarm interrupt for this alarm, the C<< $rtc->alarm_interrupt >> call
448             is not used for this alarm. The C<$pending> argument is used to report a pending interrupt, mostly for firmware, do not use it.
449              
450             Both time and date components should work to set the wake-up alarm. Some hardware allows periodic alarms if you use special values for year, month, day,
451             etc. On most hardware this alarm can kick the computer out of suspend / stand-by or power-off (might not work for laptops
452             when running on battery power). You might read wakeup-enable status from F file.
453              
454             If method arguments or results are not used, the time components can be found in the C<$rtc> object fields, as well as the two additional
455             fields C<< $rtc->{enabled} >> and C<< $rtc->{pending} >>.
456              
457             =head2 $rtc->read_voltage_low_indicator
458              
459             =head2 $rtc->clear_voltage_low_indicator
460              
461             $voltage_indicator = $rtc->read_voltage_low_indicator // die "Voltage Low indicator not supported $!."
462             $rtc->clear_voltage_low_indicator // die "Voltage low indicator not supported $!."
463              
464             Not directly documentated, presumably reads/resets RTC battery voltage low indicator for hardware that can report this.
465              
466             =head2 $rtc->close
467              
468             Closes the underlaying device in C<< $rtc->device >> (like C). The C<$rtc> object should no longer be used after calling this method.
469              
470             =cut
471              
472             sub close(\%)
473             {
474 0     0 1 0 return close $_[0]->{device};
475             }
476              
477             =head1 EXPORT
478              
479             Constants for use with the C call can be exported with:
480              
481             use Linux::RTC::Ioctl qw(:all)
482              
483             or you can export individual constants by name if you so wish.
484              
485             =head2 Exportable constants
486              
487             Each of the following constants is exported only if the platform defines it.
488              
489             =head3 ioctl requests:
490              
491             The following constants are exposed from the system headers of the underlaying
492             platofrm (see >), and have been used to implement the methods above.
493              
494             Enable/disable periodic interrupt. Can be used to generate a periodic signal
495             with any power of 2 frequency between 2Hz and C for root user
496             (usually max 64Hz for non-root, see F).
497             Using the maximum frequency is likely to consume CPU time resources on your
498             target machine.
499              
500             RTC_PIE_OFF
501             RTC_PIE_ON
502             RTC_MAX_FREQ
503              
504             Enable/disable timer interrupt on every time update. Since the RTC displays
505             time in seconds, the interrupt will occur once per second (1Hz)
506              
507             RTC_UIE_ON
508             RTC_UIE_OFF
509              
510             Enable/disable timer interrupt when the alarm rings.
511              
512             RTC_AIE_ON
513             RTC_AIE_OFF
514              
515             Read and set current RTC date and time.
516              
517             RTC_RD_TIME
518             RTC_SET_TIME
519              
520             Read and set the RTC time since the RTC epoch. This is not the same as the
521             Unix epoch normally used by the system.
522              
523             RTC_EPOCH_READ
524             RTC_EPOCH_SET
525              
526             Read or set the alarm time. Usually only hour, minutes and seconds are
527             supported.
528              
529             RTC_ALM_READ
530             RTC_ALM_SET
531              
532             Read or set the wake-up alarm time. Supports both date and time. For most hardware this alarm can pull the computer
533             out of suspend/sleep, and even out of hibrenate/poweroff.
534              
535             RTC_WKALM_RD
536             RTC_WKALM_SET
537              
538             Read / set periodic interrupt frequency:
539              
540             RTC_IRQP_READ
541             RTC_IRQP_SET
542              
543             =head3 Flags for records read from the RTC device file
544              
545             Record size (records from RTC device files are fixed-length), always defined as the native size of an unsigned long:
546              
547             RTC_RECORD_SIZE
548              
549             Flag indicating periodic interrupt has occurred:
550              
551             RTC_PF
552              
553             Flag indicating an update interrupt has occurred (current RTC time has just
554             changed):
555              
556             RTC_UF
557              
558             Flag indicating an alarm interrupt occurrent (the alarm was set and just went off):
559              
560             RTC_AF
561              
562             Flag indicating any of the above 3 flags is also set:
563              
564             RTC_IRQF
565              
566             =head3 Other constants
567              
568             These are not documented in the Linux kernel, but are exposed to C/C++
569             programs in the system headers.
570              
571             Read / set PLL correction (like the RTC used in Q40/Q60 computers):
572              
573             RTC_PLL_GET
574             RTC_PLL_SET
575              
576             Read voltage low detector / clear voltage low information:
577              
578             RTC_VL_READ
579             RTC_VL_CLR
580              
581             =head3 constant
582              
583             Internal method used to autoload the above constants.
584              
585             =cut
586              
587             =head1 AUTHOR
588              
589             Timothy Madden, C<< >>
590              
591             =head1 BUGS
592              
593             Please report any bugs or feature requests to C, or through
594             the web interface at L. I will be notified, and then you'll
595             automatically be notified of progress on your bug as I make changes.
596              
597             =head1 SUPPORT
598              
599             You can find documentation for this module with the perldoc command.
600              
601             perldoc Linux::RTC::Ioctl
602              
603              
604             You can also look for information at:
605              
606             =over 4
607              
608             =item * RT: CPAN's request tracker (report bugs here)
609              
610             L
611              
612             =item * AnnoCPAN: Annotated CPAN documentation
613              
614             L
615              
616             =item * CPAN Ratings
617              
618             L
619              
620             =item * Search CPAN
621              
622             L
623              
624             =back
625              
626              
627             =head1 ACKNOWLEDGEMENTS
628              
629              
630             =head1 LICENSE AND COPYRIGHT
631              
632             Copyright 2016 Timothy Madden.
633              
634             This program is free software; you can redistribute it and/or modify it
635             under the terms of either: the GNU General Public License as published
636             by the Free Software Foundation; or the Artistic License.
637              
638             See L for more information.
639              
640              
641             =cut
642              
643             sub AUTOLOAD
644             {
645             # This AUTOLOAD is used to 'autoload' constants from the constant()
646             # XS function.
647              
648 28     28   946 my $constname;
649 28         15 our $AUTOLOAD;
650 28         73 ($constname = $AUTOLOAD) =~ s/.*:://;
651 28 50       45 croak "&Linux::RTC::Ioctl::constant not defined" if $constname eq 'constant';
652 28         52 my ($error, $val) = constant($constname);
653 28 50       33 if ($error) { croak $error; }
  0         0  
654             {
655 3     3   14 no strict 'refs';
  3         6  
  3         258  
  28         15  
656 28     40   104 *$AUTOLOAD = sub { $val };
  40         3721  
657             }
658 28         45 goto &$AUTOLOAD;
659             }
660              
661             require XSLoader;
662             XSLoader::load('Linux::RTC::Ioctl', $VERSION);
663              
664             1; # Successfull return after loading Linux::RTC::Ioctl module