#580 work on reactor PLC wired comms
This commit is contained in:
parent
b57aceff15
commit
c62eaeb5a2
189
reactor-plc/backplane.lua
Normal file
189
reactor-plc/backplane.lua
Normal file
@ -0,0 +1,189 @@
|
||||
--
|
||||
-- Reactor PLC System Core Peripheral Backplane
|
||||
--
|
||||
|
||||
local log = require("scada-common.log")
|
||||
local network = require("scada-common.network")
|
||||
local ppm = require("scada-common.ppm")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local databus = require("reactor-plc.databus")
|
||||
local plc = require("reactor-plc.plc")
|
||||
|
||||
local println = util.println
|
||||
|
||||
---@class plc_backplane
|
||||
local backplane = {}
|
||||
|
||||
local _bp = {
|
||||
smem = nil, ---@type plc_shared_memory
|
||||
|
||||
wlan_pref = true,
|
||||
lan_iface = "",
|
||||
|
||||
act_nic = nil, ---@type nic
|
||||
wl_act = true,
|
||||
wd_nic = nil, ---@type nic|nil
|
||||
wl_nic = nil ---@type nic|nil
|
||||
}
|
||||
|
||||
-- initialize the system peripheral backplane<br>
|
||||
---@param config plc_config
|
||||
---@param __shared_memory plc_shared_memory
|
||||
--- EVENT_CONSUMER: this function consumes events
|
||||
function backplane.init(config, __shared_memory)
|
||||
_bp.smem = __shared_memory
|
||||
_bp.wlan_pref = config.PreferWireless
|
||||
_bp.lan_iface = config.WiredModem
|
||||
|
||||
local plc_dev = __shared_memory.plc_dev
|
||||
local plc_state = __shared_memory.plc_state
|
||||
|
||||
-- Modem Init
|
||||
|
||||
-- init wired NIC
|
||||
if type(config.WiredModem) == "string" then
|
||||
local modem = ppm.get_modem(_bp.lan_iface)
|
||||
_bp.wd_nic = network.nic(modem)
|
||||
|
||||
log.info("BKPLN: WIRED PHY_" .. util.trinary(modem, "UP ", "DOWN ") .. _bp.lan_iface)
|
||||
|
||||
-- set this as active for now
|
||||
_bp.wl_act = false
|
||||
_bp.act_nic = _bp.wd_nic
|
||||
end
|
||||
|
||||
-- init wireless NIC(s)
|
||||
if config.WirelessModem then
|
||||
local modem, iface = ppm.get_wireless_modem()
|
||||
_bp.wl_nic = network.nic(modem)
|
||||
|
||||
log.info("BKPLN: WIRELESS PHY_" .. util.trinary(modem, "UP ", "DOWN ") .. iface)
|
||||
|
||||
-- set this as active if connected or if both modems are disconnected and this is preferred
|
||||
if (modem and _bp.wlan_pref) or not (_bp.act_nic and _bp.act_nic.is_connected()) then
|
||||
_bp.wl_act = true
|
||||
_bp.act_nic = _bp.wl_nic
|
||||
end
|
||||
end
|
||||
|
||||
plc_state.no_modem = not _bp.act_nic.is_connected()
|
||||
|
||||
databus.tx_hw_modem(not plc_state.no_modem)
|
||||
|
||||
-- comms modem is required if networked
|
||||
if __shared_memory.networked and plc_state.no_modem then
|
||||
println("startup> comms modem not found")
|
||||
log.warning("BKPLN: no comms modem on startup")
|
||||
|
||||
plc_state.degraded = true
|
||||
end
|
||||
|
||||
-- Reactor Init
|
||||
|
||||
---@diagnostic disable-next-line: assign-type-mismatch
|
||||
plc_dev.reactor = ppm.get_fission_reactor()
|
||||
plc_state.no_reactor = plc_dev.reactor == nil
|
||||
|
||||
-- we need a reactor, can at least do some things even if it isn't formed though
|
||||
if plc_state.no_reactor then
|
||||
println("startup> fission reactor not found")
|
||||
log.warning("BKPLN: no reactor on startup")
|
||||
|
||||
plc_state.degraded = true
|
||||
plc_state.reactor_formed = false
|
||||
|
||||
-- mount a virtual peripheral to init the RPS with
|
||||
local _, dev = ppm.mount_virtual()
|
||||
plc_dev.reactor = dev
|
||||
|
||||
log.info("BKPLN: mounted virtual device as reactor")
|
||||
elseif not plc_dev.reactor.isFormed() then
|
||||
println("startup> fission reactor is not formed")
|
||||
log.warning("BKPLN: reactor logic adapter present, but reactor is not formed")
|
||||
|
||||
plc_state.degraded = true
|
||||
plc_state.reactor_formed = false
|
||||
else
|
||||
log.info("BKPLN: reactor detected")
|
||||
end
|
||||
end
|
||||
|
||||
-- get the active NIC
|
||||
---@return nic|nil
|
||||
function backplane.active_nic() return _bp.act_nic end
|
||||
|
||||
-- handle a backplane peripheral attach
|
||||
---@param iface string
|
||||
---@param type string
|
||||
---@param device table
|
||||
---@param print_no_fp function
|
||||
function backplane.attach(iface, type, device, print_no_fp)
|
||||
local networked = _bp.smem.networked
|
||||
local state = _bp.smem.plc_state
|
||||
local dev = _bp.smem.plc_dev
|
||||
local sys = _bp.smem.plc_sys
|
||||
|
||||
if state.no_reactor and (type == "fissionReactorLogicAdapter") then
|
||||
-- reconnected reactor
|
||||
dev.reactor = device
|
||||
state.no_reactor = false
|
||||
|
||||
print_no_fp("reactor reconnected")
|
||||
log.info("BKPLN: reactor reconnected")
|
||||
|
||||
-- we need to assume formed here as we cannot check in this main loop
|
||||
-- RPS will identify if it isn't and this will get set false later
|
||||
state.reactor_formed = true
|
||||
|
||||
-- determine if we are still in a degraded state
|
||||
if (not networked or not state.no_modem) and state.reactor_formed then
|
||||
state.degraded = false
|
||||
end
|
||||
|
||||
_bp.smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
|
||||
|
||||
sys.rps.reconnect_reactor(dev.reactor)
|
||||
if networked then
|
||||
sys.plc_comms.reconnect_reactor(dev.reactor)
|
||||
end
|
||||
|
||||
-- partial reset of RPS, specific to becoming formed/reconnected
|
||||
-- without this, auto control can't resume on chunk load
|
||||
sys.rps.reset_formed()
|
||||
elseif networked and type == "modem" then
|
||||
---@cast device Modem
|
||||
local is_comms_modem = util.trinary(dev.modem_wired, dev.modem_iface == iface, device.isWireless())
|
||||
|
||||
-- note, check init_ok first since nic will be nil if it is false
|
||||
if is_comms_modem and not (state.init_ok and nic.is_connected()) then
|
||||
-- reconnected modem
|
||||
dev.modem = device
|
||||
state.no_modem = false
|
||||
|
||||
if state.init_ok then nic.connect(device) end
|
||||
|
||||
print_no_fp("comms modem reconnected")
|
||||
log.info("comms modem reconnected")
|
||||
|
||||
-- determine if we are still in a degraded state
|
||||
if not state.no_reactor then
|
||||
state.degraded = false
|
||||
end
|
||||
elseif device.isWireless() then
|
||||
log.info("unused wireless modem connected")
|
||||
else
|
||||
log.info("non-comms wired modem connected")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- handle a backplane peripheral detach
|
||||
---@param iface string
|
||||
---@param type string
|
||||
---@param device table
|
||||
---@param print_no_fp function
|
||||
function backplane.detach(iface, type, device, print_no_fp)
|
||||
end
|
||||
|
||||
return backplane
|
||||
@ -81,7 +81,9 @@ local tmp_cfg = {
|
||||
SVR_Channel = nil, ---@type integer
|
||||
PLC_Channel = nil, ---@type integer
|
||||
ConnTimeout = nil, ---@type number
|
||||
WirelessModem = true,
|
||||
WiredModem = false, ---@type string|false
|
||||
PreferWireless = true,
|
||||
TrustedRange = nil, ---@type number
|
||||
AuthKey = "", ---@type string
|
||||
LogMode = 0, ---@type LOG_MODE
|
||||
@ -107,7 +109,9 @@ local fields = {
|
||||
{ "SVR_Channel", "SVR Channel", 16240 },
|
||||
{ "PLC_Channel", "PLC Channel", 16241 },
|
||||
{ "ConnTimeout", "Connection Timeout", 5 },
|
||||
{ "WiredModem", "Wired Modem", false },
|
||||
{ "WirelessModem", "Wireless/Ender Comms Modem", true },
|
||||
{ "WiredModem", "Wired Comms Modem", false },
|
||||
{ "PreferWireless", "Prefer Wireless Modem", true },
|
||||
{ "TrustedRange", "Trusted Range", 0 },
|
||||
{ "AuthKey", "Facility Auth Key" , ""},
|
||||
{ "LogMode", "Log Mode", log.MODE.APPEND },
|
||||
|
||||
@ -48,7 +48,9 @@ function plc.load_config()
|
||||
config.SVR_Channel = settings.get("SVR_Channel")
|
||||
config.PLC_Channel = settings.get("PLC_Channel")
|
||||
config.ConnTimeout = settings.get("ConnTimeout")
|
||||
config.WirelessModem = settings.get("WirelessModem")
|
||||
config.WiredModem = settings.get("WiredModem")
|
||||
config.PreferWireless = settings.get("PreferWireless")
|
||||
config.TrustedRange = settings.get("TrustedRange")
|
||||
config.AuthKey = settings.get("AuthKey")
|
||||
|
||||
@ -71,12 +73,15 @@ function plc.validate_config(cfg)
|
||||
cfv.assert_type_int(cfg.UnitID)
|
||||
cfv.assert_type_bool(cfg.EmerCoolEnable)
|
||||
|
||||
if cfg.Networked == true then
|
||||
if cfg.Networked then
|
||||
cfv.assert_channel(cfg.SVR_Channel)
|
||||
cfv.assert_channel(cfg.PLC_Channel)
|
||||
cfv.assert_type_num(cfg.ConnTimeout)
|
||||
cfv.assert_min(cfg.ConnTimeout, 2)
|
||||
cfv.assert_type_bool(cfg.WirelessModem)
|
||||
cfv.assert((cfg.WiredModem == false) or (type(cfg.WiredModem) == "string"))
|
||||
cfv.assert(cfg.WirelessModem or (type(cfg.WiredModem) == "string"))
|
||||
cfv.assert_type_bool(cfg.PreferWireless)
|
||||
cfv.assert_type_num(cfg.TrustedRange)
|
||||
cfv.assert_min(cfg.TrustedRange, 0)
|
||||
cfv.assert_type_str(cfg.AuthKey)
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
--
|
||||
|
||||
require("/initenv").init_env()
|
||||
local backplane = require("reactor-plc.backplane")
|
||||
|
||||
local comms = require("scada-common.comms")
|
||||
local crash = require("scada-common.crash")
|
||||
@ -87,7 +88,6 @@ local function main()
|
||||
-- PLC system state flags
|
||||
---@class plc_state
|
||||
plc_state = {
|
||||
init_ok = true,
|
||||
fp_ok = false,
|
||||
shutdown = false,
|
||||
degraded = true,
|
||||
@ -103,15 +103,14 @@ local function main()
|
||||
burn_rate = 0.0
|
||||
},
|
||||
|
||||
-- core PLC devices
|
||||
-- global PLC devices, still initialized by the backplane
|
||||
---@class plc_dev
|
||||
plc_dev = {
|
||||
reactor = ppm.get_fission_reactor(),
|
||||
modem_wired = type(config.WiredModem) == "string",
|
||||
modem_iface = config.WiredModem,
|
||||
modem = nil
|
||||
reactor = nil ---@type table
|
||||
},
|
||||
|
||||
-- system objects
|
||||
---@class plc_sys
|
||||
plc_sys = {
|
||||
rps = nil, ---@type rps
|
||||
nic = nil, ---@type nic
|
||||
@ -132,115 +131,66 @@ local function main()
|
||||
|
||||
local plc_state = __shared_memory.plc_state
|
||||
|
||||
-- get the configured modem
|
||||
if smem_dev.modem_wired then
|
||||
smem_dev.modem = ppm.get_modem(smem_dev.modem_iface)
|
||||
else smem_dev.modem = ppm.get_wireless_modem() end
|
||||
-- reactor and modem initialization
|
||||
backplane.init(config, __shared_memory)
|
||||
|
||||
-- initial state evaluation
|
||||
plc_state.no_reactor = smem_dev.reactor == nil
|
||||
plc_state.no_modem = smem_dev.modem == nil
|
||||
|
||||
-- we need a reactor, can at least do some things even if it isn't formed though
|
||||
if plc_state.no_reactor then
|
||||
println("init> fission reactor not found")
|
||||
log.warning("init> no reactor on startup")
|
||||
|
||||
plc_state.init_ok = false
|
||||
plc_state.degraded = true
|
||||
elseif not smem_dev.reactor.isFormed() then
|
||||
println("init> fission reactor is not formed")
|
||||
log.warning("init> reactor logic adapter present, but reactor is not formed")
|
||||
|
||||
plc_state.degraded = true
|
||||
plc_state.reactor_formed = false
|
||||
-- scram on boot if networked, otherwise leave the reactor be
|
||||
if __shared_memory.networked and (not plc_state.no_reactor) and plc_state.reactor_formed and smem_dev.reactor.getStatus() then
|
||||
log.debug("startup> power-on SCRAM")
|
||||
smem_dev.reactor.scram()
|
||||
end
|
||||
|
||||
-- comms modem is required if networked
|
||||
if __shared_memory.networked and plc_state.no_modem then
|
||||
println("init> comms modem not found")
|
||||
log.warning("init> no comms modem on startup")
|
||||
-- setup front panel
|
||||
local message
|
||||
plc_state.fp_ok, message = renderer.try_start_ui(config.FrontPanelTheme, config.ColorMode)
|
||||
|
||||
-- scram reactor if present and enabled
|
||||
if (smem_dev.reactor ~= nil) and plc_state.reactor_formed and smem_dev.reactor.getStatus() then
|
||||
smem_dev.reactor.scram()
|
||||
end
|
||||
|
||||
plc_state.init_ok = false
|
||||
plc_state.degraded = true
|
||||
-- ...or not
|
||||
if not plc_state.fp_ok then
|
||||
println_ts(util.c("UI error: ", message))
|
||||
println("startup> running without front panel")
|
||||
log.error(util.c("front panel GUI render failed with error ", message))
|
||||
log.info("startup> running in headless mode without front panel")
|
||||
end
|
||||
|
||||
-- print a log message to the terminal as long as the UI isn't running
|
||||
local function _println_no_fp(message) if not plc_state.fp_ok then println(message) end end
|
||||
local function _println_no_fp(msg) if not plc_state.fp_ok then println(msg) end end
|
||||
|
||||
-- PLC init<br>
|
||||
--- EVENT_CONSUMER: this function consumes events
|
||||
local function init()
|
||||
-- scram on boot if networked, otherwise leave the reactor be
|
||||
if __shared_memory.networked and (not plc_state.no_reactor) and plc_state.reactor_formed and smem_dev.reactor.getStatus() then
|
||||
smem_dev.reactor.scram()
|
||||
end
|
||||
----------------------------------------
|
||||
-- initialize PLC
|
||||
----------------------------------------
|
||||
|
||||
-- setup front panel
|
||||
if not renderer.ui_ready() then
|
||||
local message
|
||||
plc_state.fp_ok, message = renderer.try_start_ui(config.FrontPanelTheme, config.ColorMode)
|
||||
-- init reactor protection system
|
||||
smem_sys.rps = plc.rps_init(smem_dev.reactor, plc_state.reactor_formed)
|
||||
log.debug("startup> rps init")
|
||||
|
||||
-- ...or not
|
||||
if not plc_state.fp_ok then
|
||||
println_ts(util.c("UI error: ", message))
|
||||
println("init> running without front panel")
|
||||
log.error(util.c("front panel GUI render failed with error ", message))
|
||||
log.info("init> running in headless mode without front panel")
|
||||
end
|
||||
end
|
||||
|
||||
if plc_state.init_ok then
|
||||
-- init reactor protection system
|
||||
smem_sys.rps = plc.rps_init(smem_dev.reactor, plc_state.reactor_formed)
|
||||
log.debug("init> rps init")
|
||||
|
||||
if __shared_memory.networked then
|
||||
-- comms watchdog
|
||||
smem_sys.conn_watchdog = util.new_watchdog(config.ConnTimeout)
|
||||
log.debug("init> conn watchdog started")
|
||||
|
||||
-- create network interface then setup comms
|
||||
smem_sys.nic = network.nic(smem_dev.modem)
|
||||
smem_sys.plc_comms = plc.comms(R_PLC_VERSION, smem_sys.nic, smem_dev.reactor, smem_sys.rps, smem_sys.conn_watchdog)
|
||||
log.debug("init> comms init")
|
||||
else
|
||||
_println_no_fp("init> starting in offline mode")
|
||||
log.info("init> running without networking")
|
||||
end
|
||||
|
||||
-- notify user of emergency coolant configuration status
|
||||
if config.EmerCoolEnable then
|
||||
println("init> emergency coolant control ready")
|
||||
log.info("init> running with emergency coolant control available")
|
||||
end
|
||||
|
||||
util.push_event("clock_start")
|
||||
|
||||
_println_no_fp("init> completed")
|
||||
log.info("init> startup completed")
|
||||
else
|
||||
_println_no_fp("init> system in degraded state, awaiting devices...")
|
||||
log.warning("init> started in a degraded state, awaiting peripheral connections...")
|
||||
end
|
||||
|
||||
databus.tx_hw_status(plc_state)
|
||||
-- notify user of emergency coolant configuration status
|
||||
if config.EmerCoolEnable then
|
||||
_println_no_fp("startup> emergency coolant control ready")
|
||||
log.info("startup> emergency coolant control available")
|
||||
end
|
||||
|
||||
----------------------------------------
|
||||
-- start system
|
||||
----------------------------------------
|
||||
-- conditionally init comms
|
||||
if __shared_memory.networked then
|
||||
-- comms watchdog
|
||||
smem_sys.conn_watchdog = util.new_watchdog(config.ConnTimeout)
|
||||
log.debug("startup> conn watchdog started")
|
||||
|
||||
-- initialize PLC
|
||||
init()
|
||||
-- create network interface then setup comms
|
||||
smem_sys.nic = network.nic(backplane.active_nic())
|
||||
smem_sys.plc_comms = plc.comms(R_PLC_VERSION, smem_sys.nic, smem_dev.reactor, smem_sys.rps, smem_sys.conn_watchdog)
|
||||
log.debug("startup> comms init")
|
||||
else
|
||||
_println_no_fp("startup> starting in non-networked mode")
|
||||
log.info("startup> starting without networking")
|
||||
end
|
||||
|
||||
databus.tx_hw_status(plc_state)
|
||||
|
||||
_println_no_fp("startup> completed")
|
||||
log.info("startup> completed")
|
||||
|
||||
-- init threads
|
||||
local main_thread = threads.thread__main(__shared_memory, init)
|
||||
local main_thread = threads.thread__main(__shared_memory)
|
||||
local rps_thread = threads.thread__rps(__shared_memory)
|
||||
|
||||
if __shared_memory.networked then
|
||||
@ -254,14 +204,12 @@ local function main()
|
||||
-- run threads
|
||||
parallel.waitForAll(main_thread.p_exec, rps_thread.p_exec, comms_thread_tx.p_exec, comms_thread_rx.p_exec, sp_ctrl_thread.p_exec)
|
||||
|
||||
if plc_state.init_ok then
|
||||
-- send status one last time after RPS shutdown
|
||||
smem_sys.plc_comms.send_status(plc_state.no_reactor, plc_state.reactor_formed)
|
||||
smem_sys.plc_comms.send_rps_status()
|
||||
-- send status one last time after RPS shutdown
|
||||
smem_sys.plc_comms.send_status(plc_state.no_reactor, plc_state.reactor_formed)
|
||||
smem_sys.plc_comms.send_rps_status()
|
||||
|
||||
-- close connection
|
||||
smem_sys.plc_comms.close()
|
||||
end
|
||||
-- close connection
|
||||
smem_sys.plc_comms.close()
|
||||
else
|
||||
-- run threads, excluding comms
|
||||
parallel.waitForAll(main_thread.p_exec, rps_thread.p_exec)
|
||||
|
||||
@ -31,8 +31,7 @@ local MQ__COMM_CMD = {
|
||||
-- main thread
|
||||
---@nodiscard
|
||||
---@param smem plc_shared_memory
|
||||
---@param init function
|
||||
function threads.thread__main(smem, init)
|
||||
function threads.thread__main(smem)
|
||||
-- print a log message to the terminal as long as the UI isn't running
|
||||
local function println_ts(message) if not smem.plc_state.fp_ok then util.println_ts(message) end end
|
||||
|
||||
@ -42,7 +41,7 @@ function threads.thread__main(smem, init)
|
||||
-- execute thread
|
||||
function public.exec()
|
||||
databus.tx_rt_status("main", true)
|
||||
log.debug("main thread init, clock inactive")
|
||||
log.debug("main thread start")
|
||||
|
||||
-- send status updates at 2Hz (every 10 server ticks) (every loop tick)
|
||||
-- send link requests at 0.5Hz (every 40 server ticks) (every 8 loop ticks)
|
||||
@ -55,6 +54,9 @@ function threads.thread__main(smem, init)
|
||||
local plc_state = smem.plc_state
|
||||
local plc_dev = smem.plc_dev
|
||||
|
||||
-- start clock
|
||||
loop_clock.start()
|
||||
|
||||
-- event loop
|
||||
while true do
|
||||
-- get plc_sys fields (may have been set late due to degraded boot)
|
||||
@ -67,7 +69,6 @@ function threads.thread__main(smem, init)
|
||||
|
||||
-- handle event
|
||||
if event == "timer" and loop_clock.is_clock(param1) then
|
||||
-- note: loop clock is only running if init_ok = true
|
||||
-- blink heartbeat indicator
|
||||
databus.heartbeat()
|
||||
|
||||
@ -118,14 +119,14 @@ function threads.thread__main(smem, init)
|
||||
|
||||
-- update indicators
|
||||
databus.tx_hw_status(plc_state)
|
||||
elseif event == "modem_message" and networked and plc_state.init_ok and nic.is_connected() then
|
||||
elseif event == "modem_message" and networked and nic.is_connected() then
|
||||
-- got a packet
|
||||
local packet = plc_comms.parse_packet(param1, param2, param3, param4, param5)
|
||||
if packet ~= nil then
|
||||
-- pass the packet onto the comms message queue
|
||||
smem.q.mq_comms_rx.push_packet(packet)
|
||||
end
|
||||
elseif event == "timer" and networked and plc_state.init_ok and conn_watchdog.is_timer(param1) then
|
||||
elseif event == "timer" and networked and conn_watchdog.is_timer(param1) then
|
||||
-- haven't heard from server recently? close connection and shutdown reactor
|
||||
plc_comms.close()
|
||||
smem.q.mq_rps.push_command(MQ__RPS_CMD.TRIP_TIMEOUT)
|
||||
@ -146,8 +147,7 @@ function threads.thread__main(smem, init)
|
||||
elseif networked and type == "modem" then
|
||||
---@cast device Modem
|
||||
-- we only care if this is our comms modem
|
||||
-- note, check init_ok first since nic will be nil if it is false
|
||||
if plc_state.init_ok and nic.is_modem(device) then
|
||||
if nic.is_modem(device) then
|
||||
nic.disconnect()
|
||||
|
||||
println_ts("comms modem disconnected!")
|
||||
@ -184,7 +184,7 @@ function threads.thread__main(smem, init)
|
||||
plc_dev.reactor = device
|
||||
plc_state.no_reactor = false
|
||||
|
||||
println_ts("reactor reconnected.")
|
||||
println_ts("reactor reconnected")
|
||||
log.info("reactor reconnected")
|
||||
|
||||
-- we need to assume formed here as we cannot check in this main loop
|
||||
@ -220,7 +220,7 @@ function threads.thread__main(smem, init)
|
||||
|
||||
if plc_state.init_ok then nic.connect(device) end
|
||||
|
||||
println_ts("comms modem reconnected.")
|
||||
println_ts("comms modem reconnected")
|
||||
log.info("comms modem reconnected")
|
||||
|
||||
-- determine if we are still in a degraded state
|
||||
@ -235,22 +235,12 @@ function threads.thread__main(smem, init)
|
||||
end
|
||||
end
|
||||
|
||||
-- if not init'd and no longer degraded, proceed to init
|
||||
if not plc_state.init_ok and not plc_state.degraded then
|
||||
plc_state.init_ok = true
|
||||
init()
|
||||
end
|
||||
|
||||
-- update indicators
|
||||
databus.tx_hw_status(plc_state)
|
||||
elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" or
|
||||
event == "double_click" then
|
||||
-- handle a mouse event
|
||||
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||
elseif event == "clock_start" then
|
||||
-- start loop clock
|
||||
loop_clock.start()
|
||||
log.debug("main thread clock started")
|
||||
end
|
||||
|
||||
-- check for termination request
|
||||
@ -280,7 +270,6 @@ function threads.thread__main(smem, init)
|
||||
-- this thread cannot be slept because it will miss events (namely "terminate" otherwise)
|
||||
if not plc_state.shutdown then
|
||||
log.info("main thread restarting now...")
|
||||
util.push_event("clock_start")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -399,15 +388,15 @@ function threads.thread__rps(smem)
|
||||
if plc_state.shutdown then
|
||||
-- safe exit
|
||||
log.info("rps thread shutdown initiated")
|
||||
if plc_state.init_ok then
|
||||
if rps.scram() then
|
||||
println_ts("reactor disabled")
|
||||
log.info("rps thread reactor SCRAM OK")
|
||||
else
|
||||
println_ts("exiting, reactor failed to disable")
|
||||
log.error("rps thread failed to SCRAM reactor on exit")
|
||||
end
|
||||
|
||||
if rps.scram() then
|
||||
println_ts("exiting, reactor disabled")
|
||||
log.info("rps thread reactor SCRAM OK")
|
||||
else
|
||||
println_ts("exiting, reactor failed to disable")
|
||||
log.error("rps thread failed to SCRAM reactor on exit")
|
||||
end
|
||||
|
||||
log.info("rps thread exiting")
|
||||
break
|
||||
end
|
||||
@ -430,7 +419,7 @@ function threads.thread__rps(smem)
|
||||
databus.tx_rt_status("rps", false)
|
||||
|
||||
if not plc_state.shutdown then
|
||||
if plc_state.init_ok then smem.plc_sys.rps.scram() end
|
||||
smem.plc_sys.rps.scram()
|
||||
log.info("rps thread restarting in 5 seconds...")
|
||||
util.psleep(5)
|
||||
end
|
||||
|
||||
@ -78,7 +78,7 @@ end
|
||||
|
||||
-- NIC: Network Interface Controller<br>
|
||||
-- utilizes HMAC-MD5 for message authentication, if enabled and this is wireless
|
||||
---@param modem Modem modem to use
|
||||
---@param modem Modem|nil modem to use
|
||||
function network.nic(modem)
|
||||
local self = {
|
||||
-- modem interface name
|
||||
@ -86,9 +86,9 @@ function network.nic(modem)
|
||||
-- phy name
|
||||
name = "?",
|
||||
-- used to quickly return out of tx/rx functions if there is nothing to do
|
||||
connected = true,
|
||||
connected = false,
|
||||
-- used to avoid costly MAC calculations if not required
|
||||
use_hash = c_eng.hmac and modem.isWireless(),
|
||||
use_hash = false,
|
||||
-- open channels
|
||||
channels = {}
|
||||
}
|
||||
@ -135,13 +135,13 @@ function network.nic(modem)
|
||||
function public.is_modem(device) return device == modem end
|
||||
|
||||
-- wrap modem functions, then create custom functions
|
||||
public.connect(modem)
|
||||
if modem then public.connect(modem) end
|
||||
|
||||
-- open a channel on the modem<br>
|
||||
-- if disconnected *after* opening, previousy opened channels will be re-opened on reconnection
|
||||
---@param channel integer
|
||||
function public.open(channel)
|
||||
modem.open(channel)
|
||||
if modem then modem.open(channel) end
|
||||
|
||||
local already_open = false
|
||||
for i = 1, #self.channels do
|
||||
@ -159,7 +159,7 @@ function network.nic(modem)
|
||||
-- close a channel on the modem
|
||||
---@param channel integer
|
||||
function public.close(channel)
|
||||
modem.close(channel)
|
||||
if modem then modem.close(channel) end
|
||||
|
||||
for i = 1, #self.channels do
|
||||
if self.channels[i] == channel then
|
||||
@ -171,7 +171,7 @@ function network.nic(modem)
|
||||
|
||||
-- close all channels on the modem
|
||||
function public.closeAll()
|
||||
modem.closeAll()
|
||||
if modem then modem.closeAll() end
|
||||
self.channels = {}
|
||||
end
|
||||
|
||||
@ -193,7 +193,10 @@ function network.nic(modem)
|
||||
-- log.debug("network.modem.transmit: data processing took " .. (util.time_ms() - start) .. "ms")
|
||||
end
|
||||
|
||||
---@diagnostic disable-next-line: need-check-nil
|
||||
modem.transmit(dest_channel, local_channel, tx_packet.raw_sendable())
|
||||
else
|
||||
log.debug("network.transmit tx dropped, link is down")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user