#634 coordinator backplane interface
This commit is contained in:
@@ -12,6 +12,7 @@ local network = require("scada-common.network")
|
||||
local ppm = require("scada-common.ppm")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local backplane = require("coordinator.backplane")
|
||||
local configure = require("coordinator.configure")
|
||||
local coordinator = require("coordinator.coordinator")
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
@@ -36,45 +37,13 @@ local log_crypto = coordinator.log_crypto
|
||||
-- get configuration
|
||||
----------------------------------------
|
||||
|
||||
-- mount connected devices (required for monitor setup)
|
||||
ppm.mount_all()
|
||||
|
||||
local wait_on_load = true
|
||||
local loaded, monitors = coordinator.load_config()
|
||||
|
||||
-- if the computer just started, its chunk may have just loaded (...or the user rebooted)
|
||||
-- if monitor config failed, maybe an adjacent chunk containing all or part of a monitor has not loaded yet, so keep trying
|
||||
while wait_on_load and loaded == 2 and os.clock() < CHUNK_LOAD_DELAY_S do
|
||||
term.clear()
|
||||
term.setCursorPos(1, 1)
|
||||
println("There was a monitor configuration problem at boot.\n")
|
||||
println("Startup will keep trying every 2s in case of chunk load delays.\n")
|
||||
println(util.sprintf("The configurator will be started in %ds if all attempts fail.\n", math.max(0, CHUNK_LOAD_DELAY_S - os.clock())))
|
||||
println("(click to skip to the configurator)")
|
||||
|
||||
local timer_id = util.start_timer(2)
|
||||
|
||||
while true do
|
||||
local event, param1 = util.pull_event()
|
||||
if event == "timer" and param1 == timer_id then
|
||||
-- remount and re-attempt
|
||||
ppm.mount_all()
|
||||
loaded, monitors = coordinator.load_config()
|
||||
break
|
||||
elseif event == "mouse_click" or event == "terminate" then
|
||||
wait_on_load = false
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if loaded ~= 0 then
|
||||
-- first pass configuration check before validating monitors
|
||||
if not coordinator.load_config() then
|
||||
-- try to reconfigure (user action)
|
||||
local success, error = configure.configure(loaded, monitors)
|
||||
local success, error = configure.configure(1)
|
||||
if success then
|
||||
loaded, monitors = coordinator.load_config()
|
||||
if loaded ~= 0 then
|
||||
println(util.trinary(loaded == 2, "monitor configuration invalid", "failed to load a valid configuration") .. ", please reconfigure")
|
||||
if not coordinator.load_config() then
|
||||
println("failed to load a valid configuration, please reconfigure")
|
||||
return
|
||||
end
|
||||
else
|
||||
@@ -83,9 +52,6 @@ if loaded ~= 0 then
|
||||
end
|
||||
end
|
||||
|
||||
-- passed checks, good now
|
||||
---@cast monitors monitors_struct
|
||||
|
||||
local config = coordinator.config
|
||||
|
||||
----------------------------------------
|
||||
@@ -102,6 +68,64 @@ println(">> SCADA Coordinator " .. COORDINATOR_VERSION .. " <<")
|
||||
crash.set_env("coordinator", COORDINATOR_VERSION)
|
||||
crash.dbg_log_env()
|
||||
|
||||
----------------------------------------
|
||||
-- display init
|
||||
----------------------------------------
|
||||
|
||||
-- mount connected devices (required for monitor setup)
|
||||
ppm.mount_all()
|
||||
|
||||
local wait_on_load = true
|
||||
|
||||
local disp_ok, disp_err = backplane.init_displays(config)
|
||||
|
||||
-- if the computer just started, its chunk may have just loaded (...or the user rebooted)
|
||||
-- if monitor config failed, maybe an adjacent chunk containing all or part of a monitor has not loaded yet, so keep trying
|
||||
while wait_on_load and (not disp_ok) and os.clock() < CHUNK_LOAD_DELAY_S do
|
||||
term.clear()
|
||||
term.setCursorPos(1, 1)
|
||||
println("There was a monitor configuration problem at boot.\n")
|
||||
println("Startup will keep trying every 2s in case of chunk load delays.\n")
|
||||
println(util.sprintf("The configurator will be started in %ds if all attempts fail.\n", math.max(0, CHUNK_LOAD_DELAY_S - os.clock())))
|
||||
println("(click to skip to the configurator)")
|
||||
|
||||
local timer_id = util.start_timer(2)
|
||||
|
||||
while true do
|
||||
local event, param1 = util.pull_event()
|
||||
if event == "timer" and param1 == timer_id then
|
||||
-- remount and re-attempt
|
||||
ppm.mount_all()
|
||||
disp_ok, disp_err = backplane.init_displays(config)
|
||||
break
|
||||
elseif event == "mouse_click" or event == "terminate" then
|
||||
wait_on_load = false
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not disp_ok then
|
||||
-- try to reconfigure (user action)
|
||||
local success, error = configure.configure(2, disp_err)
|
||||
if success then
|
||||
if not coordinator.load_config() then
|
||||
println("failed to load a valid configuration, please reconfigure")
|
||||
return
|
||||
else
|
||||
disp_ok, disp_err = backplane.init_displays(config)
|
||||
|
||||
if not disp_ok then
|
||||
println("monitor configuration invalid, please reconfigure")
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
println("configuration error: " .. error)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------
|
||||
-- main application
|
||||
----------------------------------------
|
||||
@@ -111,15 +135,12 @@ local function main()
|
||||
-- system startup
|
||||
----------------------------------------
|
||||
|
||||
-- log mounts now since mounting was done before logging was ready
|
||||
ppm.log_mounts()
|
||||
|
||||
-- report versions/init fp PSIL
|
||||
iocontrol.init_fp(COORDINATOR_VERSION, comms.version)
|
||||
|
||||
-- init renderer
|
||||
renderer.configure(config)
|
||||
renderer.set_displays(monitors)
|
||||
renderer.set_displays(backplane.displays())
|
||||
renderer.init_displays()
|
||||
renderer.init_dmesg()
|
||||
|
||||
@@ -130,6 +151,12 @@ local function main()
|
||||
log_sys("system start on " .. os.date("%c"))
|
||||
log_boot("starting " .. COORDINATOR_VERSION)
|
||||
|
||||
-- message authentication init
|
||||
if type(config.AuthKey) == "string" and string.len(config.AuthKey) > 0 then
|
||||
local init_time = network.init_mac(config.AuthKey)
|
||||
log_crypto("HMAC init took " .. init_time .. "ms")
|
||||
end
|
||||
|
||||
----------------------------------------
|
||||
-- memory allocation
|
||||
----------------------------------------
|
||||
@@ -149,15 +176,9 @@ local function main()
|
||||
shutdown = false
|
||||
},
|
||||
|
||||
-- core coordinator devices
|
||||
crd_dev = {
|
||||
modem = ppm.get_wireless_modem(),
|
||||
speaker = ppm.get_device("speaker") ---@type Speaker|nil
|
||||
},
|
||||
|
||||
-- system objects
|
||||
---@class crd_sys
|
||||
crd_sys = {
|
||||
nic = nil, ---@type nic
|
||||
coord_comms = nil, ---@type coord_comms
|
||||
conn_watchdog = nil ---@type watchdog
|
||||
},
|
||||
@@ -168,65 +189,17 @@ local function main()
|
||||
}
|
||||
}
|
||||
|
||||
local smem_dev = __shared_memory.crd_dev
|
||||
local smem_sys = __shared_memory.crd_sys
|
||||
|
||||
local smem_sys = __shared_memory.crd_sys
|
||||
local crd_state = __shared_memory.crd_state
|
||||
|
||||
----------------------------------------
|
||||
-- setup alarm sounder subsystem
|
||||
-- init system
|
||||
----------------------------------------
|
||||
|
||||
if smem_dev.speaker == nil then
|
||||
log_boot("annunciator alarm speaker not found")
|
||||
println("startup> speaker not found")
|
||||
log.fatal("no annunciator alarm speaker found")
|
||||
return
|
||||
else
|
||||
local sounder_start = util.time_ms()
|
||||
log_boot("annunciator alarm speaker connected")
|
||||
sounder.init(smem_dev.speaker, config.SpeakerVolume)
|
||||
log_boot("tone generation took " .. (util.time_ms() - sounder_start) .. "ms")
|
||||
log_sys("annunciator alarm configured")
|
||||
iocontrol.fp_has_speaker(true)
|
||||
end
|
||||
-- modem and speaker initialization
|
||||
if not backplane.init(config, __shared_memory) then return end
|
||||
|
||||
----------------------------------------
|
||||
-- setup communications
|
||||
----------------------------------------
|
||||
|
||||
-- message authentication init
|
||||
if type(config.AuthKey) == "string" and string.len(config.AuthKey) > 0 then
|
||||
local init_time = network.init_mac(config.AuthKey)
|
||||
log_crypto("HMAC init took " .. init_time .. "ms")
|
||||
end
|
||||
|
||||
-- get the communications modem
|
||||
if smem_dev.modem == nil then
|
||||
log_comms("wireless modem not found")
|
||||
println("startup> wireless modem not found")
|
||||
log.fatal("no wireless modem on startup")
|
||||
return
|
||||
else
|
||||
log_comms("wireless modem connected")
|
||||
iocontrol.fp_has_modem(true)
|
||||
end
|
||||
|
||||
-- create connection watchdog
|
||||
smem_sys.conn_watchdog = util.new_watchdog(config.SVR_Timeout)
|
||||
smem_sys.conn_watchdog.cancel()
|
||||
log.debug("startup> conn watchdog created")
|
||||
|
||||
-- create network interface then setup comms
|
||||
smem_sys.nic = network.nic(smem_dev.modem)
|
||||
smem_sys.coord_comms = coordinator.comms(COORDINATOR_VERSION, smem_sys.nic, smem_sys.conn_watchdog)
|
||||
log.debug("startup> comms init")
|
||||
log_comms("comms initialized")
|
||||
|
||||
----------------------------------------
|
||||
-- start front panel
|
||||
----------------------------------------
|
||||
|
||||
log_render("starting front panel UI...")
|
||||
|
||||
local fp_message
|
||||
@@ -238,6 +211,16 @@ local function main()
|
||||
return
|
||||
else log_render("front panel ready") end
|
||||
|
||||
-- create connection watchdog
|
||||
smem_sys.conn_watchdog = util.new_watchdog(config.SVR_Timeout)
|
||||
smem_sys.conn_watchdog.cancel()
|
||||
log.debug("startup> conn watchdog created")
|
||||
|
||||
-- setup comms
|
||||
smem_sys.coord_comms = coordinator.comms(COORDINATOR_VERSION, backplane.active_nic(), smem_sys.conn_watchdog)
|
||||
log.debug("startup> comms init")
|
||||
log_comms("comms initialized")
|
||||
|
||||
----------------------------------------
|
||||
-- start system
|
||||
----------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user