Example #1
0
def prepare_can_iface():
    if '/' not in args.iface:
        logger.debug('Using iface %r as SocketCAN', args.iface)
        execute_shell_command(
            'ifconfig %s down && ip link set %s up type can bitrate %d sample-point 0.875',
            args.iface, args.iface, CAN_BITRATE)
    else:
        logger.debug('Using iface %r as SLCAN', args.iface)
        # We don't want the SLCAN daemon to interfere...
        execute_shell_command('killall -INT slcand &> /dev/null',
                              ignore_failure=True)
        time.sleep(1)
        # Making sure the interface can be open
        with open(args.iface, 'bw') as _f:
            pass
Example #2
0
def load_firmware(firmware_data):
    with tempfile.TemporaryDirectory('-drwatson') as tmpdir:
        logger.debug('Executable scratchpad directory: %r', tmpdir)
        fn = lambda x: os.path.join(tmpdir, x)
        runtc = lambda fmt, *a, **kw: execute_shell_command(
            TOOLCHAIN_PREFIX + fmt, *a, **kw)

        # Generating ELF from the downloaded binary
        with open(fn('fw.bin'), 'wb') as f:
            f.write(firmware_data)

        with open(fn('link.ld'), 'w') as f:
            f.write('SECTIONS { . = %s; .text : { *(.text) } }' % FLASH_OFFSET)

        runtc('ld -b binary -r -o %s %s', fn('tmp.elf'), fn('fw.bin'))
        runtc(
            'objcopy --rename-section .data=.text --set-section-flags .data=alloc,code,load %s',
            fn('tmp.elf'))
        runtc('ld %s -T %s -o %s', fn('tmp.elf'), fn('link.ld'),
              fn('output.elf'))

        # Loading the ELF onto the target
        with open(fn('script.gdb'), 'w') as f:
            f.write('\n'.join([
                'target extended-remote %s' % glob_one(DEBUGGER_PORT_GDB_GLOB),
                'mon swdp_scan', 'attach 1', 'load', 'compare-sections',
                'kill', 'quit 0'
            ]))

        runtc('gdb %s --batch -x %s -return-child-result -silent',
              fn('output.elf'), fn('script.gdb'))
Example #3
0
def load_firmware(firmware_data):
    with tempfile.TemporaryDirectory('-drwatson') as tmpdir:
        logger.debug('Executable scratchpad directory: %r', tmpdir)
        fn = lambda x: os.path.join(tmpdir, x)
        runtc = lambda fmt, *a, **kw: execute_shell_command(TOOLCHAIN_PREFIX + fmt, *a, **kw)

        # Generating ELF from the downloaded binary
        with open(fn('fw.bin'), 'wb') as f:
            f.write(firmware_data)

        with open(fn('link.ld'), 'w') as f:
            f.write('SECTIONS { . = %s; .text : { *(.text) } }' % FLASH_OFFSET)

        runtc('ld -b binary -r -o %s %s', fn('tmp.elf'), fn('fw.bin'))
        runtc('objcopy --rename-section .data=.text --set-section-flags .data=alloc,code,load %s', fn('tmp.elf'))
        runtc('ld %s -T %s -o %s', fn('tmp.elf'), fn('link.ld'), fn('output.elf'))

        # Loading the ELF onto the target
        with open(fn('script.gdb'), 'w') as f:
            f.write('\n'.join([
                'target extended-remote %s' % glob_one(DEBUGGER_PORT_GDB_GLOB),
                'mon swdp_scan',
                'attach 1',
                'load',
                #'compare-sections',    # Commented out because this command breaks the GDB session on GDB 8.x. Why tho?
                'kill',
                'quit 0'
            ]))

        runtc('gdb %s --batch -x %s -return-child-result -silent', fn('output.elf'), fn('script.gdb'))
def load_firmware(firmware_data):
    with tempfile.TemporaryDirectory("-drwatson") as tmpdir:
        logger.debug("Executable scratchpad directory: %r", tmpdir)
        fn = lambda x: os.path.join(tmpdir, x)
        runtc = lambda fmt, *a, **kw: execute_shell_command(TOOLCHAIN_PREFIX + fmt, *a, **kw)

        # Generating ELF from the downloaded binary
        with open(fn("fw.bin"), "wb") as f:
            f.write(firmware_data)

        with open(fn("link.ld"), "w") as f:
            f.write("SECTIONS { . = %s; .text : { *(.text) } }" % FLASH_OFFSET)

        runtc("ld -b binary -r -o %s %s", fn("tmp.elf"), fn("fw.bin"))
        runtc("objcopy --rename-section .data=.text --set-section-flags .data=alloc,code,load %s", fn("tmp.elf"))
        runtc("ld %s -T %s -o %s", fn("tmp.elf"), fn("link.ld"), fn("output.elf"))

        # Loading the ELF onto the target
        with open(fn("script.gdb"), "w") as f:
            f.write(
                "\n".join(
                    [
                        "target extended-remote %s" % glob_one(DEBUGGER_PORT_GDB_GLOB),
                        "mon swdp_scan",
                        "attach 1",
                        "load",
                        "compare-sections",
                        "kill",
                        "quit 0",
                    ]
                )
            )

        runtc("gdb %s --batch -x %s -return-child-result -silent", fn("output.elf"), fn("script.gdb"))
Example #5
0
def process_one_device(set_device_info):
    execute_shell_command('ifconfig %s down && ifconfig %s up', args.iface,
                          args.iface)

    if not args.only_sign:
        # Flashing firmware without signature
        with closing(bootloader.BootloaderInterface(args.iface)) as bli:
            input('\n'.join([
                '1. Set PIO0_3 low, PIO0_1 low (J4 closed, J3 open)',
                '2. Power on the device and connect it to CAN bus',
                '3. Press ENTER'
            ]))

            with CLIWaitCursor():
                load_and_start_firmware(bli, firmware_base)

        # Testing the device
        input('\n'.join([
            '1. Make sure that LED indicators are blinking',
            '2. Test button operation', '3. Press ENTER'
        ]))

    # Installing signature
    with closing(bootloader.BootloaderInterface(args.iface)) as bli:
        info("Now we're going to sign the device")
        input('\n'.join([
            '1. Set PIO0_3 low, PIO0_1 low (J4 closed, J3 open)',
            '2. Reset the device (e.g. cycle power)', '3. Press ENTER'
        ]))

        with CLIWaitCursor():
            info('Reading unique ID...')
            unique_id = bli.read_unique_id()
            set_device_info(PRODUCT_NAME, unique_id)

            info('Requesting signature for unique ID %s',
                 ' '.join(['%02x' % x for x in unique_id]))
            gensign_response = api.generate_signature(unique_id, PRODUCT_NAME)

            info(
                'Signature has been generated successfully [%s], patching the firmware...',
                ['existing', 'NEW'][gensign_response.new])
            firmware_with_signature = firmware_base.ljust(
                SIGNATURE_OFFSET, b'\xFF') + gensign_response.signature

            load_and_start_firmware(bli, firmware_with_signature)
Example #6
0
def init_can_iface():
    if '/' not in args.iface:
        logger.debug('Using iface %r as SocketCAN', args.iface)
        execute_shell_command('ifconfig %s down && ip link set %s up type can bitrate %d sample-point 0.875',
                              args.iface, args.iface, CAN_BITRATE)
        return args.iface
    else:
        logger.debug('Using iface %r as SLCAN', args.iface)

        # We don't want the SLCAN daemon to interfere...
        execute_shell_command('killall -INT slcand &> /dev/null', ignore_failure=True)
        time.sleep(1)

        # Making sure the interface can be open
        with open(args.iface, 'bw') as _f:
            pass

        return args.iface
Example #7
0
def process_one_device(set_device_info):
    execute_shell_command('ifconfig %s down && ifconfig %s up', args.iface, args.iface)

    if not args.only_sign:
        # Flashing firmware without signature
        with closing(bootloader.BootloaderInterface(args.iface)) as bli:
            input('\n'.join(['1. Set PIO0_3 low, PIO0_1 low (J4 closed, J3 open)',
                             '2. Power on the device and connect it to CAN bus',
                             '3. Press ENTER']))

            with CLIWaitCursor():
                load_and_start_firmware(bli, firmware_base)

        # Testing the device
        input('\n'.join(['1. Make sure that LED indicators are blinking',
                         '2. Test button operation',
                         '3. Press ENTER']))

    # Installing signature
    with closing(bootloader.BootloaderInterface(args.iface)) as bli:
        info("Now we're going to sign the device")
        input('\n'.join(['1. Set PIO0_3 low, PIO0_1 low (J4 closed, J3 open)',
                         '2. Reset the device (e.g. cycle power)',
                         '3. Press ENTER']))

        with CLIWaitCursor():
            info('Reading unique ID...')
            unique_id = bli.read_unique_id()
            set_device_info(PRODUCT_NAME, unique_id)

            info('Requesting signature for unique ID %s', ' '.join(['%02x' % x for x in unique_id]))
            gensign_response = api.generate_signature(unique_id, PRODUCT_NAME)

            info('Signature has been generated successfully [%s], patching the firmware...',
                 ['existing', 'NEW'][gensign_response.new])
            firmware_with_signature = firmware_base.ljust(SIGNATURE_OFFSET, b'\xFF') + gensign_response.signature

            load_and_start_firmware(bli, firmware_with_signature)
Example #8
0
        f.write(firmware_with_signature)
    os.chmod(image_name, 0o666)
    info('Signed image stored into %r', image_name)


with CLIWaitCursor():
    firmware_base = download(args.firmware)
    assert 0 < len(firmware_base) <= SIGNATURE_OFFSET, 'Firmware size is incorrect'

if args.generate_signed_image_for:
    generate_signed_image_for(args.generate_signed_image_for)
    exit(0)

if not args.iface:
    fatal('Iface is required')
execute_shell_command('ifconfig %s down && ip link set %s up type can bitrate %d sample-point 0.875',
                      args.iface, args.iface, bootloader.CAN_BITRATE, ignore_failure=True)


def load_and_start_firmware(bootloader_interface, firmware_image):
    while True:
        try:
            info('Flashing the firmware [%d bytes]...', len(firmware_image))
            bootloader_interface.unlock()
            bootloader_interface.load_firmware(firmware_image)
        except Exception as ex:
            error('Flashing failed: %r', ex)
            if not input('Try harder?', yes_no=True):
                abort('Flashing failed')
        else:
            input('Set PIO0_1 high (J4 open), then press ENTER')
            info('Starting the firmware...')
Example #9
0

with CLIWaitCursor():
    firmware_base = download(args.firmware)
    assert 0 < len(
        firmware_base) <= SIGNATURE_OFFSET, 'Firmware size is incorrect'

if args.generate_signed_image_for:
    generate_signed_image_for(args.generate_signed_image_for)
    exit(0)

if not args.iface:
    fatal('Iface is required')
execute_shell_command(
    'ifconfig %s down && ip link set %s up type can bitrate %d sample-point 0.875',
    args.iface,
    args.iface,
    bootloader.CAN_BITRATE,
    ignore_failure=True)


def load_and_start_firmware(bootloader_interface, firmware_image):
    while True:
        try:
            info('Flashing the firmware [%d bytes]...', len(firmware_image))
            bootloader_interface.unlock()
            bootloader_interface.load_firmware(firmware_image)
        except Exception as ex:
            error('Flashing failed: %r', ex)
            if not input('Try harder?', yes_no=True):
                abort('Flashing failed')
        else:
def init_can_iface():
    if '/' not in args.iface:
        logger.debug('Using iface %r as SocketCAN', args.iface)
        execute_shell_command(
            'ifconfig %s down && ip link set %s up type can bitrate %d sample-point 0.875',
            args.iface, args.iface, CAN_BITRATE)
        return args.iface
    else:
        logger.debug('Using iface %r as SLCAN', args.iface)

        speed_code = {
            1000000: 8,
            500000: 6,
            250000: 5,
            125000: 4,
            100000: 3
        }[CAN_BITRATE]

        execute_shell_command('killall -INT slcand &> /dev/null',
                              ignore_failure=True)
        time.sleep(1)

        tty = os.path.realpath(args.iface).replace('/dev/', '')
        logger.debug('TTY %r', tty)

        execute_shell_command('slcan_attach -f -o -s%d /dev/%s', speed_code,
                              tty)
        execute_shell_command('slcand %s', tty)

        iface_name = 'slcan0'
        time.sleep(1)
        execute_shell_command('ifconfig %s up', iface_name)
        execute_shell_command('ifconfig %s txqueuelen 1000', iface_name)

        return iface_name
def init_can_iface():
    if "/" not in args.iface:
        logger.debug("Using iface %r as SocketCAN", args.iface)
        execute_shell_command(
            "ifconfig %s down && ip link set %s up type can bitrate %d sample-point 0.875",
            args.iface,
            args.iface,
            CAN_BITRATE,
        )
        return args.iface
    else:
        logger.debug("Using iface %r as SLCAN", args.iface)

        speed_code = {1000000: 8, 500000: 6, 250000: 5, 125000: 4, 100000: 3}[CAN_BITRATE]

        execute_shell_command("killall -INT slcand &> /dev/null", ignore_failure=True)
        time.sleep(1)

        tty = os.path.realpath(args.iface).replace("/dev/", "")
        logger.debug("TTY %r", tty)

        execute_shell_command("slcan_attach -f -o -s%d /dev/%s", speed_code, tty)
        execute_shell_command("slcand %s", tty)

        iface_name = "slcan0"
        time.sleep(1)
        execute_shell_command("ifconfig %s up", iface_name)
        execute_shell_command("ifconfig %s txqueuelen 1000", iface_name)

        return iface_name