Beispiel #1
0
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)
Beispiel #2
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
Beispiel #3
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
Beispiel #4
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
Beispiel #5
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
Beispiel #7
0
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
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
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
Beispiel #10
0
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
Beispiel #11
0
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
Beispiel #12
0
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')
Beispiel #13
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
Beispiel #14
0
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')
Beispiel #15
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
Beispiel #16
0
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
Beispiel #17
0
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
Beispiel #18
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/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