diff --git a/artiq/coredevice/comm_dummy.py b/artiq/coredevice/comm_dummy.py index 0d85ba7d8..5c20d7dc2 100644 --- a/artiq/coredevice/comm_dummy.py +++ b/artiq/coredevice/comm_dummy.py @@ -17,7 +17,7 @@ class Comm: def serve(self, embedding_map, symbolizer, demangler): pass - def check_ident(self): + def check_system_info(self): pass def get_log(self): diff --git a/artiq/coredevice/comm_generic.py b/artiq/coredevice/comm_generic.py index b44e1fee2..f0d7c1d37 100644 --- a/artiq/coredevice/comm_generic.py +++ b/artiq/coredevice/comm_generic.py @@ -17,7 +17,7 @@ class _H2DMsgType(Enum): LOG_REQUEST = 1 LOG_CLEAR = 2 - IDENT_REQUEST = 3 + SYSTEM_INFO_REQUEST = 3 SWITCH_CLOCK = 4 LOAD_KERNEL = 5 @@ -35,7 +35,7 @@ class _H2DMsgType(Enum): class _D2HMsgType(Enum): LOG_REPLY = 1 - IDENT_REPLY = 2 + SYSTEM_INFO_REPLY = 2 CLOCK_SWITCH_COMPLETED = 3 CLOCK_SWITCH_FAILED = 4 @@ -200,11 +200,11 @@ class CommGeneric: def reset_session(self): self.write(struct.pack(">ll", 0x5a5a5a5a, 0)) - def check_ident(self): - self._write_empty(_H2DMsgType.IDENT_REQUEST) + def check_system_info(self): + self._write_empty(_H2DMsgType.SYSTEM_INFO_REQUEST) self._read_header() - self._read_expect(_D2HMsgType.IDENT_REPLY) + self._read_expect(_D2HMsgType.SYSTEM_INFO_REPLY) runtime_id = self._read_chunk(4) if runtime_id != b"AROR": raise UnsupportedDevice("Unsupported runtime ID: {}" @@ -215,6 +215,9 @@ class CommGeneric: logger.warning("Mismatch between gateware (%s) " "and software (%s) versions", gateware_version, software_version) + finished_cleanly = self._read_bool() + if not finished_cleanly: + logger.warning("Interrupted a running kernel") def switch_clock(self, external): self._write_header(_H2DMsgType.SWITCH_CLOCK) diff --git a/artiq/coredevice/core.py b/artiq/coredevice/core.py index fceb576bc..ef6e3f9c6 100644 --- a/artiq/coredevice/core.py +++ b/artiq/coredevice/core.py @@ -115,7 +115,7 @@ class Core: self.compile(function, args, kwargs, set_result) if self.first_run: - self.comm.check_ident() + self.comm.check_system_info() self.comm.switch_clock(self.external_clock) self.first_run = False diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index 1399b8e4d..7128ffe77 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -1,6 +1,6 @@ use std::prelude::v1::*; use std::{mem, str}; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::io::{self, Read, Write}; use std::error::Error; use std::btree_set::BTreeSet; @@ -34,14 +34,16 @@ fn io_error(msg: &str) -> io::Error { #[derive(Debug)] struct Congress { now: u64, - cache: Cache + cache: Cache, + finished_cleanly: Cell } impl Congress { fn new() -> Congress { Congress { now: 0, - cache: Cache::new() + cache: Cache::new(), + finished_cleanly: Cell::new(true) } } } @@ -204,8 +206,14 @@ fn process_host_message(io: &Io, stream: &mut TcpStream, session: &mut Session) -> io::Result<()> { match host_read(stream)? { - host::Request::Ident => - host_write(stream, host::Reply::Ident(board::ident(&mut [0; 64]))), + host::Request::SystemInfo => { + host_write(stream, host::Reply::SystemInfo { + ident: board::ident(&mut [0; 64]), + finished_cleanly: session.congress.finished_cleanly.get() + })?; + session.congress.finished_cleanly.set(true); + Ok(()) + } // artiq_corelog host::Request::Log => { @@ -628,7 +636,6 @@ fn respawn(io: &Io, handle: &mut Option, f: F) None => (), Some(handle) => { if !handle.terminated() { - info!("terminating running kernel"); handle.interrupt(); io.join(handle).expect("cannot join interrupt thread") } @@ -659,6 +666,7 @@ pub fn thread(io: Io) { if err.kind() == io::ErrorKind::NotFound { info!("no startup kernel found") } else { + congress.finished_cleanly.set(false); error!("startup kernel aborted: {}", err); } } @@ -690,6 +698,7 @@ pub fn thread(io: Io) { if err.kind() == io::ErrorKind::UnexpectedEof { info!("connection closed"); } else { + congress.finished_cleanly.set(false); error!("session aborted: {}", err); } } diff --git a/artiq/firmware/runtime/session_proto.rs b/artiq/firmware/runtime/session_proto.rs index fb02281bf..c30bf7eed 100644 --- a/artiq/firmware/runtime/session_proto.rs +++ b/artiq/firmware/runtime/session_proto.rs @@ -20,7 +20,7 @@ pub enum Request { Log, LogClear, - Ident, + SystemInfo, SwitchClock(u8), LoadKernel(Vec), @@ -49,7 +49,7 @@ impl Request { Ok(match read_u8(reader)? { 1 => Request::Log, 2 => Request::LogClear, - 3 => Request::Ident, + 3 => Request::SystemInfo, 4 => Request::SwitchClock(read_u8(reader)?), 5 => Request::LoadKernel(read_bytes(reader)?), 6 => Request::RunKernel, @@ -87,7 +87,10 @@ impl Request { pub enum Reply<'a> { Log(&'a str), - Ident(&'a str), + SystemInfo { + ident: &'a str, + finished_cleanly: bool + }, ClockSwitchCompleted, ClockSwitchFailed, @@ -126,10 +129,11 @@ impl<'a> Reply<'a> { write_string(writer, log)?; }, - Reply::Ident(ident) => { + Reply::SystemInfo { ident, finished_cleanly } => { write_u8(writer, 2)?; writer.write(b"AROR")?; write_string(writer, ident)?; + write_u8(writer, finished_cleanly as u8)?; }, Reply::ClockSwitchCompleted => { write_u8(writer, 3)?; diff --git a/artiq/frontend/artiq_coreconfig.py b/artiq/frontend/artiq_coreconfig.py index cf5ff8b19..cc8aa44be 100755 --- a/artiq/frontend/artiq_coreconfig.py +++ b/artiq/frontend/artiq_coreconfig.py @@ -53,7 +53,7 @@ def main(): device_mgr = DeviceManager(DeviceDB(args.device_db)) try: comm = device_mgr.get("comm") - comm.check_ident() + comm.check_system_info() if args.action == "read": value = comm.flash_storage_read(args.key) diff --git a/artiq/frontend/artiq_corelog.py b/artiq/frontend/artiq_corelog.py index 046d6cece..4842b7d6b 100755 --- a/artiq/frontend/artiq_corelog.py +++ b/artiq/frontend/artiq_corelog.py @@ -22,7 +22,7 @@ def main(): device_mgr = DeviceManager(DeviceDB(args.device_db)) try: comm = device_mgr.get("comm") - comm.check_ident() + comm.check_system_info() print(comm.get_log(), end="") finally: device_mgr.close_devices()