forked from M-Labs/artiq
never stop RTIO counter
This commit is contained in:
parent
a5b6792f95
commit
8a33d8c868
|
@ -95,7 +95,12 @@ class CommGeneric:
|
||||||
def _write_header(self, length, ty):
|
def _write_header(self, length, ty):
|
||||||
self.open()
|
self.open()
|
||||||
logger.debug("sending message: type=%r length=%d", ty, length)
|
logger.debug("sending message: type=%r length=%d", ty, length)
|
||||||
self.write(struct.pack(">llB", 0x5a5a5a5a, length, ty.value))
|
self.write(struct.pack(">ll", 0x5a5a5a5a, length))
|
||||||
|
if ty is not None:
|
||||||
|
self.write(struct.pack("B", ty.value))
|
||||||
|
|
||||||
|
def reset_session(self):
|
||||||
|
self._write_header(0, None)
|
||||||
|
|
||||||
def check_ident(self):
|
def check_ident(self):
|
||||||
self._write_header(9, _H2DMsgType.IDENT_REQUEST)
|
self._write_header(9, _H2DMsgType.IDENT_REQUEST)
|
||||||
|
@ -125,9 +130,8 @@ class CommGeneric:
|
||||||
if ty != _D2HMsgType.LOAD_COMPLETED:
|
if ty != _D2HMsgType.LOAD_COMPLETED:
|
||||||
raise IOError("Incorrect reply from device: "+str(ty))
|
raise IOError("Incorrect reply from device: "+str(ty))
|
||||||
|
|
||||||
def run(self, kname, reset_now):
|
def run(self, kname):
|
||||||
self._write_header(len(kname) + 10, _H2DMsgType.RUN_KERNEL)
|
self._write_header(len(kname) + 9, _H2DMsgType.RUN_KERNEL)
|
||||||
self.write(struct.pack("B", reset_now))
|
|
||||||
self.write(bytes(kname, "ascii"))
|
self.write(bytes(kname, "ascii"))
|
||||||
logger.debug("running kernel: %s", kname)
|
logger.debug("running kernel: %s", kname)
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ class Comm(CommGeneric, AutoDB):
|
||||||
return
|
return
|
||||||
self.port = serial.serial_for_url(self.serial_dev,
|
self.port = serial.serial_for_url(self.serial_dev,
|
||||||
baudrate=self.baud_rate)
|
baudrate=self.baud_rate)
|
||||||
|
self.reset_session()
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if not hasattr(self, "port"):
|
if not hasattr(self, "port"):
|
||||||
|
|
|
@ -116,7 +116,7 @@ class Core(AutoDB):
|
||||||
binary, rpc_map, exception_map = self.compile(
|
binary, rpc_map, exception_map = self.compile(
|
||||||
k_function, k_args, k_kwargs)
|
k_function, k_args, k_kwargs)
|
||||||
self.comm.load(binary)
|
self.comm.load(binary)
|
||||||
self.comm.run(k_function.__name__, self.first_run)
|
self.comm.run(k_function.__name__)
|
||||||
self.comm.serve(rpc_map, exception_map)
|
self.comm.serve(rpc_map, exception_map)
|
||||||
self.first_run = False
|
self.first_run = False
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,8 @@ class _RTIOCounter(Module):
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
self.sync.rio += self.value_rio.eq(self.value_rio + 1),
|
# note: counter is in rtio domain and never affected by the reset CSRs
|
||||||
|
self.sync.rtio += self.value_rio.eq(self.value_rio + 1)
|
||||||
gt = _GrayCodeTransfer(width)
|
gt = _GrayCodeTransfer(width)
|
||||||
self.submodules += gt
|
self.submodules += gt
|
||||||
self.comb += gt.i.eq(self.value_rio), self.value_sys.eq(gt.o)
|
self.comb += gt.i.eq(self.value_rio), self.value_sys.eq(gt.o)
|
||||||
|
|
|
@ -147,6 +147,33 @@ class SequenceError(Experiment, AutoDB):
|
||||||
self.ttl_out.pulse(25*us)
|
self.ttl_out.pulse(25*us)
|
||||||
|
|
||||||
|
|
||||||
|
class TimeKeepsRunning(Experiment, AutoDB):
|
||||||
|
class DBKeys:
|
||||||
|
core = Device()
|
||||||
|
time_at_start = Result()
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def run(self):
|
||||||
|
self.time_at_start = now_mu()
|
||||||
|
|
||||||
|
|
||||||
|
class Handover(Experiment, AutoDB):
|
||||||
|
class DBKeys:
|
||||||
|
core = Device()
|
||||||
|
t1 = Result()
|
||||||
|
t2 = Result()
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def get_now(self):
|
||||||
|
self.time_at_start = now_mu()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.get_now()
|
||||||
|
self.t1 = self.time_at_start
|
||||||
|
self.get_now()
|
||||||
|
self.t2 = self.time_at_start
|
||||||
|
|
||||||
|
|
||||||
class CoredeviceTest(ExperimentCase):
|
class CoredeviceTest(ExperimentCase):
|
||||||
def test_rtt(self):
|
def test_rtt(self):
|
||||||
self.execute(RTT)
|
self.execute(RTT)
|
||||||
|
@ -192,6 +219,21 @@ class CoredeviceTest(ExperimentCase):
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
self.execute(Watchdog)
|
self.execute(Watchdog)
|
||||||
|
|
||||||
|
def test_time_keeps_running(self):
|
||||||
|
self.execute(TimeKeepsRunning)
|
||||||
|
t1 = self.dbh.get_result("time_at_start").read
|
||||||
|
self.dbh.close_devices() # a fortiori the core device connection
|
||||||
|
self.execute(TimeKeepsRunning)
|
||||||
|
t2 = self.dbh.get_result("time_at_start").read
|
||||||
|
self.assertGreater(mu_to_seconds(t2 - t1,
|
||||||
|
self.dbh.get_device("core")),
|
||||||
|
1*ms)
|
||||||
|
|
||||||
|
def test_handover(self):
|
||||||
|
self.execute(Handover)
|
||||||
|
self.assertEqual(self.dbh.get_result("t1").read,
|
||||||
|
self.dbh.get_result("t2").read)
|
||||||
|
|
||||||
|
|
||||||
class RPCTiming(Experiment, AutoDB):
|
class RPCTiming(Experiment, AutoDB):
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
|
|
|
@ -79,7 +79,7 @@ long long int now_init(void)
|
||||||
|
|
||||||
if(now < 0) {
|
if(now < 0) {
|
||||||
rtio_init();
|
rtio_init();
|
||||||
now = 125000;
|
now = rtio_get_counter() + 125000;
|
||||||
}
|
}
|
||||||
|
|
||||||
return now;
|
return now;
|
||||||
|
|
|
@ -151,16 +151,18 @@ static void regular_main(void)
|
||||||
|
|
||||||
#else /* CSR_ETHMAC_BASE */
|
#else /* CSR_ETHMAC_BASE */
|
||||||
|
|
||||||
static void reset_serial_session(void)
|
static void reset_serial_session(int signal)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
session_end();
|
session_end();
|
||||||
|
if(signal) {
|
||||||
/* Signal end-of-session inband with zero length packet. */
|
/* Signal end-of-session inband with zero length packet. */
|
||||||
for(i=0;i<4;i++)
|
for(i=0;i<4;i++)
|
||||||
uart_write(0x5a);
|
uart_write(0x5a);
|
||||||
for(i=0;i<4;i++)
|
for(i=0;i<4;i++)
|
||||||
uart_write(0x00);
|
uart_write(0x00);
|
||||||
|
}
|
||||||
session_start();
|
session_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +183,8 @@ static void serial_service(void)
|
||||||
if(r > 0)
|
if(r > 0)
|
||||||
rxpending = 0;
|
rxpending = 0;
|
||||||
if(r < 0)
|
if(r < 0)
|
||||||
reset_serial_session();
|
/* do not signal if reset was requested by host */
|
||||||
|
reset_serial_session(r != -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
session_poll((void **)&txdata, &txlen);
|
session_poll((void **)&txdata, &txlen);
|
||||||
|
@ -191,7 +194,7 @@ static void serial_service(void)
|
||||||
session_ack_data(txlen);
|
session_ack_data(txlen);
|
||||||
session_ack_mem(txlen);
|
session_ack_mem(txlen);
|
||||||
} else if(txlen < 0)
|
} else if(txlen < 0)
|
||||||
reset_serial_session();
|
reset_serial_session(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void regular_main(void)
|
static void regular_main(void)
|
||||||
|
|
|
@ -14,4 +14,3 @@ long long int rtio_get_counter(void)
|
||||||
rtio_counter_update_write(1);
|
rtio_counter_update_write(1);
|
||||||
return rtio_counter_read();
|
return rtio_counter_read();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,11 +70,13 @@ void session_start(void)
|
||||||
memset(&buffer_out[4], 0, 4);
|
memset(&buffer_out[4], 0, 4);
|
||||||
kloader_stop();
|
kloader_stop();
|
||||||
user_kernel_state = USER_KERNEL_NONE;
|
user_kernel_state = USER_KERNEL_NONE;
|
||||||
|
now = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_end(void)
|
void session_end(void)
|
||||||
{
|
{
|
||||||
kloader_stop();
|
kloader_stop();
|
||||||
|
now = -1;
|
||||||
kloader_start_idle_kernel();
|
kloader_start_idle_kernel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,10 +191,7 @@ static int process_input(void)
|
||||||
}
|
}
|
||||||
buffer_in[buffer_in_index] = 0;
|
buffer_in[buffer_in_index] = 0;
|
||||||
|
|
||||||
if(buffer_in[9])
|
k = kloader_find((char *)&buffer_in[9]);
|
||||||
now = -1;
|
|
||||||
|
|
||||||
k = kloader_find((char *)&buffer_in[10]);
|
|
||||||
if(k == NULL) {
|
if(k == NULL) {
|
||||||
log("Failed to find kernel entry point '%s' in object", &buffer_in[9]);
|
log("Failed to find kernel entry point '%s' in object", &buffer_in[9]);
|
||||||
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED;
|
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED;
|
||||||
|
@ -311,6 +310,9 @@ int session_input(void *data, int len)
|
||||||
/* receiving length */
|
/* receiving length */
|
||||||
buffer_in[buffer_in_index++] = _data[consumed];
|
buffer_in[buffer_in_index++] = _data[consumed];
|
||||||
consumed++; len--;
|
consumed++; len--;
|
||||||
|
if((buffer_in_index == 8) && (get_in_packet_len() == 0))
|
||||||
|
/* zero-length packet = session reset */
|
||||||
|
return -2;
|
||||||
} else {
|
} else {
|
||||||
/* receiving payload */
|
/* receiving payload */
|
||||||
int packet_len;
|
int packet_len;
|
||||||
|
@ -465,12 +467,14 @@ static int send_rpc_request(int rpc_num, va_list args)
|
||||||
/* assumes output buffer is empty when called */
|
/* assumes output buffer is empty when called */
|
||||||
static int process_kmsg(struct msg_base *umsg)
|
static int process_kmsg(struct msg_base *umsg)
|
||||||
{
|
{
|
||||||
if(user_kernel_state != USER_KERNEL_RUNNING) {
|
|
||||||
log("Received message from kernel CPU while not in running state");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(!validate_kpointer(umsg))
|
if(!validate_kpointer(umsg))
|
||||||
return 0;
|
return 0;
|
||||||
|
if((user_kernel_state != USER_KERNEL_RUNNING)
|
||||||
|
&& (umsg->type != MESSAGE_TYPE_NOW_INIT_REQUEST)
|
||||||
|
&& (umsg->type != MESSAGE_TYPE_NOW_SAVE)) {
|
||||||
|
log("Received unexpected message from kernel CPU while not in running state");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch(umsg->type) {
|
switch(umsg->type) {
|
||||||
case MESSAGE_TYPE_NOW_INIT_REQUEST: {
|
case MESSAGE_TYPE_NOW_INIT_REQUEST: {
|
||||||
|
|
Loading…
Reference in New Issue