cc-mek-scada/reactor-plc/startup.lua

173 lines
4.8 KiB
Lua
Raw Normal View History

--
-- Reactor Programmable Logic Controller
--
local log = require("scada-common.log")
local mqueue = require("scada-common.mqueue")
local ppm = require("scada-common.ppm")
local util = require("scada-common.util")
2022-03-14 18:19:14 +00:00
2022-05-11 15:31:02 +00:00
local config = require("reactor-plc.config")
local plc = require("reactor-plc.plc")
local threads = require("reactor-plc.threads")
2022-05-10 16:01:56 +00:00
local R_PLC_VERSION = "alpha-v0.6.6"
local print = util.print
local println = util.println
local print_ts = util.print_ts
local println_ts = util.println_ts
2022-04-29 17:36:00 +00:00
log.init(config.LOG_PATH, config.LOG_MODE)
log.info("========================================")
log.info("BOOTING reactor-plc.startup " .. R_PLC_VERSION)
log.info("========================================")
println(">> Reactor PLC " .. R_PLC_VERSION .. " <<")
-- mount connected devices
ppm.mount_all()
2022-04-25 15:40:53 +00:00
-- shared memory across threads
2022-05-11 01:49:14 +00:00
---@class plc_shared_memory
2022-04-25 15:40:53 +00:00
local __shared_memory = {
2022-04-27 16:21:10 +00:00
-- networked setting
2022-05-11 01:49:14 +00:00
networked = config.NETWORKED, ---@type boolean
2022-04-25 15:40:53 +00:00
2022-04-27 16:21:10 +00:00
-- PLC system state flags
2022-05-11 01:49:14 +00:00
---@class plc_state
2022-04-25 15:40:53 +00:00
plc_state = {
init_ok = true,
2022-04-27 16:21:10 +00:00
shutdown = false,
2022-04-25 15:40:53 +00:00
degraded = false,
no_reactor = false,
no_modem = false
},
2022-04-30 02:27:54 +00:00
2022-05-11 01:49:14 +00:00
-- control setpoints
---@class setpoints
2022-04-30 02:27:54 +00:00
setpoints = {
2022-05-05 20:00:49 +00:00
burn_rate_en = false,
2022-04-30 02:27:54 +00:00
burn_rate = 0.0
},
2022-05-10 16:01:56 +00:00
2022-04-27 16:21:10 +00:00
-- core PLC devices
plc_dev = {
2022-04-25 15:40:53 +00:00
reactor = ppm.get_fission_reactor(),
modem = ppm.get_wireless_modem()
},
2022-04-27 16:37:28 +00:00
-- system objects
2022-04-27 16:21:10 +00:00
plc_sys = {
2022-05-11 01:49:14 +00:00
rps = nil, ---@type rps
plc_comms = nil, ---@type plc_comms
conn_watchdog = nil ---@type watchdog
2022-04-27 16:21:10 +00:00
},
-- message queues
q = {
2022-05-05 15:55:04 +00:00
mq_rps = mqueue.new(),
mq_comms_tx = mqueue.new(),
mq_comms_rx = mqueue.new()
2022-04-25 15:40:53 +00:00
}
}
2022-04-27 16:21:10 +00:00
local smem_dev = __shared_memory.plc_dev
local smem_sys = __shared_memory.plc_sys
2022-04-25 15:40:53 +00:00
local plc_state = __shared_memory.plc_state
-- we need a reactor and a modem
2022-04-25 15:40:53 +00:00
if smem_dev.reactor == nil then
println("boot> fission reactor not found");
log.warning("no reactor on startup")
2022-04-05 13:41:06 +00:00
plc_state.init_ok = false
plc_state.degraded = true
plc_state.no_reactor = true
end
2022-05-10 16:01:56 +00:00
if __shared_memory.networked and smem_dev.modem == nil then
2022-04-07 15:44:17 +00:00
println("boot> wireless modem not found")
log.warning("no wireless modem on startup")
2022-04-25 15:40:53 +00:00
if smem_dev.reactor ~= nil then
smem_dev.reactor.scram()
2022-04-05 13:41:06 +00:00
end
plc_state.init_ok = false
plc_state.degraded = true
plc_state.no_modem = true
end
2022-05-10 16:01:56 +00:00
-- PLC init
local init = function ()
if plc_state.init_ok then
-- just booting up, no fission allowed (neutrons stay put thanks)
2022-04-25 15:40:53 +00:00
smem_dev.reactor.scram()
2022-05-05 15:55:04 +00:00
-- init reactor protection system
smem_sys.rps = plc.rps_init(smem_dev.reactor)
log.debug("init> rps init")
2022-04-25 15:40:53 +00:00
if __shared_memory.networked then
-- comms watchdog, 3 second timeout
2022-04-25 15:40:53 +00:00
smem_sys.conn_watchdog = util.new_watchdog(3)
log.debug("init> conn watchdog started")
-- start comms
smem_sys.plc_comms = plc.comms(config.REACTOR_ID, smem_dev.modem, config.LISTEN_PORT, config.SERVER_PORT, smem_dev.reactor, smem_sys.rps, smem_sys.conn_watchdog)
log.debug("init> comms init")
else
println("boot> starting in offline mode");
log.debug("init> running without networking")
end
2022-05-10 16:01:56 +00:00
---@diagnostic disable-next-line: undefined-field
2022-04-25 15:40:53 +00:00
os.queueEvent("clock_start")
println("boot> completed");
log.debug("init> boot completed")
else
println("boot> system in degraded state, awaiting devices...")
log.warning("init> booted in a degraded state, awaiting peripheral connections...")
end
end
----------------------------------------
-- start system
----------------------------------------
-- initialize PLC
init()
2022-04-25 15:40:53 +00:00
-- init threads
2022-05-01 17:26:02 +00:00
local main_thread = threads.thread__main(__shared_memory, init)
2022-05-05 15:55:04 +00:00
local rps_thread = threads.thread__rps(__shared_memory)
if __shared_memory.networked then
-- init comms threads
local comms_thread_tx = threads.thread__comms_tx(__shared_memory)
local comms_thread_rx = threads.thread__comms_rx(__shared_memory)
2022-04-30 02:27:54 +00:00
-- setpoint control only needed when networked
local sp_ctrl_thread = threads.thread__setpoint_control(__shared_memory)
-- run threads
2022-05-05 15:55:04 +00:00
parallel.waitForAll(main_thread.exec, rps_thread.exec, comms_thread_tx.exec, comms_thread_rx.exec, sp_ctrl_thread.exec)
if plc_state.init_ok then
2022-05-05 15:55:04 +00:00
-- send status one last time after RPS shutdown
smem_sys.plc_comms.send_status(plc_state.degraded)
2022-05-05 15:55:04 +00:00
smem_sys.plc_comms.send_rps_status()
-- close connection
2022-05-10 16:01:56 +00:00
smem_sys.plc_comms.close()
end
else
-- run threads, excluding comms
2022-05-05 15:55:04 +00:00
parallel.waitForAll(main_thread.exec, rps_thread.exec)
end
println_ts("exited")
log.info("exited")