From 501de306269eab0c386580827def702d3d9a46e9 Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 18 Mar 2016 22:29:42 +0000 Subject: [PATCH] Report watchdog expiration and RTIO clock failure as exceptions. Fixes #316. --- artiq/coredevice/comm_generic.py | 7 ++++++ artiq/coredevice/exceptions.py | 6 +++++ artiq/runtime/net_server.c | 8 ++++--- artiq/runtime/net_server.h | 2 +- artiq/runtime/session.c | 39 ++++++++++++++++++++------------ artiq/runtime/session.h | 2 +- 6 files changed, 44 insertions(+), 20 deletions(-) diff --git a/artiq/coredevice/comm_generic.py b/artiq/coredevice/comm_generic.py index f4e1d2eee..31f3ccccb 100644 --- a/artiq/coredevice/comm_generic.py +++ b/artiq/coredevice/comm_generic.py @@ -50,6 +50,9 @@ class _D2HMsgType(Enum): FLASH_OK_REPLY = 12 FLASH_ERROR_REPLY = 13 + WATCHDOG_EXPIRED = 14 + CLOCK_FAILURE = 15 + class UnsupportedDevice(Exception): pass @@ -522,6 +525,10 @@ class CommGeneric: self._serve_rpc(object_map) elif self._read_type == _D2HMsgType.KERNEL_EXCEPTION: self._serve_exception(object_map, symbolizer) + elif self._read_type == _D2HMsgType.WATCHDOG_EXPIRED: + raise exceptions.WatchdogExpired + elif self._read_type == _D2HMsgType.CLOCK_FAILURE: + raise exceptions.ClockFailure else: self._read_expect(_D2HMsgType.KERNEL_FINISHED) return diff --git a/artiq/coredevice/exceptions.py b/artiq/coredevice/exceptions.py index 6317edfe6..5c43bbd6d 100644 --- a/artiq/coredevice/exceptions.py +++ b/artiq/coredevice/exceptions.py @@ -129,3 +129,9 @@ class DDSBatchError(Exception): class I2CError(Exception): """Raised with a I2C transaction fails.""" artiq_builtin = True + +class WatchdogExpired(Exception): + """Raised when a watchdog expires.""" + +class ClockFailure(Exception): + """Raised when RTIO PLL is unable to lock.""" diff --git a/artiq/runtime/net_server.c b/artiq/runtime/net_server.c index dc27f7e4b..88e69f0a1 100644 --- a/artiq/runtime/net_server.c +++ b/artiq/runtime/net_server.c @@ -158,9 +158,9 @@ static void tcp_pcb_service(void *arg, struct tcp_pcb *pcb) /* Writer interface */ if(cs == instance->open_session_cs) { void *data; - int len, sndbuf; + int len, sndbuf, close_flag; - cs->instance->poll(&data, &len); + cs->instance->poll(&data, &len, &close_flag); if(len > 0) { sndbuf = tcp_sndbuf(pcb); if(len > sndbuf) @@ -168,8 +168,10 @@ static void tcp_pcb_service(void *arg, struct tcp_pcb *pcb) tcp_write(pcb, data, len, 0); instance->ack_consumed(len); } - if(len < 0) + if(close_flag) { + tcp_output(pcb); net_server_close(cs, pcb); + } } } diff --git a/artiq/runtime/net_server.h b/artiq/runtime/net_server.h index d3f6a8726..9bb57d6c6 100644 --- a/artiq/runtime/net_server.h +++ b/artiq/runtime/net_server.h @@ -10,7 +10,7 @@ struct net_server_instance { void (*start)(void); void (*end)(void); int (*input)(void *data, int length); - void (*poll)(void **data, int *length); + void (*poll)(void **data, int *length, int *close_flag); void (*ack_consumed)(int length); void (*ack_sent)(int length); diff --git a/artiq/runtime/session.c b/artiq/runtime/session.c index fb6e4dcaf..f2f8a8881 100644 --- a/artiq/runtime/session.c +++ b/artiq/runtime/session.c @@ -392,7 +392,10 @@ enum { REMOTEMSG_TYPE_FLASH_READ_REPLY, REMOTEMSG_TYPE_FLASH_OK_REPLY, - REMOTEMSG_TYPE_FLASH_ERROR_REPLY + REMOTEMSG_TYPE_FLASH_ERROR_REPLY, + + REMOTEMSG_TYPE_WATCHDOG_EXPIRED, + REMOTEMSG_TYPE_CLOCK_FAILURE, }; static int receive_rpc_value(const char **tag, void **slot); @@ -1083,30 +1086,36 @@ int session_input(void *data, int length) /* *length is set to -1 in case of irrecoverable error * (the session must be dropped and session_end called) */ -void session_poll(void **data, int *length) +void session_poll(void **data, int *length, int *close_flag) { + *close_flag = 0; + if(user_kernel_state == USER_KERNEL_RUNNING) { if(watchdog_expired()) { core_log("Watchdog expired\n"); - *length = -1; - return; + + *close_flag = 1; + out_packet_empty(REMOTEMSG_TYPE_WATCHDOG_EXPIRED); } if(!rtiocrg_check()) { core_log("RTIO clock failure\n"); - *length = -1; - return; + + *close_flag = 1; + out_packet_empty(REMOTEMSG_TYPE_CLOCK_FAILURE); } } - /* If the output buffer is available, - * check if the kernel CPU has something to transmit. - */ - if(out_packet_available()) { - struct msg_base *umsg = mailbox_receive(); - if(umsg) { - if(!process_kmsg(umsg)) { - *length = -1; - return; + if(!*close_flag) { + /* If the output buffer is available, + * check if the kernel CPU has something to transmit. + */ + if(out_packet_available()) { + struct msg_base *umsg = mailbox_receive(); + if(umsg) { + if(!process_kmsg(umsg)) { + *length = -1; + return; + } } } } diff --git a/artiq/runtime/session.h b/artiq/runtime/session.h index 4184b1758..06ee421ed 100644 --- a/artiq/runtime/session.h +++ b/artiq/runtime/session.h @@ -6,7 +6,7 @@ void session_start(void); void session_end(void); int session_input(void *data, int length); -void session_poll(void **data, int *length); +void session_poll(void **data, int *length, int *close_flag); void session_ack_consumed(int length); void session_ack_sent(int length);