summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2018-02-24 16:01:19 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2018-03-01 09:39:42 +0100
commitbfcdef33add4f58ebd7f6a9621c94b1fb2caabd5 (patch)
tree0d97784763bcaae6059e405673bfaae3d45f880d /scripts
parent706328c33fc8e9e680f37ee4cdac9ecbf3127f23 (diff)
downloadbarebox-bfcdef33add4f58ebd7f6a9621c94b1fb2caabd5.tar.gz
barebox-bfcdef33add4f58ebd7f6a9621c94b1fb2caabd5.tar.xz
ratp: new md and mw commands
This commit introduces support for running the md and mw commands using the binary interface provided by RATP. This allows clients to read and write memory files without needing to do custom string parsing on the data returned by the console 'md' and 'mw' operations. The request and response messages used for these new operations are structured in the same way: * An initial fixed-sized section includes the fixed-sized variables (e.g. integers), as well as the size and offset of the variable-length variables. * After the initial fixed-sized section, the buffer is given, which contains the variable-length variables in the offsets previously defined and with the size previously defined. The message also defines separately the offset of the buffer w.r.t. the start of the message. The endpoint reading the message will use this information to decide where the buffer starts. This allows to extend the message format in the future without needing to break the message API, as new fields can be appended to the fixed-sized section as long as the buffer offset is also updated to report the new position of the buffer. E.g.: $ ./bbremote --port /dev/ttyUSB2 md /dev/pic_eeprom_rdu 0x107 5 0000000000 $ ./bbremote --port /dev/ttyUSB2 mw /dev/pic_eeprom_rdu 0x107 0102030405 5 bytes written $ ./bbremote --port /dev/ttyUSB2 md /dev/pic_eeprom_rdu 0x107 5 0102030405 $ ./bbremote --port /dev/ttyUSB2 mw /dev/pic_eeprom_rdu 0x107 0000000000 5 bytes written $ ./bbremote --port /dev/ttyUSB2 md /dev/pic_eeprom_rdu 0x107 5 0000000000 Signed-off-by: Aleksander Morgado <aleksander@aleksander.es> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/remote/controller.py24
-rw-r--r--scripts/remote/main.py38
-rw-r--r--scripts/remote/messages.py89
3 files changed, 151 insertions, 0 deletions
diff --git a/scripts/remote/controller.py b/scripts/remote/controller.py
index a7257ecc97..eaab9f8f6b 100644
--- a/scripts/remote/controller.py
+++ b/scripts/remote/controller.py
@@ -46,6 +46,18 @@ def unpack(data):
elif p_type == BBType.fs_return:
logging.debug("received: fs_return")
return BBPacketFSReturn(raw=data)
+ elif p_type == BBType.md:
+ logging.debug("received: md")
+ return BBPacketMd(raw=data)
+ elif p_type == BBType.md_return:
+ logging.debug("received: md_return")
+ return BBPacketMdReturn(raw=data)
+ elif p_type == BBType.mw:
+ logging.debug("received: mw")
+ return BBPacketMw(raw=data)
+ elif p_type == BBType.mw_return:
+ logging.debug("received: mw_return")
+ return BBPacketMwReturn(raw=data)
else:
logging.debug("received: UNKNOWN")
return BBPacket(raw=data)
@@ -112,6 +124,18 @@ class Controller(Thread):
r = self._expect(BBPacketGetenvReturn)
return r.text
+ def md(self, path, addr, size):
+ self._send(BBPacketMd(path=path, addr=addr, size=size))
+ r = self._expect(BBPacketMdReturn)
+ logging.info("Md return: %r", r)
+ return (r.exit_code,r.data)
+
+ def mw(self, path, addr, data):
+ self._send(BBPacketMw(path=path, addr=addr, data=data))
+ r = self._expect(BBPacketMwReturn)
+ logging.info("Mw return: %r", r)
+ return (r.exit_code,r.written)
+
def close(self):
self.conn.close()
diff --git a/scripts/remote/main.py b/scripts/remote/main.py
index 79203df05a..29f601e9f8 100644
--- a/scripts/remote/main.py
+++ b/scripts/remote/main.py
@@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function
import sys
import os
import argparse
+import binascii
import logging
from Queue import Queue
from .ratp import RatpError
@@ -76,6 +77,27 @@ def handle_getenv(args):
return res
+def handle_md(args):
+ ctrl = get_controller(args)
+ (res,data) = ctrl.md(args.path, args.address, args.size)
+ if res == 0:
+ print(binascii.hexlify(data))
+ ctrl.close()
+ return res
+
+
+def handle_mw(args):
+ ctrl = get_controller(args)
+ data=args.data
+ if ((len(data) % 2) != 0):
+ data="0"+data
+ (res,written) = ctrl.mw(args.path, args.address, binascii.unhexlify(data))
+ if res == 0:
+ print("%i bytes written" % written)
+ ctrl.close()
+ return res
+
+
def handle_listen(args):
port = serial.serial_for_url(args.port, args.baudrate)
conn = SerialRatpConnection(port)
@@ -118,6 +140,10 @@ def handle_console(args):
ctrl.conn.total_retransmits,
ctrl.conn.total_crc_errors))
+# Support base 10 or base 16 numbers automatically
+def auto_int(x):
+ return int(x, 0)
+
VERBOSITY = {
0: logging.WARN,
1: logging.INFO,
@@ -143,6 +169,18 @@ parser_getenv = subparsers.add_parser('getenv', help="get a barebox environment
parser_getenv.add_argument('arg', nargs='+', help="variable name")
parser_getenv.set_defaults(func=handle_getenv)
+parser_md = subparsers.add_parser('md', help="run md command")
+parser_md.add_argument('path', help="path")
+parser_md.add_argument('address', type=auto_int, help="address")
+parser_md.add_argument('size', type=auto_int, help="size")
+parser_md.set_defaults(func=handle_md)
+
+parser_mw = subparsers.add_parser('mw', help="run mw command")
+parser_mw.add_argument('path', help="path")
+parser_mw.add_argument('address', type=auto_int, help="address")
+parser_mw.add_argument('data', help="data")
+parser_mw.set_defaults(func=handle_mw)
+
parser_listen = subparsers.add_parser('listen', help="listen for an incoming connection")
parser_listen.set_defaults(func=handle_listen)
diff --git a/scripts/remote/messages.py b/scripts/remote/messages.py
index 8e8495b12e..4f4d8e97f8 100644
--- a/scripts/remote/messages.py
+++ b/scripts/remote/messages.py
@@ -4,6 +4,7 @@
from __future__ import absolute_import, division, print_function
import struct
+import binascii
class BBType(object):
@@ -16,6 +17,10 @@ class BBType(object):
getenv_return = 7
fs = 8
fs_return = 9
+ md = 10
+ md_return = 11
+ mw = 12
+ mw_return = 13
class BBPacket(object):
@@ -152,3 +157,87 @@ class BBPacketFSReturn(BBPacket):
def __repr__(self):
return "BBPacketFSReturn(payload=%r)" % self.payload
+
+
+class BBPacketMd(BBPacket):
+ def __init__(self, raw=None, path=None, addr=None, size=None):
+ self.path = path
+ self.addr = addr
+ self.size = size
+ super(BBPacketMd, self).__init__(BBType.md, raw=raw)
+
+ def __repr__(self):
+ return "BBPacketMd(path=%r,addr=0x%x,size=%u)" % (self.path, self.addr, self.size)
+
+ def _unpack_payload(self, payload):
+ buffer_offset, self.addr, self.size, path_size, path_offset = struct.unpack("!HHHHH", payload[:10])
+ # header size is always 4 bytes (HH), so adjust the absolute data offset without the header size
+ absolute_path_offset = buffer_offset + path_offset - 4
+ self.path = payload[absolute_path_offset:absolute_path_offset+path_size]
+
+ def _pack_payload(self):
+ # header size is always 4 bytes (HH) and we have 10 bytes of fixed data (HHHHH), so buffer offset is 14
+ return struct.pack("!HHHHH%ds" % len(self.path), 14, self.addr, self.size, len(self.path), 0, self.path)
+
+
+class BBPacketMdReturn(BBPacket):
+ def __init__(self, raw=None, exit_code=None, data=None):
+ self.exit_code = exit_code
+ self.data = data
+ super(BBPacketMdReturn, self).__init__(BBType.md_return, raw=raw)
+
+ def __repr__(self):
+ return "BBPacketMdReturn(exit_code=%i, data=%s)" % (self.exit_code, binascii.hexlify(self.data))
+
+ def _unpack_payload(self, payload):
+ buffer_offset, self.exit_code, data_size, data_offset = struct.unpack("!HLHH", payload[:10])
+ # header size is always 4 bytes (HH), so adjust the absolute data offset without the header size
+ absolute_data_offset = buffer_offset + data_offset - 4
+ self.data = payload[absolute_data_offset:absolute_data_offset + data_size]
+
+ def _pack_payload(self):
+ # header size is always 4 bytes (HH) and we have 10 bytes of fixed data (HLHH), so buffer offset is 14
+ return struct.pack("!HLHH%ds" % len(self.data), 14, self.exit_code, len(self.data), 0, self.data)
+ return self.text
+
+
+class BBPacketMw(BBPacket):
+ def __init__(self, raw=None, path=None, addr=None, data=None):
+ self.path = path
+ self.addr = addr
+ self.data = data
+ super(BBPacketMw, self).__init__(BBType.mw, raw=raw)
+
+ def __repr__(self):
+ return "BBPacketMw(path=%r,addr=0x%x,data=%r)" % (self.path, self.addr, self.data)
+
+ def _unpack_payload(self, payload):
+ buffer_offset, self.addr, path_size, path_offset, data_size, data_offset = struct.unpack("!HHHHHH", payload[:12])
+ # header size is always 4 bytes (HH), so adjust the absolute data offset without the header size
+ absolute_path_offset = buffer_offset + path_offset - 4
+ self.path = payload[absolute_path_offset:absolute_path_offset+path_size]
+ absolute_data_offset = buffer_offset + data_offset - 4
+ self.data = payload[absolute_data_offset:absolute_data_offset+data_size]
+
+ def _pack_payload(self):
+ # header size is always 4 bytes (HH) and we have 12 bytes of fixed data (HHHHHH), so buffer offset is 16
+ path_size = len(self.path)
+ data_size = len(self.data)
+ return struct.pack("!HHHHHH%ds%ds" % (path_size, path_size), 16, self.addr, path_size, 0, data_size, path_size, self.path, self.data)
+
+
+class BBPacketMwReturn(BBPacket):
+ def __init__(self, raw=None, exit_code=None, written=None):
+ self.exit_code = exit_code
+ self.written = written
+ super(BBPacketMwReturn, self).__init__(BBType.mw_return, raw=raw)
+
+ def __repr__(self):
+ return "BBPacketMwReturn(exit_code=%i, written=%i)" % (self.exit_code, self.written)
+
+ def _unpack_payload(self, payload):
+ buffer_offset, self.exit_code, self.written = struct.unpack("!HLH", payload[:8])
+
+ def _pack_payload(self):
+ # header size is always 4 bytes (HH) and we have 8 bytes of fixed data (HLH), so buffer offset is 14
+ return struct.pack("!HLH", 12, self.exit_code, self.written)