From 6e1ece8183c91670a1aa7a77858b6b69041cb92f Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 10 May 2022 13:06:13 -0400 Subject: [PATCH] watchdog cleanup and loop clock object --- reactor-plc/threads.lua | 12 +++---- rtu/threads.lua | 22 ++++++------ scada-common/util.lua | 71 ++++++++++++++++++++++++++++---------- supervisor/session/plc.lua | 2 +- supervisor/session/rtu.lua | 2 +- 5 files changed, 72 insertions(+), 37 deletions(-) diff --git a/reactor-plc/threads.lua b/reactor-plc/threads.lua index 9dcb26e..bf05f22 100644 --- a/reactor-plc/threads.lua +++ b/reactor-plc/threads.lua @@ -39,7 +39,7 @@ threads.thread__main = function (smem, init) -- send link requests at 0.5Hz (every 40 server ticks) (every 4 loop ticks) local LINK_TICKS = 4 local ticks_to_update = 0 - local loop_clock = nil + local loop_clock = util.new_clock(MAIN_CLOCK) -- load in from shared memory local networked = smem.networked @@ -47,7 +47,7 @@ threads.thread__main = function (smem, init) local plc_dev = smem.plc_dev local rps = smem.plc_sys.rps local plc_comms = smem.plc_sys.plc_comms - local conn_watchdog = smem.plc_sys.conn_watchdog + local conn_watchdog = smem.plc_sys.conn_watchdog ---@type watchdog -- event loop while true do @@ -55,11 +55,11 @@ threads.thread__main = function (smem, init) local event, param1, param2, param3, param4, param5 = os.pullEventRaw() -- handle event - if event == "timer" and param1 == loop_clock then + if event == "timer" and loop_clock.is_clock(param1) then -- core clock tick if networked then -- start next clock timer - loop_clock = os.startTimer(MAIN_CLOCK) + loop_clock.start() -- send updated data if not plc_state.no_modem then @@ -82,7 +82,7 @@ threads.thread__main = function (smem, init) -- pass the packet onto the comms message queue smem.q.mq_comms_rx.push_packet(packet) end - elseif event == "timer" and networked and param1 == conn_watchdog.get_timer() then + elseif event == "timer" and networked and conn_watchdog.is_timer(param1) then -- haven't heard from server recently? shutdown reactor plc_comms.unlink() smem.q.mq_rps.push_command(MQ__RPS_CMD.TRIP_TIMEOUT) @@ -165,7 +165,7 @@ threads.thread__main = function (smem, init) end elseif event == "clock_start" then -- start loop clock - loop_clock = os.startTimer(MAIN_CLOCK) + loop_clock.start() log.debug("main thread clock started") end diff --git a/rtu/threads.lua b/rtu/threads.lua index c113e1d..ef30b45 100644 --- a/rtu/threads.lua +++ b/rtu/threads.lua @@ -35,29 +35,30 @@ threads.thread__main = function (smem) local exec = function () log.debug("main thread start") - -- advertisement/heartbeat clock - local loop_clock = os.startTimer(MAIN_CLOCK) + -- main loop clock + local loop_clock = util.new_clock(MAIN_CLOCK) -- load in from shared memory local rtu_state = smem.rtu_state local rtu_dev = smem.rtu_dev local rtu_comms = smem.rtu_sys.rtu_comms - local conn_watchdog = smem.rtu_sys.conn_watchdog + local conn_watchdog = smem.rtu_sys.conn_watchdog ---@type watchdog local units = smem.rtu_sys.units + -- start clock + loop_clock.start() + -- event loop while true do ---@diagnostic disable-next-line: undefined-field local event, param1, param2, param3, param4, param5 = os.pullEventRaw() - if event == "timer" and param1 == loop_clock then + if event == "timer" and loop_clock.is_clock(param1) then -- start next clock timer - loop_clock = os.startTimer(MAIN_CLOCK) + loop_clock.start() - -- period tick, if we are linked send heartbeat, if not send advertisement - if rtu_state.linked then - rtu_comms.send_heartbeat() - else + -- period tick, if we are not linked send advertisement + if not rtu_state.linked then -- advertise units rtu_comms.send_advertisement(units) end @@ -68,7 +69,7 @@ threads.thread__main = function (smem) -- pass the packet onto the comms message queue smem.q.mq_comms.push_packet(packet) end - elseif event == "timer" and param1 == conn_watchdog.get_timer() then + elseif event == "timer" and conn_watchdog.is_timer(param1) then -- haven't heard from server recently? unlink rtu_comms.unlink(rtu_state) elseif event == "peripheral_detach" then @@ -162,7 +163,6 @@ threads.thread__comms = function (smem) -- load in from shared memory local rtu_state = smem.rtu_state local rtu_comms = smem.rtu_sys.rtu_comms - local conn_watchdog = smem.rtu_sys.conn_watchdog local units = smem.rtu_sys.units local comms_queue = smem.q.mq_comms diff --git a/scada-common/util.lua b/scada-common/util.lua index 78ab422..77ad4c9 100644 --- a/scada-common/util.lua +++ b/scada-common/util.lua @@ -67,40 +67,75 @@ end -- WATCHDOG -- -- ComputerCraft OS Timer based Watchdog --- triggers a timer event if not fed within 'timeout' seconds +---@param timeout number timeout duration +--- +--- triggers a timer event if not fed within 'timeout' seconds util.new_watchdog = function (timeout) - ---@diagnostic disable-next-line: undefined-field +---@diagnostic disable-next-line: undefined-field local start_timer = os.startTimer - ---@diagnostic disable-next-line: undefined-field +---@diagnostic disable-next-line: undefined-field local cancel_timer = os.cancelTimer local self = { - _timeout = timeout, - _wd_timer = start_timer(timeout) + timeout = timeout, + wd_timer = start_timer(timeout) } - local get_timer = function () - return self._wd_timer + ---@class watchdog + local public = {} + + ---@param timer number timer event timer ID + public.is_timer = function (timer) + return self.wd_timer == timer end - local feed = function () - if self._wd_timer ~= nil then - cancel_timer(self._wd_timer) + -- satiate the beast + public.feed = function () + if self.wd_timer ~= nil then + cancel_timer(self.wd_timer) end - self._wd_timer = start_timer(self._timeout) + self.wd_timer = start_timer(self.timeout) end - local cancel = function () - if self._wd_timer ~= nil then - cancel_timer(self._wd_timer) + -- cancel the watchdog + public.cancel = function () + if self.wd_timer ~= nil then + cancel_timer(self.wd_timer) end end - return { - get_timer = get_timer, - feed = feed, - cancel = cancel + return public +end + +-- LOOP CLOCK -- + +-- ComputerCraft OS Timer based Loop Clock +---@param period number clock period +--- +--- fires a timer event at the specified period, does not start at construct time +util.new_clock = function (period) +---@diagnostic disable-next-line: undefined-field + local start_timer = os.startTimer + + local self = { + period = period, + timer = nil } + + ---@class clock + local public = {} + + ---@param timer number timer event timer ID + public.is_clock = function (timer) + return self.timer == timer + end + + -- start the clock + public.start = function () + self.timer = start_timer(self.period) + end + + return public end return util diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index 22726d3..f6a12ca 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -403,7 +403,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue) -- check if a timer matches this session's watchdog local check_wd = function (timer) - return timer == self.plc_conn_watchdog.get_timer() + return self.plc_conn_watchdog.is_timer(timer) end -- close the connection diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index 2e79ec8..fb60904 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -115,7 +115,7 @@ rtu.new_session = function (id, in_queue, out_queue) -- check if a timer matches this session's watchdog local check_wd = function (timer) - return timer == self.rtu_conn_watchdog.get_timer() + return self.rtu_conn_watchdog.is_timer(timer) end -- close the connection