forked from M-Labs/artiq
1
0
Fork 0

runtime,coredevice: support session reset for serial

This commit is contained in:
Sebastien Bourdeauducq 2015-04-28 02:11:58 +08:00
parent 27d94a22de
commit 9b62e7e77b
3 changed files with 37 additions and 22 deletions

View File

@ -76,7 +76,10 @@ class CommGeneric:
sync_count += 1 sync_count += 1
else: else:
sync_count = 0 sync_count = 0
length, tyv = struct.unpack(">lB", self.read(5)) length = struct.unpack(">l", self.read(4))[0]
if not length: # inband connection close
raise OSError("Connection closed")
tyv = struct.unpack("B", self.read(1))[0]
ty = _D2HMsgType(tyv) ty = _D2HMsgType(tyv)
logger.debug("receiving message: type=%r length=%d", ty, length) logger.debug("receiving message: type=%r length=%d", ty, length)
return length, ty return length, ty

View File

@ -269,6 +269,8 @@ static void kserver_service(void)
tcp_write(active_pcb, data, len, 0); tcp_write(active_pcb, data, len, 0);
session_ack_data(len); session_ack_data(len);
} }
if(len < 0)
kserver_close(active_cs, active_pcb);
} }
} }
@ -285,6 +287,19 @@ static void regular_main(void)
#else /* CSR_ETHMAC_BASE */ #else /* CSR_ETHMAC_BASE */
static void reset_serial_session(void)
{
int i;
session_end();
/* Signal end-of-session inband with zero length packet. */
for(i=0;i<4;i++)
uart_write(0x5a);
for(i=0;i<4;i++)
uart_write(0x00);
session_start();
}
static void serial_service(void) static void serial_service(void)
{ {
char *txdata; char *txdata;
@ -301,10 +316,8 @@ static void serial_service(void)
r = session_input(&rxdata, 1); r = session_input(&rxdata, 1);
if(r > 0) if(r > 0)
rxpending = 0; rxpending = 0;
if(r < 0) { if(r < 0)
session_end(); reset_serial_session();
session_start();
}
} }
session_poll((void **)&txdata, &txlen); session_poll((void **)&txdata, &txlen);
@ -313,7 +326,8 @@ static void serial_service(void)
uart_write(txdata[i]); uart_write(txdata[i]);
session_ack_data(txlen); session_ack_data(txlen);
session_ack_mem(txlen); session_ack_mem(txlen);
} } else if(txlen < 0)
reset_serial_session();
} }
static void regular_main(void) static void regular_main(void)

View File

@ -362,11 +362,11 @@ int session_input(void *data, int len)
} }
/* assumes output buffer is empty when called */ /* assumes output buffer is empty when called */
static void process_kmsg(struct msg_base *umsg) static int process_kmsg(struct msg_base *umsg)
{ {
if(user_kernel_state != USER_KERNEL_RUNNING) { if(user_kernel_state != USER_KERNEL_RUNNING) {
log("Received message from kernel CPU while not in running state"); log("Received message from kernel CPU while not in running state");
return; return 0;
} }
switch(umsg->type) { switch(umsg->type) {
@ -392,7 +392,8 @@ static void process_kmsg(struct msg_base *umsg)
case MESSAGE_TYPE_RPC_REQUEST: { case MESSAGE_TYPE_RPC_REQUEST: {
struct msg_rpc_request *msg = (struct msg_rpc_request *)umsg; struct msg_rpc_request *msg = (struct msg_rpc_request *)umsg;
send_rpc_request(msg->rpc_num, msg->args); if(!send_rpc_request(msg->rpc_num, msg->args))
return 0;
user_kernel_state = USER_KERNEL_WAIT_RPC; user_kernel_state = USER_KERNEL_WAIT_RPC;
break; break;
} }
@ -403,23 +404,16 @@ static void process_kmsg(struct msg_base *umsg)
break; break;
} }
default: { default: {
int eid;
log("Received invalid message type from kernel CPU"); log("Received invalid message type from kernel CPU");
return 0;
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_EXCEPTION;
eid = EID_INTERNAL_ERROR;
memcpy(&buffer_out[9], &eid, 4);
memset(&buffer_out[13], 0, 3*8);
submit_output(9+4+3*8);
kloader_stop_kernel();
user_kernel_state = USER_KERNEL_LOADED;
break;
} }
} }
return 1;
} }
/* len is set to -1 in case of irrecoverable error
* (the session must be dropped and session_end called)
*/
void session_poll(void **data, int *len) void session_poll(void **data, int *len)
{ {
int l; int l;
@ -434,7 +428,10 @@ void session_poll(void **data, int *len)
umsg = mailbox_receive(); umsg = mailbox_receive();
if(umsg) { if(umsg) {
process_kmsg(umsg); if(!process_kmsg(umsg)) {
*len = -1;
return;
}
mailbox_acknowledge(); mailbox_acknowledge();
} }
l = get_out_packet_len(); l = get_out_packet_len();
@ -454,6 +451,7 @@ void session_ack_mem(int len)
buffer_out_index_mem += len; buffer_out_index_mem += len;
if(buffer_out_index_mem >= get_out_packet_len()) { if(buffer_out_index_mem >= get_out_packet_len()) {
memset(&buffer_out[4], 0, 4); memset(&buffer_out[4], 0, 4);
buffer_out_index_data = 0;
buffer_out_index_mem = 0; buffer_out_index_mem = 0;
} }
} }