forked from M-Labs/artiq
runtime,coredevice: support session reset for serial
This commit is contained in:
parent
27d94a22de
commit
9b62e7e77b
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue