aboutsummaryrefslogtreecommitdiff
path: root/projects/cli-test
AgeCommit message (Expand)Author
2016-06-25Split LIB*_DIR into _SRC and _BLD.Paul Selkirk
2016-06-16Merge branch 'master' into ft-ks_flashFredrik Thulin
2016-06-13Only the HSM project needs the RTOS; most of the test projects can use the ST...Paul Selkirk
2016-06-09Put all the keystore commands under 'keystore' instead.Fredrik Thulin
2016-06-09updated test-code for keystore functionalityFredrik Thulin
2016-06-08Include strings.h, for strcasecmp().Rob Austein
2016-06-08Test code for ks_flash in corresponding branch of libhal.Fredrik Thulin
2016-06-07Don't reboot when CLI logout is intended.Paul Selkirk
2016-06-02Use DMA for UART RX instead of interrupts.Fredrik Thulin
2016-06-02Move the rest of the CLI commands out of cli-test.c.Fredrik Thulin
2016-06-01Implement circular buffer UART RX using interrupts.Fredrik Thulin
2016-06-01Move FPGA related commands to mgmt-fpga.cFredrik Thulin
2016-05-27DFU working - but no signature validation for now.Fredrik Thulin
2016-05-27cli_command_root_node: bugfix missing command callbackFredrik Thulin
2016-05-26Implement a bootloader.Fredrik Thulin
2016-05-25More DFU code. This might actually work.Fredrik Thulin
2016-05-24non-working code to upload an application and jump to itFredrik Thulin
2016-05-24make 'test sdram' take number of iterations as argumentFredrik Thulin
2016-05-23SDRAM initialization and test code from Pavel.Fredrik Thulin
2016-05-21Add code to test reading, writing and erasing keystore data.Fredrik Thulin
2016-05-21Add code to access the keystore memory (SPI flash).Fredrik Thulin
2016-05-21Add some exciting defines to define commans in the CLI.Fredrik Thulin
2016-05-20Add code to reset FPGA using FPGA_PROGRAM_B and FPGA_INIT_B.Fredrik Thulin
2016-05-19Refactor FPGA bitstream upload code.Fredrik Thulin
2016-05-18Add FPGA bitstream upload command to cli-test.Fredrik Thulin
2016-05-18A little more robust file transferFredrik Thulin
2016-05-18put some generic CLI code in mgmt-cli.cFredrik Thulin
2016-05-18Add reboot command.Fredrik Thulin
2016-05-18Write in 4k-chunks, with acks for flow control.Fredrik Thulin
2016-05-18build libcliPaul Selkirk
2016-05-16Use baud rate 921600 instead of 115200.Fredrik Thulin
2016-05-15add simple filetransfer pocFredrik Thulin
2016-05-13Add test program for libcli based CLI.Fredrik Thulin
: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#!/usr/bin/python
#
# Copyright (c) 2016, NORDUnet A/S All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# - Redistributions of source code must retain the above copyright notice,
#   this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in the
#   documentation and/or other materials provided with the distribution.
#
# - Neither the name of the NORDUnet nor the names of its contributors may
#   be used to endorse or promote products derived from this software
#   without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
Utility to transfer a new firmware to the bootloader.

Example usage:

   ./bin/dfu path/to/firmware.bin

Then reset the Cryptech Alpha board.
"""
import os
import sys
import time
import struct
import serial
import argparse

from binascii import crc32

CHUNK_SIZE = 4096


def parse_args():
    """
    Parse the command line arguments
    """
    parser = argparse.ArgumentParser(description = "Device firmware upgrader",
                                     add_help = True,
                                     formatter_class = argparse.ArgumentDefaultsHelpFormatter,
                                     )

    parser.add_argument('--verbose',
                        dest='verbose',
                        action='store_true', default=False,
                        help='Verbose operation',
                        )

    parser.add_argument('--device',
                        dest='device',
                        default='/dev/ttyUSB0',
                        help='Name of management port USB serial device',
                        )

    # positional argument(s)
    parser.add_argument('filename')

    return parser.parse_args()


def _write(dst, data):
    for i in range(len(data)):
        dst.write(data[i])
        time.sleep(0.1)
    if len(data) == 4:
        print("Wrote 0x{:02x}{:02x}{:02x}{:02x}".format(ord(data[0]), ord(data[1]), ord(data[2]), ord(data[3])))
    else:
        print("Wrote {!r}".format(data))


def _read(dst, verbose=False):
    res = ''
    while True:
        x = dst.read(1)
        if not x:
            break
        res += x
    if res and verbose:
        print ("Read {!r}".format(res))
    return res


def send_file(filename, args):
    s = os.stat(filename)
    size = s.st_size
    src = open(filename, 'rb')
    chunk_size = CHUNK_SIZE

    print("Waiting for contact with the bootloader on device {!s}, reset the CrypTech Alpha...".format(args.device))

    while True:
        try:
            dst = serial.Serial(args.device, 921600, timeout=0.1)
        except serial.SerialException:
            time.sleep(0.2)
            continue
        dst.write('\r')
        response = _read(dst, args.verbose)
        if 'OK' in response:
            dst.timeout=2
            break

    print('\nUploading firmware\n')

    crc = 0
    counter = 0
    # 1. Write size of file (4 bytes)
    _write(dst, struct.pack('<I', size))
    _read(dst, args.verbose)
    # 2. Write file contents while calculating CRC-32
    while True:
        data = src.read(chunk_size)
        if not data:
            break
        dst.write(data)
        print("Wrote {!s} bytes (chunk {!s}/{!s})".format(len(data), counter, int(size / chunk_size)))
        # read ACK (a counter of number of 4k chunks received)
        while True:
            ack_bytes = dst.read(4)
            if len(ack_bytes) == 4:
                break
            print('ERROR: Did not receive an ACK, got {!r}'.format(ack_bytes))
            dst.write('\r')  # eventually get back to the CLI prompt
        ack = struct.unpack('<I', ack_bytes)[0]
        if ack != counter + 1:
            print('ERROR: Did not receive the expected counter as ACK (got {!r}/{!r}, not {!r})'.format(ack, ack_bytes, counter))
            flush = dst.read(100)
            print('FLUSH data: {!r}'.format(flush))
            return False
        counter += 1

        crc = crc32(data, crc) & 0xffffffff

    _read(dst, args.verbose)

    # 3. Write CRC-32 (4 bytes)
    _write(dst, struct.pack('<I', crc))

    if args.verbose:
        print('\nFinished - this command might hang now depending on the firmware loaded')
        _read(dst, args.verbose)
    else:
        print('\nFinished uploading firmware')

    src.close()
    dst.close()
    return True


def main(args):
    send_file(args.filename, args)
    return True

if __name__ == '__main__':
    try:
        args = parse_args()
        if main(args):
            sys.exit(0)
        sys.exit(1)
    except KeyboardInterrupt:
        pass