Report watchdog expiration and RTIO clock failure as exceptions.

Fixes #316.
release-1
whitequark 2016-03-18 22:29:42 +00:00
parent 80b13b1263
commit 501de30626
6 changed files with 44 additions and 20 deletions

View File

@ -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

View File

@ -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."""

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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;
}
}
}
}

View File

@ -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);