forked from M-Labs/artiq
inter-experiment smooth handover
This commit is contained in:
parent
ef8f60c78d
commit
c8dc6ca07c
@ -37,6 +37,10 @@ class CompileError(Exception):
|
||||
return "\n" + _render_diagnostic(self.diagnostic, colored=colors_supported)
|
||||
|
||||
|
||||
@syscall
|
||||
def rtio_init():
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
def rtio_get_counter() -> TInt64:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
@ -121,10 +125,21 @@ class Core:
|
||||
def get_rtio_counter_mu(self):
|
||||
return rtio_get_counter()
|
||||
|
||||
@kernel
|
||||
def reset(self):
|
||||
"""Clear RTIO FIFOs, release RTIO PHY reset, and set the time cursor
|
||||
at the current value of the hardware RTIO counter plus a margin of
|
||||
125000 machine units."""
|
||||
rtio_init()
|
||||
at_mu(rtio_get_counter() + 125000)
|
||||
|
||||
@kernel
|
||||
def break_realtime(self):
|
||||
"""Set the timeline to the current value of the hardware RTIO counter
|
||||
plus a margin of 125000 machine units."""
|
||||
"""Set the time cursor after the current value of the hardware RTIO
|
||||
counter plus a margin of 125000 machine units.
|
||||
|
||||
If the time cursor is already after that position, this function
|
||||
does nothing."""
|
||||
min_now = rtio_get_counter() + 125000
|
||||
if now_mu() < min_now:
|
||||
at_mu(min_now)
|
||||
|
21
artiq/examples/master/idle_kernel.py
Normal file
21
artiq/examples/master/idle_kernel.py
Normal file
@ -0,0 +1,21 @@
|
||||
from artiq.experiment import *
|
||||
|
||||
|
||||
class IdleKernel(EnvExperiment):
|
||||
def build(self):
|
||||
self.setattr_device("core")
|
||||
self.setattr_device("led")
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
start_time = now_mu() + seconds_to_mu(500*ms)
|
||||
while self.core.get_rtio_counter_mu() < start_time:
|
||||
pass
|
||||
self.core.reset()
|
||||
while True:
|
||||
self.led.pulse(250*ms)
|
||||
delay(125*ms)
|
||||
self.led.pulse(125*ms)
|
||||
delay(125*ms)
|
||||
self.led.pulse(125*ms)
|
||||
delay(250*ms)
|
@ -38,6 +38,7 @@ class PDQ2Simple(EnvExperiment):
|
||||
return self.pmt.count()
|
||||
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
offsets = np.arange(0, 3)
|
||||
for o in offsets:
|
||||
self.setup(o)
|
||||
|
@ -48,6 +48,7 @@ class PhotonHistogram(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
self.program_cooling()
|
||||
|
||||
hist = [0 for _ in range(self.nbins)]
|
||||
|
@ -9,6 +9,7 @@ class AD5360Test(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
self.dac.setup_bus(write_div=30, read_div=40)
|
||||
self.dac.write_offsets()
|
||||
self.led.on()
|
||||
|
@ -8,6 +8,7 @@ class BlinkForever(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
while True:
|
||||
self.led.pulse(100*ms)
|
||||
delay(100*ms)
|
||||
|
@ -17,6 +17,7 @@ class DDSTest(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
with self.core_dds.batch:
|
||||
self.dds1.set(120*MHz)
|
||||
self.dds2.set(200*MHz)
|
||||
|
@ -12,5 +12,6 @@ class Handover(EnvExperiment):
|
||||
delay(250*ms)
|
||||
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
while True:
|
||||
self.blink_once()
|
||||
|
@ -36,6 +36,7 @@ class TDR(EnvExperiment):
|
||||
self.setattr_device("ttl2")
|
||||
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
n = 1000 # repetitions
|
||||
latency = 50e-9 # calibrated latency without a transmission line
|
||||
pulse = 1e-6 # pulse length, larger than rtt
|
||||
|
@ -91,6 +91,7 @@ class Transport(EnvExperiment):
|
||||
self.repeat()
|
||||
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
# scan transport endpoint
|
||||
stops = np.linspace(0, 10, 10)
|
||||
self.scan(stops)
|
||||
|
@ -149,7 +149,7 @@ int kloader_is_essential_kmsg(int msgtype)
|
||||
}
|
||||
}
|
||||
|
||||
long long int now;
|
||||
static long long int now = 0;
|
||||
|
||||
void kloader_service_essential_kmsg(void)
|
||||
{
|
||||
|
@ -8,8 +8,6 @@
|
||||
#define KERNELCPU_LAST_ADDRESS (0x4fffffff - 1024*1024)
|
||||
#define KSUPPORT_HEADER_SIZE 0x80
|
||||
|
||||
extern long long int now;
|
||||
|
||||
int kloader_load_library(const void *code);
|
||||
void kloader_filter_backtrace(struct artiq_backtrace_item *backtrace,
|
||||
size_t *backtrace_size);
|
||||
|
@ -111,6 +111,7 @@ static const struct symbol runtime_exports[] = {
|
||||
{"recv_rpc", &recv_rpc},
|
||||
|
||||
/* direct syscalls */
|
||||
{"rtio_init", &rtio_init},
|
||||
{"rtio_get_counter", &rtio_get_counter},
|
||||
{"rtio_log", &rtio_log},
|
||||
{"rtio_output", &rtio_output},
|
||||
@ -351,11 +352,6 @@ static void now_init(void)
|
||||
}
|
||||
now = reply->now;
|
||||
mailbox_acknowledge();
|
||||
|
||||
if(now < 0) {
|
||||
rtio_init();
|
||||
now = rtio_get_counter() + (272000 << CONFIG_RTIO_FINE_TS_WIDTH);
|
||||
}
|
||||
}
|
||||
|
||||
static void now_save(void)
|
||||
|
@ -300,7 +300,6 @@ void session_startup_kernel(void)
|
||||
{
|
||||
struct msg_base *umsg;
|
||||
|
||||
now = -1;
|
||||
watchdog_init();
|
||||
if(!kloader_start_startup_kernel())
|
||||
return;
|
||||
@ -341,14 +340,12 @@ void session_start(void)
|
||||
out_packet_reset();
|
||||
|
||||
kloader_stop();
|
||||
now = -1;
|
||||
user_kernel_state = USER_KERNEL_NONE;
|
||||
}
|
||||
|
||||
void session_end(void)
|
||||
{
|
||||
kloader_stop();
|
||||
now = -1;
|
||||
watchdog_init();
|
||||
kloader_start_idle_kernel();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ class CreateTTLPulse(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def initialize_io(self):
|
||||
self.core.reset()
|
||||
self.loop_in.input()
|
||||
self.loop_out.off()
|
||||
|
||||
@ -33,6 +34,7 @@ class WriteLog(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
rtio_log("foo", 32)
|
||||
|
||||
|
||||
|
@ -12,6 +12,7 @@ class _Roundtrip(EnvExperiment):
|
||||
def roundtrip(self, obj, fn):
|
||||
fn(obj)
|
||||
|
||||
|
||||
class RoundtripTest(ExperimentCase):
|
||||
def assertRoundtrip(self, obj):
|
||||
exp = self.create(_Roundtrip)
|
||||
@ -55,6 +56,7 @@ class _DefaultArg(EnvExperiment):
|
||||
def run(self):
|
||||
return self.test()
|
||||
|
||||
|
||||
class DefaultArgTest(ExperimentCase):
|
||||
def test_default_arg(self):
|
||||
exp = self.create(_DefaultArg)
|
||||
@ -103,6 +105,7 @@ class _RPC(EnvExperiment):
|
||||
def builtin(self):
|
||||
sleep(1.0)
|
||||
|
||||
|
||||
class RPCTest(ExperimentCase):
|
||||
def test_args(self):
|
||||
exp = self.create(_RPC)
|
||||
@ -128,6 +131,7 @@ class _Payload1MB(EnvExperiment):
|
||||
data = [0 for _ in range(1000000//4)]
|
||||
self.devnull(data)
|
||||
|
||||
|
||||
class LargePayloadTest(ExperimentCase):
|
||||
def test_1MB(self):
|
||||
exp = self.create(_Payload1MB)
|
||||
|
@ -24,6 +24,7 @@ class RTT(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
self.ttl_inout.output()
|
||||
delay(1*us)
|
||||
with interleave:
|
||||
@ -48,6 +49,7 @@ class Loopback(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
self.loop_in.input()
|
||||
self.loop_out.off()
|
||||
delay(1*us)
|
||||
@ -71,6 +73,7 @@ class ClockGeneratorLoopback(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
self.loop_clock_in.input()
|
||||
self.loop_clock_out.stop()
|
||||
delay(1*us)
|
||||
@ -89,6 +92,7 @@ class PulseRate(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
dt = seconds_to_mu(300*ns)
|
||||
while True:
|
||||
for i in range(10000):
|
||||
@ -113,6 +117,7 @@ class PulseRateDDS(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
dt = seconds_to_mu(5*us)
|
||||
while True:
|
||||
delay(10*ms)
|
||||
@ -154,6 +159,7 @@ class LoopbackCount(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
self.loop_in.input()
|
||||
self.loop_out.output()
|
||||
delay(5*us)
|
||||
@ -173,6 +179,7 @@ class Underflow(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
while True:
|
||||
delay(25*ns)
|
||||
self.ttl_out.pulse(25*ns)
|
||||
@ -185,6 +192,7 @@ class SequenceError(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
t = now_mu()
|
||||
self.ttl_out.pulse(25*us)
|
||||
at_mu(t)
|
||||
@ -198,6 +206,7 @@ class Collision(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
delay(5*ms) # make sure we won't get underflow
|
||||
for i in range(16):
|
||||
self.ttl_out_serdes.pulse_mu(1)
|
||||
@ -211,6 +220,7 @@ class AddressCollision(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
self.loop_in.input()
|
||||
self.loop_in.pulse(10*us)
|
||||
|
||||
|
@ -13,7 +13,7 @@ class Collision(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.break_realtime()
|
||||
self.core.reset()
|
||||
t = now_mu()
|
||||
try:
|
||||
self.spi0.set_config_mu()
|
||||
@ -31,8 +31,8 @@ class Busy(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
try:
|
||||
self.core.break_realtime()
|
||||
self.spi0.set_config_mu()
|
||||
t = now_mu()
|
||||
self.spi0.set_config_mu()
|
||||
@ -54,6 +54,7 @@ class DrainErrors(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.reset()
|
||||
while True:
|
||||
try:
|
||||
self.core.break_realtime()
|
||||
|
Loading…
Reference in New Issue
Block a user