#!/usr/bin/perl use strict; use warnings; use Device::SerialPort; my $port; my $debug=0; # Wait for a string on the serial port sub port_wait { my $count; my $data; my $str = ''; while(1) { ($count, $data) = $port->read(1); $str .= $data; $str =~ /$_[0]$/m and last; }; $str =~ s/\r/\n/g; if ($debug) { my $newstr = $str; $newstr =~ s/\r/\nRX: /g; print "RX: $newstr\n"; } return $str; } # Write a string sub port_write { if ($debug) { my $str=$_[0]; $str =~ s/\r/\nTX: /gm; print "TX: $str\n"; } $port->write($_[0]); } # Read a line sub port_readline { my $str = port_wait("\r"); chomp($str); return $str; } # Read all pending data sub port_flush { # nop for now #while ( port_readline() ) { }; } # Write a string and wait for a response sub port_write_wait { port_write($_[0]); return port_wait($_[1]); } # setup serial port $port = new Device::SerialPort("/dev/ttyUSB0", 0) || die "cannot open serial device: $!\n"; $port->baudrate(115200); $port->databits(8); $port->stopbits(1); $port->parity('none'); $port->datatype('raw'); $port->debug(999); # wait for boot loader print "# Please turn on or power cycle the BR6101 device.\n"; port_wait('key to enter command mode'); print "# Entering boot loader.\n"; port_write_wait("\r", "BRN"); # enter administration mode print "# Entering administration mode.\n"; port_write_wait("!", "Enter Administrator Mode"); # get data dump print "# Dumping data.\n"; open(FF, '>firmware.dump'); binmode(FF); my $chunksize = 0x100; for (my $addr=0; $addr<0x00100000; $addr+=$chunksize) { # Enter command my $addrstr = sprintf("%x", $addr); port_write_wait("r", "Start Address"); port_write_wait("$addrstr\r", "Data Length"); port_write_wait("3", "Count"); port_write_wait("$chunksize\r", "----------------\r"); port_wait("----------\r"); # Print and write data while(1) { my $data = port_readline(); $data =~ s/^0x04//; print $data; if ($data =~ /^\s*([0-9a-zA-Z]+)\s(.*)$/) { # also write to binary file my @elements = split(/ /, $2); foreach my $el (@elements) { $el ne '' and print FF pack("H2", $el); } # stop when last line was processed last if ( hex($1) >= ($addr+$chunksize-0x10) ); } } } close(FF); $port->close();