@@ -37,6 +37,52 @@ function RTC:secondsFromNowToEpoch(seconds_from_now)
37
37
return epoch
38
38
end
39
39
40
+
41
+ --[[ --
42
+ Enable/Disable the alarm interrupt.
43
+ The use of RTC_WKALM_SET allows us to bypass the need for RTC_AIE_* calls,
44
+ thanks to the enabled field in the rtc_wkalrm struct.
45
+ Busybox rtcwake still does an RTC_AIE_OFF when resuming from an alarm wakeup,
46
+ as does Nickel when powering off.
47
+ In this scenario, the modern util-linux rtcwake, which never uses legacy RTC_ALM_SET calls,
48
+ instead uses RTC_WKALM_SET filled from RTC_WKALM_RD but with enabled set to 0.
49
+
50
+ @enabled bool Whether the call enables or disables the alarm interrupt. Defaults to true.
51
+
52
+ @treturn bool Success.
53
+ @treturn re Error code (if any).
54
+ @treturn err Error string (if any).
55
+ --]]
56
+ function RTC :toggleAlarmInterrupt (enabled )
57
+ enabled = (enabled ~= nil ) and enabled or true
58
+
59
+ local err
60
+ local rtc0 = C .open (" /dev/rtc0" , bor (bor (C .O_RDONLY , C .O_NONBLOCK ), C .O_CLOEXEC ))
61
+ if rtc0 == - 1 then
62
+ err = ffi .string (C .strerror (ffi .errno ()))
63
+ print (" toggleAlarmInterrupt open /dev/rtc0" , rtc0 , err )
64
+ return nil , rtc0 , err
65
+ end
66
+ local re = C .ioctl (rtc0 , enabled and C .RTC_AIE_ON or C .RTC_AIE_OFF , 0 )
67
+ if re == - 1 then
68
+ err = ffi .string (C .strerror (ffi .errno ()))
69
+ if enabled then
70
+ print (" toggleAlarmInterrupt ioctl RTC_AIE_ON" , re , err )
71
+ else
72
+ print (" toggleAlarmInterrupt ioctl RTC_AIE_OFF" , re , err )
73
+ end
74
+ return nil , re , err
75
+ end
76
+ re = C .close (rtc0 )
77
+ if re == - 1 then
78
+ err = ffi .string (C .strerror (ffi .errno ()))
79
+ print (" toggleAlarmInterrupt close /dev/rtc0" , re , err )
80
+ return nil , re , err
81
+ end
82
+
83
+ return true
84
+ end
85
+
40
86
--[[ --
41
87
Set wakeup alarm.
42
88
103
149
Unset wakeup alarm.
104
150
--]]
105
151
function RTC :unsetWakeupAlarm ()
106
- self :setWakeupAlarm (- 1 , false )
152
+ -- NOTE: Both util-linux & busybox rtcwake leave the current alarm as-is, and just disable the alarm interrupt.
153
+ -- c.f., toggleAlarmInterrupt for details.
154
+ self :toggleAlarmInterrupt (false )
107
155
self ._wakeup_scheduled = false
108
156
self ._wakeup_scheduled_ptm = nil
109
157
end
0 commit comments