class NodePycom(NodeNoBase): """ Open node Pycom implementation """ TYPE = 'pycom' TTY = '/dev/iotlab/ttyON_PYCOM' BAUDRATE = 115200 def __init__(self): self.serial_redirection = SerialRedirection( self.TTY, self.BAUDRATE, serial_opts=('echo=0', 'raw', 'crnl')) def _send_sequence(self, sequence, delay=None): try: ser = serial.Serial(self.TTY, self.BAUDRATE) except serial.serialutil.SerialException: LOGGER.error("No serial port found") return 1 else: for command in sequence: ser.write(command) if delay is not None: time.sleep(delay) LOGGER.info("%s: %s", command, ser.read_all()) ser.close() return 0 @logger_call("Node Pycom: Setup node") def setup(self, firmware_path=None): """Start the custom serial redirection. Access from the frontend: socat -,echo=0 tcp:<node>:20000 Access from pymakr: ssh -L 20000:<pycom node>:20000 <login>@<site>.iot-lab.info socat PTY,link=/tmp/ttyS0,echo=0,crnl TCP:localhost:20000 """ pycom_str = PYCOM_FLASH_ERASE_HARD.format(bin=PYCOM_UPDATE_BIN, port=self.TTY) ret_val = subprocess.call(shlex.split(pycom_str)) ret_val += gateway_code.common.wait_tty(self.TTY, LOGGER, timeout=10) ret_val += self._send_sequence(PYCOM_SAFE_REBOOT_SEQUENCE, delay=2) ret_val += self._send_sequence(PYCOM_FLASH_ERASE_SEQUENCE) ret_val += self.reset() ret_val += self.serial_redirection.start() return ret_val @logger_call("Node Pycom: teardown node") def teardown(self): """Stop the serial redirection.""" ret_val = self._send_sequence(PYCOM_SAFE_REBOOT_SEQUENCE, delay=2) ret_val += self._send_sequence(PYCOM_FLASH_ERASE_SEQUENCE) ret_val += self.serial_redirection.stop() pycom_str = PYCOM_FLASH_ERASE_HARD.format(bin=PYCOM_UPDATE_BIN, port=self.TTY) ret_val += subprocess.call(shlex.split(pycom_str)) return ret_val @logger_call("Node Pycom: reset node") def reset(self): """Machine reset of the pycom node.""" return self._send_sequence(PYCOM_RESET_SEQUENCE)
class NodeOpenOCDBase(OpenNodeBase): # pylint:disable=no-member """ Open node OpenOCD implemention """ ELF_TARGET = ('ELFCLASS32', 'EM_ARM') OPENOCD_CLASS = OpenOCD OPENOCD_PATH = '/opt/openocd-0.10.0/bin/openocd' AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'get_uid', 'leds_on', 'leds_off', 'leds_blink' ] ALIM = '5V' def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = self.OPENOCD_CLASS.from_node(self) def clear_serial(self): """Clear serial link by flushing the input buffer.""" try: ser = serial.Serial(self.TTY, self.BAUDRATE) except serial.serialutil.SerialException: LOGGER.error("No serial port found") return 1 ser.reset_input_buffer() ser.close() return 0 @logger_call("Node OpenOCD: Setup of openocd node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node OpenOCD: teardown of openocd node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 # ON may have been stopped at the end of the experiment. # And then restarted again in cn teardown. # This leads to problem where the TTY disappears and reappears during # the first 2 seconds. So let some time if it wants to disappear first. common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) # cleanup debugger before flashing ret_val += self.debug_stop() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node OpenOCD: flash of openocd node") def flash(self, firmware_path=None): """ Flash the given firmware on openocd node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on OpenOCD: %s', firmware_path) ret_val = self.openocd.flash(firmware_path) if hasattr(self, 'JLINK_SERIAL') and self.JLINK_SERIAL: ret_val += common.wait_tty(self.TTY, LOGGER) if hasattr(self, 'DIRTY_SERIAL') and self.DIRTY_SERIAL: ret_val += self.clear_serial() return ret_val @logger_call("Node OpenOCD: reset of openocd node") def reset(self): """ Reset the openocd node using jtag """ LOGGER.info('Reset openocd node') return self.openocd.reset() def debug_start(self): """ Start openocd node debugger """ LOGGER.info('openocd node debugger start') return self.openocd.debug_start() def debug_stop(self): """ Stop openocd node debugger """ LOGGER.info('openocd node debugger stop') return self.openocd.debug_stop() @staticmethod def status(): """ Check openocd node status """ # Status is called when open node is not powered return 0
class NodeZigduino(OpenNodeBase): """Open node Zigduino implementation.""" TYPE = "zigduino" ELF_TARGET = ('ELFCLASS32', 'EM_AVR') TTY = '/dev/iotlab/ttyON_ZIGDUINO' BAUDRATE = 57600 FW_IDLE = static_path('zigduino_idle.elf') FW_AUTOTEST = static_path('zigduino_autotest.elf') AVRDUDE_CONF = { 'tty': TTY, 'baudrate': 57600, 'model': 'atmega128rfa1', 'programmer': 'arduino', } AUTOTEST_AVAILABLE = [ 'echo', 'get_time' # mandatory ] ALIM = '5V' def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.avrdude = AvrDude(self.AVRDUDE_CONF) def disable_dtr(self): """ Disable serial port DTR in order to avoid board autoreset at first connection """ # Check if Zigduino is up before DTR reset try: ser = serial.Serial(self.TTY, self.BAUDRATE) except SerialException: LOGGER.error("No serial port found") return 1 with open(self.TTY) as ser: attrs = termios.tcgetattr(ser) attrs[2] = attrs[2] & ~termios.HUPCL termios.tcsetattr(ser, termios.TCSAFLUSH, attrs) return 0 @logger_call("Setup of Zigduino node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 # it appears that /dev/ttyON_ZIGDUINO need some time to be detected common.wait_no_tty(self.TTY, timeout=common.TTY_DETECT_TIME) ret_val += common.wait_tty(self.TTY, LOGGER, timeout=common.TTY_DETECT_TIME) ret_val += self.flash(firmware_path, redirect=False) ret_val += self.disable_dtr() ret_val += self.serial_redirection.start() return ret_val @logger_call("Teardown of Zigduino node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 common.wait_no_tty(self.TTY, timeout=common.TTY_DETECT_TIME) ret_val += common.wait_tty(self.TTY, LOGGER, timeout=common.TTY_DETECT_TIME) ret_val += self.serial_redirection.stop() # Reboot needs 8 seconds before ending linux sees it in < 2 seconds ret_val += common.wait_tty(self.TTY, LOGGER, timeout=10) ret_val += self.flash(None, redirect=False) return ret_val @logger_call("Flash of Zigduino node") def flash(self, firmware_path=None, redirect=True): """ Flash the given firmware on Zigduino node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware """ ret_val = 0 firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on Zigduino: %s', firmware_path) # First stop serial redirection, flash hangup if an # user session is openened on port 20000 common.wait_no_tty(self.TTY, timeout=common.TTY_DETECT_TIME) ret_val += common.wait_tty(self.TTY, LOGGER, timeout=common.TTY_DETECT_TIME) if redirect: ret_val += self.serial_redirection.stop() # Then flash ret_val += self.avrdude.flash(firmware_path) ret_val += common.wait_tty(self.TTY, LOGGER, timeout=10) # Finally restore serial redirection if redirect: ret_val += self.disable_dtr() ret_val += self.serial_redirection.start() LOGGER.info("end flash") return ret_val @logger_call("Reset of Zigduino node") def reset(self): """ Reset the Zigduino node using DTR""" ret_val = 0 # Check if Zigduino is up before DTR reset try: ser = serial.Serial(self.TTY, self.BAUDRATE) except SerialException: LOGGER.error("No serial port found") return 1 try: ser.setDTR(False) time.sleep(0.5) ser.setDTR(True) time.sleep(0.5) ser.close() except OSError: LOGGER.warning("Nothing to reset") ret_val += common.wait_tty(self.TTY, LOGGER, timeout=10) return ret_val @staticmethod def status(): """ Check Zigduino node status """ # It's impossible for us to check the status of the zigduino node return 0
class NodeStLrwan1(object): """ Open node STM32 LRWAN1 implemention """ TYPE = 'st_lrwan1' ELF_TARGET = ('ELFCLASS32', 'EM_ARM') TTY = '/dev/iotlab/ttyON_ST_LRWAN1' BAUDRATE = 115200 OPENOCD_CFG_FILE = static_path('iot-lab-st-lrwan1.cfg') OPENOCD_PATH = '/opt/openocd-0.10.0/bin/openocd' FW_IDLE = static_path('st_lrwan1_idle.elf') FW_AUTOTEST = static_path('st_lrwan1_autotest.elf') AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'leds_on', 'leds_off' ] ALIM = '5V' def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self) def clear_serial(self): """Clear serial link by flushing the input buffer.""" try: ser = serial.Serial(self.TTY, self.BAUDRATE) except serial.serialutil.SerialException: LOGGER.error("No serial port found") return 1 ser.reset_input_buffer() ser.close() return 0 @logger_call("Node ST_LRWAN1 : Setup of st_lrwan1 node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node ST_LRWAN1 : teardown of st_lrwan1 node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 # ON may have been stopped at the end of the experiment. # And then restarted again in cn teardown. # This leads to problem where the TTY disappears and reappears during # the first 2 seconds. So let some time if it wants to disappear first. common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) # cleanup debugger before flashing ret_val += self.debug_stop() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node ST_LRWAN1 : flash of st_lrwan1 node") def flash(self, firmware_path=None): """ Flash the given firmware on ST_LRWAN1 node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on ST_LRWAN1: %s', firmware_path) ret = self.openocd.flash(firmware_path) ret += self.clear_serial() return ret @logger_call("Node ST_LRWAN1 : reset of st_lrwan1 node") def reset(self): """ Reset the ST_LRWAN1 node using jtag """ LOGGER.info('Reset ST_LRWAN1 node') return self.openocd.reset() def debug_start(self): """ Start ST_LRWAN1 node debugger """ LOGGER.info('ST_LRWAN1 Node debugger start') return self.openocd.debug_start() def debug_stop(self): """ Stop ST_LRWAN1 node debugger """ LOGGER.info('ST_LRWAN1 Node debugger stop') return self.openocd.debug_stop() @staticmethod def status(): """ Check ST_LRWAN1 node status """ # Status is called when open node is not powered # So can't check for FTDI return 0
class NodeRpi3(OpenNodeBase): """ Open node RPi3 implementation """ TYPE = 'rpi3' TTY = '/dev/iotlab/ttyON_RPI3' BAUDRATE = 115200 ALIM = '5V' # 15 secs was not always enough RPI3_TTY_DETECT_TIME = 20 def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self._rpi3_expect = None @property def programmer(self): """There's no programmer for RPI3 node.""" return None @logger_call("Node RPi3 : setup of rpi3 node") def setup(self, _firmware, debug=True): # pylint: disable=arguments-differ """ Wait that open nodes tty appears and start RPi3 boot log """ ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER, self.RPI3_TTY_DETECT_TIME) ret_val += self.serial_redirection.start() if ret_val == 0 and debug: # Timeout 15 minutes for boot (we saw 10minutes boot already) self._debug_boot_start(15 * 60) return ret_val @logger_call("Node RPi3 : teardown of rpi3 node") def teardown(self): """ Stop RPi3 boot log """ ret_val = 0 ret_val += self.serial_redirection.stop() ret_val += self._debug_boot_stop() return ret_val @classmethod def verify(cls): # Linux open node = no autotest and firmware target verification return 0 def _debug_boot_start(self, timeout): """ RPi3 boot debug thread start """ thr = Thread(target=self.wait_booted, args=(timeout, )) thr.daemon = True thr.start() def wait_booted(self, timeout): """ Monitor RPi3 tty to check if node booted """ t_start = time.time() try: LOGGER.debug("Time before boot %s", datetime.datetime.now()) self._rpi3_expect = SerialExpectForSocket(logger=LOGGER) match = self._rpi3_expect.expect(' login: '******'wait_tty' and serial creation (fast start/stop) match = '' finally: delta_t = time.time() - t_start self._debug_boot_stop() if match != '': LOGGER.info("Boot RPi3 succeeded in time: %ds", delta_t) else: LOGGER.error("Boot RPi3 failed in time: %ds", delta_t) return match def _debug_boot_stop(self): """ Stop the debug thread """ try: self._rpi3_expect.close() except AttributeError: # pragma: no cover pass return 0 def status(self): """ Check RPi3 node status """ # No check done for the moment return 0
class NodeSamr21(object): """ Open node SAMR21 implemention """ TYPE = 'samr21' ELF_TARGET = ('ELFCLASS32', 'EM_ARM') TTY = '/dev/ttyON_SAMR21' BAUDRATE = 115200 OPENOCD_CFG_FILE = static_path('iot-lab-samr21.cfg') OPENOCD_OPTS = () FW_IDLE = static_path('samr21_idle.elf') FW_AUTOTEST = static_path('samr21_autotest.elf') AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'leds_on', 'leds_off' ] ALIM = '5V' FLASH_TIMEOUT = 60 # Got 40 seconds at max with riot gnrc_networking def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self, timeout=self.FLASH_TIMEOUT) @logger_call("Node SAMR21 : Setup of samr21 node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node SAMR21 : teardown of samr21 node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 # ON may have been stopped at the end of the experiment. # And then restarted again in cn teardown. # This leads to problem where the TTY disappears and reappears during # the first 2 seconds. So let some time if it wants to disappear first. common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) # cleanup debugger before flashing ret_val += self.debug_stop() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node SAMR21 : flash of sam21 node") def flash(self, firmware_path=None): """ Flash the given firmware on SAMR21 node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on SAMR21: %s', firmware_path) return self.openocd.flash(firmware_path) @logger_call("Node SAMR21 : reset of samr21 node") def reset(self): """ Reset the SAMR21 node using jtag """ LOGGER.info('Reset SAMR21 node') return self.openocd.reset() def debug_start(self): """ Start SAMR21 node debugger """ LOGGER.info('SAMR21 Node debugger start') return self.openocd.debug_start() def debug_stop(self): """ Stop SAMR21 node debugger """ LOGGER.info('SAMR21 Node debugger stop') return self.openocd.debug_stop() @staticmethod def status(): """ Check SAMR21 node status """ # Status is called when open node is not powered # So can't check for FTDI return 0
class NodeFox(object): """ Open node FOX implemention """ # Contrary to m3 node, fox node need some time to be visible. # Also flash/reset may fail after a node start_dc but don't care TYPE = "fox" ELF_TARGET = ("ELFCLASS32", "EM_ARM") TTY = "/dev/ttyON_FOX" BAUDRATE = 500000 OPENOCD_CFG_FILE = static_path("iot-lab-fox.cfg") OPENOCD_OPTS = ("target/stm32f1x.cfg",) FW_IDLE = static_path("idle_fox.elf") FW_AUTOTEST = static_path("fox_autotest.elf") AUTOTEST_AVAILABLE = [ "echo", "get_time", # mandatory "get_uid", "get_accelero", "get_gyro", "get_magneto", "radio_pkt", "radio_ping_pong", "leds_on", "leds_off", "leds_blink", # 'leds_consumption', not precise enough # (0.886405, [0.886405, 0.886405, 0.886405, 0.887015]) ] ALIM = "5V" def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self) @logger_call("Node Fox : Setup of fox node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node Fox : teardown of fox node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 # ON may have been stopped at the end of the experiment. # And then restarted again in cn teardown. # This leads to problem where the TTY disappears and reappears during # the first 2 seconds. So let some time if it wants to disappear first. common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) # cleanup debugger before flashing ret_val += self.debug_stop() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node Fox : flash of fox node") def flash(self, firmware_path=None): """ Flash the given firmware on FOX node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info("Flash firmware on FOX: %s", firmware_path) return self.openocd.flash(firmware_path) @logger_call("Node Fox : reset of fox node") def reset(self): """ Reset the FOX node using jtag """ LOGGER.info("Reset FOX node") return self.openocd.reset() def debug_start(self): """ Start FOX node debugger """ LOGGER.info("FOX Node debugger start") return self.openocd.debug_start() def debug_stop(self): """ Stop FOX node debugger """ LOGGER.info("FOX Node debugger stop") return self.openocd.debug_stop() @staticmethod def status(): """ Check FOX node status """ # Status is called when open node is not powered # So can't check for FTDI return 0
class NodeMicrobit(object): """ Open node Micro:Bit implementation """ TYPE = 'microbit' ELF_TARGET = ('ELFCLASS32', 'EM_ARM') TTY = '/dev/iotlab/ttyON_MICROBIT' BAUDRATE = 115200 FW_IDLE = static_path('microbit_idle.elf') FW_AUTOTEST = static_path('microbit_autotest.elf') AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'leds_on', 'leds_off' ] ALIM = '5V' FLASH_TIMEOUT = 60 # Got 40 seconds at max with riot gnrc_networking def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.ocd = PyOCD(True, self.FLASH_TIMEOUT) @logger_call("Node Micro:Bit : Setup of micro:bit node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node Micro:Bit : teardown of micro:bit node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 # ON may have been stopped at the end of the experiment. # And then restarted again in cn teardown. # This leads to problem where the TTY disappears and reappears during # the first 2 seconds. So let some time if it wants to disappear first. common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) # cleanup debugger before flashing ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node Micro:Bit : flash of micro:bit node") def flash(self, firmware_path=None): """ Flash the given firmware on Node Micro:Bit node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on Node Micro:Bit : %s', firmware_path) return self.ocd.flash(firmware_path) @logger_call("Node Micro:Bit : reset of micro:bit node") def reset(self): """ Reset the Micro:Bit node """ LOGGER.info('Reset Micro:Bit node') return self.ocd.reset() def debug_start(self): """ Start Micro:Bit node debugger """ LOGGER.info('Micro:Bit Node debugger start') return self.ocd.debug_start() def debug_stop(self): """ Stop Micro:Bit node debugger """ LOGGER.info('Micro:Bit Node debugger stop') return self.ocd.debug_stop() @staticmethod def status(): """ Check Micro:Bit node status """ return 0
class NodeA8(object): """ Open node A8 implementation """ TYPE = 'a8' ELF_TARGET = ('ELFCLASS32', 'EM_ARM') TTY = '/dev/ttyON_A8' BAUDRATE = 115200 LOCAL_A8_M3_TTY = '/tmp/local_ttyA8_M3' A8_M3_TTY = '/dev/ttyA8_M3' A8_M3_BAUDRATE = 500000 A8_M3_FW_AUTOTEST = static_path('a8_autotest.elf') ALIM = '5V' # 15 secs was not always enough A8_TTY_DETECT_TIME = 20 AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'get_uid', 'get_accelero', 'get_gyro', 'get_magneto', 'test_gpio', 'test_i2c', 'radio_pkt', 'radio_ping_pong', 'test_pps_start', 'test_pps_get', 'test_pps_stop', 'leds_on', 'leds_off', 'leds_blink', ] def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self._a8_expect = None @logger_call("Node A8 : setup of a8 node") def setup(self, _firmware, debug=True): # pylint: disable=unused-argument """ Wait that open nodes tty appears and start A8 boot log """ ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER, self.A8_TTY_DETECT_TIME) ret_val += self.serial_redirection.start() if ret_val == 0 and debug: # Timeout 15 minutes for boot (we saw 10minutes boot already) self._debug_boot_start(15 * 60) return ret_val @logger_call("Node A8 : teardown of a8 node") def teardown(self): """ Stop A8 boot log """ ret_val = 0 ret_val += self.serial_redirection.stop() ret_val += self._debug_boot_stop() return ret_val def _debug_boot_start(self, timeout): """ A8 boot debug thread start """ thr = Thread(target=self.wait_booted, args=(timeout,)) thr.daemon = True thr.start() def wait_booted(self, timeout): """ Monitor A8 tty to check if node booted """ try: t_start = time.time() LOGGER.debug("Time before boot %s", datetime.datetime.now()) self._a8_expect = SerialExpectForSocket(logger=LOGGER) match = self._a8_expect.expect(' login: '******'wait_tty' and serial creation (fast start/stop) match = '' finally: delta_t = time.time() - t_start self._debug_boot_stop() if match != '': LOGGER.info("Boot A8 succeeded in time: %ds", delta_t) else: LOGGER.error("Boot A8 failed in time: %ds", delta_t) return match def _debug_boot_stop(self): """ Stop the debug thread """ try: self._a8_expect.close() except AttributeError: # pragma: no cover pass return 0 @staticmethod def status(): """ Check A8 node status """ # No check done for the moment return 0
def __init__(self): self.serial_redirection = SerialRedirection( self.TTY, self.BAUDRATE, serial_opts=('echo=0', 'raw', 'crnl'))
def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self, timeout=self.FLASH_TIMEOUT)
class NodeM3(object): """ Open node M3 implemenation """ TYPE = 'm3' ELF_TARGET = ('ELFCLASS32', 'EM_ARM') TTY = '/dev/ttyON_M3' BAUDRATE = 500000 OPENOCD_CFG_FILE = static_path('iot-lab-m3.cfg') OPENOCD_OPTS = ('target/stm32f1x.cfg',) FW_IDLE = static_path('idle_m3.elf') FW_AUTOTEST = static_path('m3_autotest.elf') ALIM = '3.3V' AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'get_uid', 'get_pressure', 'get_light', 'test_flash', 'get_accelero', 'get_gyro', 'get_magneto', 'test_gpio', 'test_i2c', 'radio_pkt', 'radio_ping_pong', 'leds_consumption', 'leds_on', 'leds_off', 'leds_blink', ] def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self) @logger_call("Node M3 : Setup of m3 node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 common.wait_no_tty(self.TTY, timeout=0) ret_val += common.wait_tty(self.TTY, LOGGER, timeout=0) ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node M3 : teardown of m3 node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 common.wait_no_tty(self.TTY, timeout=0) ret_val += common.wait_tty(self.TTY, LOGGER, timeout=0) # cleanup debugger before flashing ret_val += self.debug_stop() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node M3 : flash of m3 node") def flash(self, firmware_path=None): """ Flash the given firmware on M3 node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on M3: %s', firmware_path) return self.openocd.flash(firmware_path) @logger_call("Node M3 : reset of m3 node") def reset(self): """ Reset the M3 node using jtag """ LOGGER.info('Reset M3 node') return self.openocd.reset() def debug_start(self): """ Start M3 node debugger """ LOGGER.info('M3 Node debugger start') return self.openocd.debug_start() def debug_stop(self): """ Stop M3 node debugger """ LOGGER.info('M3 Node debugger stop') return self.openocd.debug_stop() @staticmethod def status(): """ Check M3 node status """ return ftdi_check('m3', '2232')
def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.avrdude = AvrDude(self.AVRDUDE_CONF)
class NodeLeonardo(object): """ Open node Leonardo implemention """ TYPE = 'leonardo' ELF_TARGET = ('ELFCLASS32', 'EM_AVR') TTY = '/dev/ttyON_LEONARDO' # The Leonardo node need a special open/close and then appear on a new TTY TTY_PROG = '/dev/ttyON_LEONARDO_PROG' # Regular TTY will be restored after 8 seconds TTY_RESTORE_TIME = 8 + common.TTY_DETECT_TIME TTY_READY_DELAY = 1 BAUDRATE = 9600 FW_IDLE = static_path('idle_leonardo.elf') FW_AUTOTEST = static_path('leonardo_autotest.elf') AVRDUDE_CONF = { 'tty': TTY_PROG, 'baudrate': 9600, 'model': 'atmega32u4', 'programmer': 'avr109', } AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'get_uid', ] ALIM = '5V' def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.avrdude = AvrDude(self.AVRDUDE_CONF) @logger_call("Node Leonardo : Setup of leonardo node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 ret_val += self._wait_tty_ready() ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node Leonardo : Teardown of leonardo node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 ret_val += self._wait_tty_ready() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node Leonardo : Flash of leonardo node") def flash(self, firmware_path=None): """ Flash the given firmware on Leonardo node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware """ if AvrDude.trigger_bootloader(self.TTY, self.TTY_PROG, timeout=15): LOGGER.error("FLASH : Leonardo's jtag port not available") return 1 ret_val = 0 firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on Leonardo: %s', firmware_path) ret_val += self.avrdude.flash(firmware_path) ret_val += common.wait_tty(self.TTY, LOGGER, self.TTY_RESTORE_TIME) return ret_val @logger_call("Node Leonardo : Reset of leonardo node") def reset(self): """ Reset the Leonardo node using jtag """ ret_val = 0 ret_val += AvrDude.trigger_bootloader(self.TTY, self.TTY_PROG) ret_val += common.wait_tty(self.TTY, LOGGER, self.TTY_RESTORE_TIME) return ret_val @staticmethod def status(): """ Check Leonardo node status """ # It's impossible for us to check the status of the leonardo node return 0 def _wait_tty_ready(self): """Wait that the tty is ready to use. Node may have been stopped at the end of the experiment. And then restarted again in cn teardown. This leads to problem where the TTY disappears and reappears during the first 2 seconds. So let some time if it wants to disappear first. Also, got some problems when using the tty directly after appearing, so git it some delay. """ common.wait_no_tty(self.TTY) ret = common.wait_tty(self.TTY, LOGGER) # wait tty ready to speak time.sleep(self.TTY_READY_DELAY) return ret
def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self._a8_expect = None
def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self) self.edbg = Edbg() self._current_fw = None self._in_debug = False
class NodeM3(object): """ Open node M3 implemenation """ TYPE = 'm3' ELF_TARGET = ('ELFCLASS32', 'EM_ARM') TTY = '/dev/iotlab/ttyON_M3' BAUDRATE = 500000 OPENOCD_CFG_FILE = static_path('iot-lab-m3.cfg') OPENOCD_OPTS = ('target/stm32f1x.cfg',) FW_IDLE = static_path('m3_idle.elf') FW_AUTOTEST = static_path('m3_autotest.elf') ALIM = '3.3V' AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'get_uid', 'get_pressure', 'get_light', 'test_flash', 'get_accelero', 'get_gyro', 'get_magneto', 'test_gpio', 'test_i2c', 'radio_pkt', 'radio_ping_pong', 'leds_consumption', 'leds_on', 'leds_off', 'leds_blink', ] def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self) @logger_call("Node M3 : Setup of m3 node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 common.wait_no_tty(self.TTY, timeout=0) ret_val += common.wait_tty(self.TTY, LOGGER, timeout=0) ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node M3 : teardown of m3 node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 common.wait_no_tty(self.TTY, timeout=0) ret_val += common.wait_tty(self.TTY, LOGGER, timeout=0) # cleanup debugger before flashing ret_val += self.debug_stop() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node M3 : flash of m3 node") def flash(self, firmware_path=None): """ Flash the given firmware on M3 node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on M3: %s', firmware_path) return self.openocd.flash(firmware_path) @logger_call("Node M3 : reset of m3 node") def reset(self): """ Reset the M3 node using jtag """ LOGGER.info('Reset M3 node') return self.openocd.reset() def debug_start(self): """ Start M3 node debugger """ LOGGER.info('M3 Node debugger start') return self.openocd.debug_start() def debug_stop(self): """ Stop M3 node debugger """ LOGGER.info('M3 Node debugger stop') return self.openocd.debug_stop() @staticmethod def status(): """ Check M3 node status """ return ftdi_check('m3', '2232')
def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.ocd = PyOCD(True, self.FLASH_TIMEOUT)
class NodeSamr21(object): """ Open node SAMR21 implemention """ TYPE = 'samr21' ELF_TARGET = ('ELFCLASS32', 'EM_ARM') TTY = '/dev/iotlab/ttyON_SAMR21' BAUDRATE = 115200 OPENOCD_CFG_FILE = static_path('iot-lab-samr21.cfg') FW_IDLE = static_path('samr21_idle.elf') FW_AUTOTEST = static_path('samr21_autotest.elf') AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'leds_on', 'leds_off' ] ALIM = '5V' def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self) self.edbg = Edbg() @logger_call("Node SAMR21 : Setup of samr21 node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node SAMR21 : teardown of samr21 node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 # ON may have been stopped at the end of the experiment. # And then restarted again in cn teardown. # This leads to problem where the TTY disappears and reappears during # the first 2 seconds. So let some time if it wants to disappear first. common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) # cleanup debugger before flashing ret_val += self.debug_stop() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node SAMR21 : flash of sam21 node") def flash(self, firmware_path=None): """ Flash the given firmware on SAMR21 node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on SAMR21: %s', firmware_path) return self.edbg.flash(firmware_path) @logger_call("Node SAMR21 : reset of samr21 node") def reset(self): """ Reset the SAMR21 node using jtag """ LOGGER.info('Reset SAMR21 node') return self.openocd.reset() def debug_start(self): """ Start SAMR21 node debugger """ LOGGER.info('SAMR21 Node debugger start') return self.openocd.debug_start() def debug_stop(self): """ Stop SAMR21 node debugger """ LOGGER.info('SAMR21 Node debugger stop') return self.openocd.debug_stop() @staticmethod def status(): """ Check SAMR21 node status """ # Status is called when open node is not powered # So can't check for FTDI return 0
def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self)
class NodeLeonardo(OpenNodeBase): """ Open node Leonardo implementation """ TYPE = 'leonardo' ELF_TARGET = ('ELFCLASS32', 'EM_AVR') TTY = '/dev/iotlab/ttyON_LEONARDO' # The Leonardo node need a special open/close and then appear on a new TTY TTY_PROG = '/dev/ttyON_LEONARDO_PROG' # Regular TTY will be restored after 8 seconds TTY_RESTORE_TIME = 8 + common.TTY_DETECT_TIME TTY_READY_DELAY = 1 BAUDRATE = 9600 FW_IDLE = static_path('leonardo_idle.elf') FW_AUTOTEST = static_path('leonardo_autotest.elf') AVRDUDE_CONF = { 'tty': TTY_PROG, 'baudrate': 9600, 'model': 'atmega32u4', 'programmer': 'avr109', } AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'get_uid', ] ALIM = '5V' def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.avrdude = AvrDude(self.AVRDUDE_CONF) @logger_call("Node Leonardo : Setup of leonardo node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 ret_val += self._wait_tty_ready() ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node Leonardo : Teardown of leonardo node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 ret_val += self._wait_tty_ready() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node Leonardo : Flash of leonardo node") def flash(self, firmware_path=None, binary=False, offset=0): """ Flash the given firmware on Leonardo node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware :param binary: whether to flash a binary file :param offset: at which offset to flash the binary file """ if AvrDude.trigger_bootloader(self.TTY, self.TTY_PROG, timeout=15): LOGGER.error("FLASH : Leonardo's jtag port not available") return 1 if binary: LOGGER.error('FLASH: binary mode not supported with Leonardo') return 1 if offset != 0: LOGGER.error('FLASH: flash offset is not supported with Leonardo') return 1 ret_val = 0 firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on Leonardo: %s', firmware_path) ret_val += self.avrdude.flash(firmware_path) ret_val += common.wait_tty(self.TTY, LOGGER, self.TTY_RESTORE_TIME) return ret_val @logger_call("Node Leonardo : Reset of leonardo node") def reset(self): """ Reset the Leonardo node using jtag """ ret_val = 0 ret_val += AvrDude.trigger_bootloader(self.TTY, self.TTY_PROG) ret_val += common.wait_tty(self.TTY, LOGGER, self.TTY_RESTORE_TIME) return ret_val @staticmethod def status(): """ Check Leonardo node status """ # It's impossible for us to check the status of the leonardo node return 0 def _wait_tty_ready(self): """Wait that the tty is ready to use. Node may have been stopped at the end of the experiment. And then restarted again in cn teardown. This leads to problem where the TTY disappears and reappears during the first 2 seconds. So let some time if it wants to disappear first. Also, got some problems when using the tty directly after appearing, so git it some delay. """ common.wait_no_tty(self.TTY) ret = common.wait_tty(self.TTY, LOGGER) # wait tty ready to speak time.sleep(self.TTY_READY_DELAY) return ret
class NodeArduinoZero(object): """ Open node Arduino Zero implementation """ TYPE = 'arduino_zero' ELF_TARGET = ('ELFCLASS32', 'EM_ARM') TTY = '/dev/iotlab/ttyON_ARDUINO_ZERO' BAUDRATE = 115200 OPENOCD_CFG_FILE = static_path('iot-lab-arduino-zero.cfg') FW_IDLE = static_path('arduino_zero_idle.elf') FW_AUTOTEST = static_path('arduino_zero_autotest.elf') AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'leds_on', 'leds_off' ] ALIM = '5V' def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self) self.edbg = Edbg() self._current_fw = None self._in_debug = False @logger_call("Node Arduino Zero : Setup of arduino zero node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ self._in_debug = False ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node Arduino Zero : teardown of arduino zero node") def teardown(self): """ Stop serial redirection and flash idle firmware """ self._in_debug = False ret_val = 0 # ON may have been stopped at the end of the experiment. # And then restarted again in cn teardown. # This leads to problem where the TTY disappears and reappears during # the first 2 seconds. So let some time if it wants to disappear first. common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) # cleanup debugger before flashing ret_val += self.debug_stop() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node Arduino Zero : flash of arduino zero node") def flash(self, firmware_path=None): """ Flash the given firmware on Arduino Zero node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on Arduino Zero: %s', firmware_path) self._current_fw = firmware_path if self._in_debug: return self.openocd.flash(firmware_path) return self.edbg.flash(firmware_path) @logger_call("Node Arduino Zero : reset of arduino zero node") def reset(self): """ Reset the Arduino Zero node using jtag """ LOGGER.info('Reset Arduino Zero node') return self.openocd.reset() def debug_start(self): """ Start Arduino Zero node debugger """ LOGGER.info('Arduino Zero Node debugger start') self._in_debug = True if self._current_fw is not None: # Reflash current firmware using openocd to avoid misbehavior of # previously flashed firmware (with edbg) self.flash(firmware_path=self._current_fw) return self.openocd.debug_start() def debug_stop(self): """ Stop Arduino Zero node debugger """ LOGGER.info('Arduino Zero Node debugger stop') self._in_debug = False return self.openocd.debug_stop() @staticmethod def status(): """ Check Arduino Zero node status """ # Status is called when open node is not powered # So can't check for FTDI return 0
def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self._rpi3_expect = None
class NodeFirefly(OpenNodeBase): """ implementation of The Zolertia Firefly open node""" TYPE = 'firefly' ELF_TARGET = ('ELFCLASS32', 'EM_ARM') TTY = '/dev/iotlab/ttyON_FIREFLY' # The tty as named in the udev rule BAUDRATE = 115200 PROGRAM_BAUDRATE = 460800 # The baudrate used to communicate with the open-node on the serial port FW_IDLE = static_path('firefly_idle.elf') # The name of the idle firmware FW_AUTOTEST = static_path('firefly_autotest.elf') # The name of the autotest firmware ALIM = '5V' # The tension of alimentation (will be 5V in most of the case) TTY_READY_DELAY = 1 FIREFLY_CONF = {'port': TTY, 'baudrate': PROGRAM_BAUDRATE} AUTOTEST_AVAILABLE = [ 'echo', 'get_time', 'get_uid', 'leds_on', 'leds_off', 'leds_blink' ] # The list of autotest available for your node. # As describe in the document, # this list must contain at least 'echo' def __init__(self): # The initialization of your class self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.cc2538 = CC2538(self.FIREFLY_CONF) @logger_call("Node firefly : Setup of firefly node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) ret_val += self.do_flash(firmware_path, toggle_redirect=False) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node firefly : Teardown of firefly node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) ret_val += self.serial_redirection.stop() ret_val += self.do_flash(None, toggle_redirect=False) return ret_val def flash(self, firmware_path=None, binary=False, offset=0): """Flash the given firmware on Firefly.""" if binary: LOGGER.error('FLASH: binary mode not supported with Firefly') return 1 if offset != 0: LOGGER.error('FLASH: flash offset is not supported with Firefly') return 1 return self.do_flash(firmware_path, True) @logger_call("Node firefly : flash of firefly node") def do_flash(self, firmware_path=None, toggle_redirect=True): """ Flash the given firmware on firefly node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on firefly: %s', firmware_path) LOGGER.info('Firmware path : %s -- Firmware idle path : %s', firmware_path, self.FW_IDLE) ret_val = 0 if toggle_redirect: ret_val += self.serial_redirection.stop() ret_val += self.cc2538.flash(firmware_path) if toggle_redirect: ret_val += self.serial_redirection.start() return ret_val @logger_call("Node firefly : reset of firefly node") def reset(self): """ Reset the firefly node using jtag """ LOGGER.info('Reset firefly node') return self.cc2538.reset() @staticmethod def status(): """ check the node status """ return 0
def __init__(self): # The initialization of your class self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.cc2538 = CC2538(self.FIREFLY_CONF)
class NodeEdbgBase(OpenNodeBase): # pylint:disable=no-member """ Open node EDBG implementation """ ELF_TARGET = ('ELFCLASS32', 'EM_ARM') TTY = '/dev/iotlab/ttyON_CMSIS_DAP' BAUDRATE = 115200 AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'get_uid', 'leds_on', 'leds_off', 'leds_blink' ] ALIM = '5V' def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self) self.edbg = Edbg() self._current_fw = None self._in_debug = False @property def programmer(self): """Returns the openocd instance of the open node.""" return self.edbg @logger_call("Node EDBG: Setup of EDBG node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ self._in_debug = False ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node EDBG: teardown of EDBG node") def teardown(self): """ Stop serial redirection and flash idle firmware """ self._in_debug = False ret_val = 0 # ON may have been stopped at the end of the experiment. # And then restarted again in cn teardown. # This leads to problem where the TTY disappears and reappears during # the first 2 seconds. So let some time if it wants to disappear first. common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) # cleanup debugger before flashing ret_val += self.debug_stop() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node EDBG: flash of edbg node") def flash(self, firmware_path=None, binary=False, offset=0): """ Flash the given firmware on EDBG node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on %s: %s', self.TYPE.upper(), firmware_path) self._current_fw = firmware_path if self._in_debug: return self.openocd.flash(firmware_path, binary, offset) return self.edbg.flash(firmware_path, binary, offset) @logger_call("Node EDBG: reset of EDBG node") def reset(self): """ Reset the EDBG node using jtag """ LOGGER.info('Reset %s node', self.TYPE.upper()) return self.openocd.reset() def debug_start(self): """ Start EDBG node debugger """ LOGGER.info('%s Node debugger start', self.TYPE.upper()) self._in_debug = True if self._current_fw is not None: # Reflash current firmware using openocd to avoid misbehavior of # previously flashed firmware (with edbg) self.flash(firmware_path=self._current_fw) return self.openocd.debug_start() def debug_stop(self): """ Stop EDBG node debugger """ LOGGER.info('%s Node debugger stop', self.TYPE.upper()) self._in_debug = False return self.openocd.debug_stop() @staticmethod def status(): """ Check EDBG node status """ # Status is called when open node is not powered # So can't check for FTDI return 0
def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = self.OPENOCD_CLASS.from_node(self)
class NodeFox(object): """ Open node FOX implemention """ # Contrary to m3 node, fox node need some time to be visible. # Also flash/reset may fail after a node start_dc but don't care TYPE = 'fox' ELF_TARGET = ('ELFCLASS32', 'EM_ARM') TTY = '/dev/iotlab/ttyON_FOX' BAUDRATE = 500000 OPENOCD_CFG_FILE = static_path('iot-lab-fox.cfg') OPENOCD_OPTS = ('target/stm32f1x.cfg', ) FW_IDLE = static_path('fox_idle.elf') FW_AUTOTEST = static_path('fox_autotest.elf') AUTOTEST_AVAILABLE = [ 'echo', 'get_time', # mandatory 'get_uid', 'get_accelero', 'get_gyro', 'get_magneto', 'radio_pkt', 'radio_ping_pong', 'leds_on', 'leds_off', 'leds_blink', # 'leds_consumption', not precise enough # (0.886405, [0.886405, 0.886405, 0.886405, 0.887015]) ] ALIM = '5V' def __init__(self): self.serial_redirection = SerialRedirection(self.TTY, self.BAUDRATE) self.openocd = OpenOCD.from_node(self) @logger_call("Node Fox : Setup of fox node") def setup(self, firmware_path): """ Flash open node, create serial redirection """ ret_val = 0 common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) ret_val += self.flash(firmware_path) ret_val += self.serial_redirection.start() return ret_val @logger_call("Node Fox : teardown of fox node") def teardown(self): """ Stop serial redirection and flash idle firmware """ ret_val = 0 # ON may have been stopped at the end of the experiment. # And then restarted again in cn teardown. # This leads to problem where the TTY disappears and reappears during # the first 2 seconds. So let some time if it wants to disappear first. common.wait_no_tty(self.TTY) ret_val += common.wait_tty(self.TTY, LOGGER) # cleanup debugger before flashing ret_val += self.debug_stop() ret_val += self.serial_redirection.stop() ret_val += self.flash(None) return ret_val @logger_call("Node Fox : flash of fox node") def flash(self, firmware_path=None): """ Flash the given firmware on FOX node :param firmware_path: Path to the firmware to be flashed on `node`. If None, flash 'idle' firmware. """ firmware_path = firmware_path or self.FW_IDLE LOGGER.info('Flash firmware on FOX: %s', firmware_path) return self.openocd.flash(firmware_path) @logger_call("Node Fox : reset of fox node") def reset(self): """ Reset the FOX node using jtag """ LOGGER.info('Reset FOX node') return self.openocd.reset() def debug_start(self): """ Start FOX node debugger """ LOGGER.info('FOX Node debugger start') return self.openocd.debug_start() def debug_stop(self): """ Stop FOX node debugger """ LOGGER.info('FOX Node debugger stop') return self.openocd.debug_stop() @staticmethod def status(): """ Check FOX node status """ # Status is called when open node is not powered # So can't check for FTDI return 0