reorganize for devices/controllers

pull/4/head
Sebastien Bourdeauducq 2014-10-19 23:51:49 +08:00
parent c5acb68258
commit 61a50ee53c
32 changed files with 147 additions and 146 deletions

View File

View File

@ -1,7 +1,7 @@
from operator import itemgetter
from fractions import Fraction
from artiq.devices.runtime import LinkInterface
from artiq.coredevice.runtime import LinkInterface
class _RuntimeEnvironment(LinkInterface):
@ -12,7 +12,7 @@ class _RuntimeEnvironment(LinkInterface):
return str(self.llvm_module)
class CoreCom:
class Comm:
def get_runtime_env(self):
return _RuntimeEnvironment(Fraction(1, 1000000000))

View File

@ -7,8 +7,8 @@ from fractions import Fraction
import logging
from artiq.language import core as core_language
from artiq.devices.runtime import Environment
from artiq.devices import runtime_exceptions
from artiq.coredevice.runtime import Environment
from artiq.coredevice import runtime_exceptions
logger = logging.getLogger(__name__)
@ -54,7 +54,7 @@ def _read_exactly(f, n):
return r
class CoreCom:
class Comm:
def __init__(self, dev="/dev/ttyUSB1", baud=115200):
self._fd = os.open(dev, os.O_RDWR | os.O_NOCTTY)
self.port = os.fdopen(self._fd, "r+b", buffering=0)

View File

@ -1,13 +1,13 @@
from artiq.language.core import *
from artiq.language.units import *
from artiq.devices import rtio_core
from artiq.coredevice import rtio
class DDS(AutoContext):
"""Core device Direct Digital Synthesis (DDS) driver.
Controls DDS devices managed directly by the core device's runtime. It also
uses a RTIO channel (through :class:`artiq.devices.rtio_core.RTIOOut`) to
uses a RTIO channel (through :class:`artiq.coredevice.rtio.RTIOOut`) to
control a RF switch that gates the output of the DDS device.
:param dds_sysclk: DDS system frequency, used for computing the frequency
@ -21,7 +21,7 @@ class DDS(AutoContext):
def build(self):
self.previous_frequency = 0*MHz
self.sw = rtio_core.RTIOOut(self, channel=self.rtio_switch)
self.sw = rtio.RTIOOut(self, channel=self.rtio_switch)
kernel_attr = "previous_frequency"

View File

@ -1,5 +1,5 @@
from artiq.language.core import *
from artiq.devices.runtime_exceptions import RTIOSequenceError
from artiq.coredevice.runtime_exceptions import RTIOSequenceError
class LLRTIOOut(AutoContext):

View File

@ -1,6 +1,6 @@
from artiq.language.core import *
from artiq.language.units import *
from artiq.devices import rtio_core
from artiq.coredevice import rtio
# FIXME: check those numbers
@ -104,10 +104,10 @@ class CompoundPDQ2(AutoContext):
parameters = "ids rtio_trigger rtio_frame"
def build(self):
self.trigger = rtio_core.LLRTIOOut(self, channel=self.rtio_trigger)
self.frame0 = rtio_core.LLRTIOOut(self, channel=self.rtio_frame[0])
self.frame1 = rtio_core.LLRTIOOut(self, channel=self.rtio_frame[1])
self.frame2 = rtio_core.LLRTIOOut(self, channel=self.rtio_frame[2])
self.trigger = rtio.LLRTIOOut(self, channel=self.rtio_trigger)
self.frame0 = rtio.LLRTIOOut(self, channel=self.rtio_frame[0])
self.frame1 = rtio.LLRTIOOut(self, channel=self.rtio_frame[1])
self.frame2 = rtio.LLRTIOOut(self, channel=self.rtio_frame[2])
self.frames = []
self.current_frame = -1

View File

@ -9,7 +9,7 @@ import logging
from scipy import interpolate
import numpy as np
from artiq.devices.pdq2com import Pdq2
from pdq2com import Pdq2
def _main():

View File

@ -395,7 +395,7 @@ def EncodedException(eid):
class RuntimeException(Exception):
"""Base class for all exceptions used by the device runtime.
Those exceptions are defined in ``artiq.devices.runtime_exceptions``.
Those exceptions are defined in ``artiq.coredevice.runtime_exceptions``.
"""
pass

View File

@ -1,20 +1,20 @@
Drivers reference
=================
:mod:`artiq.devices.rtio_core` module
-------------------------------------
:mod:`artiq.coredevice.rtio` module
-----------------------------------
.. automodule:: artiq.devices.rtio_core
.. automodule:: artiq.coredevice.rtio
:members:
:mod:`artiq.devices.dds_core` module
-------------------------------------
:mod:`artiq.coredevice.dds` module
----------------------------------
.. automodule:: artiq.devices.dds_core
.. automodule:: artiq.coredevice.dds
:members:
:mod:`artiq.devices.runtime_exceptions` module
----------------------------------------------
:mod:`artiq.coredevice.runtime_exceptions` module
-------------------------------------------------
.. automodule:: artiq.devices.runtime_exceptions
.. automodule:: artiq.coredevice.runtime_exceptions
:members:

View File

@ -7,7 +7,7 @@ Connecting to the core device
As a very first step, we will turn on a LED on the core device. Create a file ``led.py`` containing the following: ::
from artiq import *
from artiq.devices import corecom_serial, core, gpio_core
from artiq.coredevice import comm_serial, core, gpio
class LED(AutoContext):
parameters = "led"
@ -17,9 +17,9 @@ As a very first step, we will turn on a LED on the core device. Create a file ``
self.led.set(1)
if __name__ == "__main__":
with corecom_serial.CoreCom() as com:
core_driver = core.Core(com)
led_driver = gpio_core.GPIOOut(core=core_driver, channel=0)
with comm_serial.Comm() as comm:
core_driver = core.Core(comm)
led_driver = gpio.GPIOOut(core=core_driver, channel=0)
exp = LED(core=core_driver, led=led_driver)
exp.run()
@ -82,7 +82,7 @@ The point of running code on the core device is the ability to meet demanding re
Create a new file ``rtio.py`` containing the following: ::
from artiq import *
from artiq.devices import corecom_serial, core, rtio_core
from artiq.coredevice import comm_serial, core, rtio
class Tutorial(AutoContext):
parameters = "o"
@ -94,9 +94,9 @@ Create a new file ``rtio.py`` containing the following: ::
delay(2*us)
if __name__ == "__main__":
with corecom_serial.CoreCom() as com:
core_driver = core.Core(com)
out_driver = rtio_core.RTIOOut(core=core_driver, channel=1)
with comm_serial.Comm() as comm:
core_driver = core.Core(comm)
out_driver = rtio.RTIOOut(core=core_driver, channel=1)
exp = Tutorial(core=core_driver, o=out_driver)
exp.run()
@ -106,7 +106,7 @@ Instead, inside the core device, output timing is generated by the gateware and
Try reducing the period of the generated waveform until the CPU cannot keep up with the generation of switching events and the underflow exception is raised. Then try catching it: ::
from artiq.devices.runtime_exceptions import RTIOUnderflow
from artiq.coredevice.runtime_exceptions import RTIOUnderflow
def print_underflow():
print("RTIO underflow occured")

View File

@ -30,19 +30,19 @@ class CompilerTest(AutoContext):
def main():
from artiq.devices import corecom_dummy, core, dds_core
from artiq.coredevice import comm_dummy, core, dds
coredev = core.Core(corecom_dummy.CoreCom())
coredev = core.Core(comm_dummy.Comm())
exp = CompilerTest(
core=coredev,
a=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=0, rtio_switch=0),
b=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=1, rtio_switch=1),
A=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=2, rtio_switch=2),
B=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=3, rtio_switch=3)
a=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=0, rtio_switch=0),
b=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=1, rtio_switch=1),
A=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=2, rtio_switch=2),
B=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=3, rtio_switch=3)
)
exp.run(3, 100*us)

View File

@ -1,5 +1,5 @@
from artiq import *
from artiq.devices import corecom_serial, core, dds_core, gpio_core
from artiq.coredevice import comm_serial, core, dds, gpio
class DDSTest(AutoContext):
@ -23,19 +23,19 @@ class DDSTest(AutoContext):
def main():
with corecom_serial.CoreCom() as com:
coredev = core.Core(com)
with comm_serial.Comm() as comm:
coredev = core.Core(comm)
exp = DDSTest(
core=coredev,
a=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=0, rtio_switch=0),
b=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=1, rtio_switch=1),
c=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=2, rtio_switch=2),
d=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=3, rtio_switch=3),
led=gpio_core.GPIOOut(core=coredev, channel=0)
a=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=0, rtio_switch=0),
b=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=1, rtio_switch=1),
c=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=2, rtio_switch=2),
d=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=3, rtio_switch=3),
led=gpio.GPIOOut(core=coredev, channel=0)
)
exp.run()

View File

@ -1,7 +1,7 @@
import sys
from artiq import *
from artiq.devices import corecom_serial, core
from artiq.coredevice import comm_serial, core
class Mandelbrot(AutoContext):
@ -39,8 +39,8 @@ class Mandelbrot(AutoContext):
def main():
with corecom_serial.CoreCom() as com:
exp = Mandelbrot(core=core.Core(com))
with comm_serial.Comm() as comm:
exp = Mandelbrot(core=core.Core(comm))
exp.run()
if __name__ == "__main__":

View File

@ -1,5 +1,5 @@
from artiq import *
from artiq.devices import corecom_serial, core, dds_core, rtio_core
from artiq.coredevice import comm_serial, core, dds, rtio
class PhotonHistogram(AutoContext):
@ -36,15 +36,15 @@ class PhotonHistogram(AutoContext):
def main():
with corecom_serial.CoreCom() as com:
coredev = core.Core(com)
with comm_serial.Comm() as comm:
coredev = core.Core(comm)
exp = PhotonHistogram(
core=coredev,
bd=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=0, rtio_switch=1),
bdd=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=1, rtio_switch=2),
pmt=rtio_core.RTIOIn(core=coredev, channel=0),
bd=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=0, rtio_switch=1),
bdd=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=1, rtio_switch=2),
pmt=rtio.RTIOIn(core=coredev, channel=0),
repeats=100,
nbins=100
)

View File

@ -1,6 +1,6 @@
from artiq import *
from artiq.devices import corecom_serial, core, rtio_core
from artiq.devices.runtime_exceptions import RTIOUnderflow
from artiq.coredevice import comm_serial, core, rtio
from artiq.coredevice.runtime_exceptions import RTIOUnderflow
def print_min_period(p):
@ -27,8 +27,8 @@ class PulsePerformance(AutoContext):
if __name__ == "__main__":
with corecom_serial.CoreCom() as com:
coredev = core.Core(com)
with comm_serial.Comm() as comm:
coredev = core.Core(comm)
exp = PulsePerformance(core=coredev,
o=rtio_core.RTIOOut(core=coredev, channel=1))
o=rtio.RTIOOut(core=coredev, channel=1))
exp.run()

View File

@ -1,5 +1,5 @@
from artiq import *
from artiq.devices import corecom_serial, core, rtio_core
from artiq.coredevice import comm_serial, core, rtio
def print_skew(p):
@ -28,9 +28,9 @@ class RTIOSkew(AutoContext):
print_skew(int((out_t - in_t)/(1*ns)))
if __name__ == "__main__":
with corecom_serial.CoreCom() as com:
coredev = core.Core(com)
with comm_serial.Comm() as comm:
coredev = core.Core(comm)
exp = RTIOSkew(core=coredev,
i=rtio_core.RTIOIn(core=coredev, channel=0),
o=rtio_core.RTIOOut(core=coredev, channel=1))
i=rtio.RTIOIn(core=coredev, channel=0),
o=rtio.RTIOOut(core=coredev, channel=1))
exp.run()

View File

@ -1,7 +1,8 @@
import numpy as np
from artiq import *
from artiq.devices import corecom_serial, core, dds_core, rtio_core, pdq2
from artiq.coredevice import comm_serial, core, dds, rtio
from artiq.devices import pdq2
class Transport(AutoContext):
@ -114,15 +115,15 @@ if __name__ == "__main__":
# 4 devices, 3 board each, 3 dacs each
)
with corecom_serial.CoreCom() as com:
coredev = core.Core(com)
with comm_serial.Comm() as comm:
coredev = core.Core(comm)
exp = Transport(
core=coredev,
bd=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=0, rtio_switch=1),
bdd=dds_core.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=1, rtio_switch=2),
pmt=rtio_core.RTIOIn(core=coredev, channel=0),
bd=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=0, rtio_switch=1),
bdd=dds.DDS(core=coredev, dds_sysclk=1*GHz,
reg_channel=1, rtio_switch=2),
pmt=rtio.RTIOIn(core=coredev, channel=0),
# a compound pdq device that wraps multiple usb devices (looked up
# by usb "serial number"/id) into one
electrodes=pdq2.CompoundPDQ2(

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
import argparse
from artiq.devices import corecom_serial
from artiq.coredevice import comm_serial
def main():
@ -16,13 +16,13 @@ def main():
with open(args.file, "rb") as f:
binary = f.read()
with corecom_serial.CoreCom() as com:
runtime_env = com.get_runtime_env()
with comm_serial.CoreCom() as comm:
runtime_env = comm.get_runtime_env()
if args.e:
print(runtime_env)
com.load(binary)
com.run(args.f)
com.serve(dict(), dict())
comm.load(binary)
comm.run(args.f)
comm.serve(dict(), dict())
if __name__ == "__main__":
main()

View File

@ -3,7 +3,7 @@ include $(MSCDIR)/software/common.mak
BOARD=papilio_pro
SERIAL=/dev/ttyUSB1
OBJECTS=isr.o elf_loader.o exception_jmp.o exceptions.o services.o corecom_serial.o gpio.o rtio.o dds.o main.o
OBJECTS=isr.o elf_loader.o exception_jmp.o exceptions.o services.o comm_serial.o gpio.o rtio.o dds.o main.o
all: runtime.bin

17
soc/runtime/comm.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef __COMM_H
#define __COMM_H
enum {
KERNEL_RUN_FINISHED,
KERNEL_RUN_EXCEPTION,
KERNEL_RUN_STARTUP_FAILED
};
typedef int (*object_loader)(void *, int);
typedef int (*kernel_runner)(const char *, int *);
void comm_serve(object_loader load_object, kernel_runner run_kernel);
int comm_rpc(int rpc_num, int n_args, ...);
void comm_log(const char *fmt, ...);
#endif /* __COMM_H */

View File

@ -3,7 +3,7 @@
#include <uart.h>
#include <generated/csr.h>
#include "corecom.h"
#include "comm.h"
/* host to device */
enum {
@ -139,12 +139,12 @@ static void receive_and_run_kernel(kernel_runner run_kernel)
send_char(MSGTYPE_KERNEL_STARTUP_FAILED);
break;
default:
corecom_log("BUG: run_kernel returned unexpected value '%d'", r);
comm_log("BUG: run_kernel returned unexpected value '%d'", r);
break;
}
}
void corecom_serve(object_loader load_object, kernel_runner run_kernel)
void comm_serve(object_loader load_object, kernel_runner run_kernel)
{
char msgtype;
@ -166,7 +166,7 @@ void corecom_serve(object_loader load_object, kernel_runner run_kernel)
}
}
int corecom_rpc(int rpc_num, int n_args, ...)
int comm_rpc(int rpc_num, int n_args, ...)
{
send_char(MSGTYPE_RPC_REQUEST);
send_sint(rpc_num);
@ -181,7 +181,7 @@ int corecom_rpc(int rpc_num, int n_args, ...)
return receive_int();
}
void corecom_log(const char *fmt, ...)
void comm_log(const char *fmt, ...)
{
va_list args;
int len;

View File

@ -1,17 +0,0 @@
#ifndef __CORECOM_H
#define __CORECOM_H
enum {
KERNEL_RUN_FINISHED,
KERNEL_RUN_EXCEPTION,
KERNEL_RUN_STARTUP_FAILED
};
typedef int (*object_loader)(void *, int);
typedef int (*kernel_runner)(const char *, int *);
void corecom_serve(object_loader load_object, kernel_runner run_kernel);
int corecom_rpc(int rpc_num, int n_args, ...);
void corecom_log(const char *fmt, ...);
#endif /* __CORECOM_H */

View File

@ -1,6 +1,6 @@
#include <string.h>
#include "corecom.h"
#include "comm.h"
#include "elf_loader.h"
#define EI_NIDENT 16
@ -85,11 +85,11 @@ struct elf32_sym {
#define SANITIZE_OFFSET_SIZE(offset, size) \
if(offset > 0x10000000) { \
corecom_log("Incorrect offset in ELF data"); \
comm_log("Incorrect offset in ELF data"); \
return 0; \
} \
if((offset + size) > elf_length) { \
corecom_log("Attempted to access past the end of ELF data"); \
comm_log("Attempted to access past the end of ELF data"); \
return 0; \
}
@ -121,7 +121,7 @@ static int fixup(void *dest, int dest_length, struct elf32_rela *rela, void *tar
val = _target - (_dest + offset);
_dest[offset] = (_dest[offset] & 0xfc000000) | (val & 0x03ffffff);
} else
corecom_log("Unsupported relocation type: %d", type);
comm_log("Unsupported relocation type: %d", type);
return 1;
}
@ -141,15 +141,15 @@ int load_elf(symbol_resolver resolver, symbol_callback callback, void *elf_data,
/* validate ELF */
GET_POINTER_SAFE(ehdr, struct elf32_ehdr, 0);
if(memcmp(ehdr->ident, elf_magic_header, sizeof(elf_magic_header)) != 0) {
corecom_log("Incorrect ELF header");
comm_log("Incorrect ELF header");
return 0;
}
if(ehdr->type != ET_REL) {
corecom_log("ELF is not relocatable");
comm_log("ELF is not relocatable");
return 0;
}
if(ehdr->machine != EM_OR1K) {
corecom_log("ELF is for a different machine");
comm_log("ELF is for a different machine");
return 0;
}
@ -190,7 +190,7 @@ int load_elf(symbol_resolver resolver, symbol_callback callback, void *elf_data,
/* load .text section */
if(textsize > dest_length) {
corecom_log(".text section is too large");
comm_log(".text section is too large");
return 0;
}
memcpy(dest, (char *)elf_data + textoff, textsize);
@ -209,13 +209,13 @@ int load_elf(symbol_resolver resolver, symbol_callback callback, void *elf_data,
name = (char *)elf_data + strtaboff + sym->name;
target = resolver(name);
if(target == NULL) {
corecom_log("Undefined symbol: %s", name);
comm_log("Undefined symbol: %s", name);
return 0;
}
if(!fixup(dest, dest_length, rela, target))
return 0;
} else {
corecom_log("Unsupported relocation");
comm_log("Unsupported relocation");
return 0;
}
}

View File

@ -1,5 +1,5 @@
#include "exceptions.h"
#include "corecom.h"
#include "comm.h"
#define MAX_EXCEPTION_CONTEXTS 64
@ -34,7 +34,7 @@ void exception_raise(int id)
stored_id = id;
exception_longjmp(exception_contexts[--ec_top].jb);
} else {
corecom_log("ERROR: uncaught exception, ID=%d\n", id);
comm_log("ERROR: uncaught exception, ID=%d\n", id);
while(1);
}
}

View File

@ -6,7 +6,7 @@
#include <time.h>
#include <generated/csr.h>
#include "corecom.h"
#include "comm.h"
#include "elf_loader.h"
#include "exceptions.h"
#include "services.h"
@ -31,7 +31,7 @@ static void symtab_init(void)
static int symtab_add(const char *name, void *target)
{
if(_symtab_count >= sizeof(symtab)/sizeof(symtab[0])) {
corecom_log("Too many provided symbols in object");
comm_log("Too many provided symbols in object");
symtab_init();
return 0;
}
@ -41,7 +41,7 @@ static int symtab_add(const char *name, void *target)
while(1) {
if(_symtab_strptr >= &_symtab_strings[sizeof(_symtab_strings)]) {
corecom_log("Provided symbol string table overflow");
comm_log("Provided symbol string table overflow");
symtab_init();
return 0;
}
@ -72,7 +72,7 @@ static int run_kernel(const char *kernel_name, int *eid)
k = find_symbol(symtab, kernel_name);
if(k == NULL) {
corecom_log("Failed to find kernel entry point '%s' in object", kernel_name);
comm_log("Failed to find kernel entry point '%s' in object", kernel_name);
return KERNEL_RUN_STARTUP_FAILED;
}
@ -113,6 +113,6 @@ int main(void)
rtio_init();
dds_init();
blink_led();
corecom_serve(load_object, run_kernel);
comm_serve(load_object, run_kernel);
return 0;
}

View File

@ -1,7 +1,7 @@
#include <string.h>
#include "elf_loader.h"
#include "corecom.h"
#include "comm.h"
#include "gpio.h"
#include "rtio.h"
#include "dds.h"
@ -9,7 +9,7 @@
#include "services.h"
static const struct symbol syscalls[] = {
{"rpc", corecom_rpc},
{"rpc", comm_rpc},
{"gpio_set", gpio_set},
{"rtio_oe", rtio_oe},
{"rtio_set", rtio_set},

View File

@ -2,13 +2,13 @@ import unittest
from operator import itemgetter
from artiq import *
from artiq.devices import corecom_serial, core, runtime_exceptions, rtio_core
from artiq.coredevice import comm_serial, core, runtime_exceptions, rtio
from artiq.sim import devices as sim_devices
def _run_on_device(k_class, **parameters):
with corecom_serial.CoreCom() as com:
coredev = core.Core(com)
with comm_serial.Comm() as comm:
coredev = core.Core(comm)
k_inst = k_class(core=coredev, **parameters)
k_inst.run()
@ -190,33 +190,33 @@ class _RTIOSequenceError(AutoContext):
class RTIOCase(unittest.TestCase):
def test_loopback(self):
npulses = 4
with corecom_serial.CoreCom() as com:
coredev = core.Core(com)
with comm_serial.Comm() as comm:
coredev = core.Core(comm)
uut = _RTIOLoopback(
core=coredev,
i=rtio_core.RTIOIn(core=coredev, channel=0),
o=rtio_core.RTIOOut(core=coredev, channel=1),
i=rtio.RTIOIn(core=coredev, channel=0),
o=rtio.RTIOOut(core=coredev, channel=1),
npulses=npulses
)
uut.run()
self.assertEqual(uut.result, npulses)
def test_underflow(self):
with corecom_serial.CoreCom() as com:
coredev = core.Core(com)
with comm_serial.Comm() as comm:
coredev = core.Core(comm)
uut = _RTIOUnderflow(
core=coredev,
o=rtio_core.RTIOOut(core=coredev, channel=1)
o=rtio.RTIOOut(core=coredev, channel=1)
)
with self.assertRaises(runtime_exceptions.RTIOUnderflow):
uut.run()
def test_sequence_error(self):
with corecom_serial.CoreCom() as com:
coredev = core.Core(com)
with comm_serial.Comm() as comm:
coredev = core.Core(comm)
uut = _RTIOSequenceError(
core=coredev,
o=rtio_core.RTIOOut(core=coredev, channel=1)
o=rtio.RTIOOut(core=coredev, channel=1)
)
with self.assertRaises(runtime_exceptions.RTIOSequenceError):
uut.run()