You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

146 lines
4.2 KiB

  1. #!/usr/bin/env python3
  2. """
  3. OpenOCD RPC example, covered by GNU GPLv3 or later
  4. Copyright (C) 2014 Andreas Ortmann (ortmann@finf.uni-hannover.de)
  5. Example output:
  6. ./ocd_rpc_example.py
  7. echo says hi!
  8. target state: halted
  9. target halted due to debug-request, current mode: Thread
  10. xPSR: 0x01000000 pc: 0x00000188 msp: 0x10000fd8
  11. variable @ 0x10000000: 0x01c9c380
  12. variable @ 0x10000000: 0xdeadc0de
  13. memory (before): ['0xdeadc0de', '0x00000011', '0xaaaaaaaa', '0x00000023',
  14. '0x00000042', '0x0000ffff']
  15. memory (after): ['0x00000001', '0x00000000', '0xaaaaaaaa', '0x00000023',
  16. '0x00000042', '0x0000ffff']
  17. """
  18. import socket
  19. import itertools
  20. def strToHex(data):
  21. return map(strToHex, data) if isinstance(data, list) else int(data, 16)
  22. def hexify(data):
  23. return "<None>" if data is None else ("0x%08x" % data)
  24. def compareData(a, b):
  25. for i, j, num in zip(a, b, itertools.count(0)):
  26. if i != j:
  27. print("difference at %d: %s != %s" % (num, hexify(i), hexify(j)))
  28. class OpenOcd:
  29. COMMAND_TOKEN = '\x1a'
  30. def __init__(self, verbose=False):
  31. self.verbose = verbose
  32. self.tclRpcIp = "127.0.0.1"
  33. self.tclRpcPort = 6666
  34. self.bufferSize = 4096
  35. self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  36. def __enter__(self):
  37. self.sock.connect((self.tclRpcIp, self.tclRpcPort))
  38. return self
  39. def __exit__(self, type, value, traceback):
  40. try:
  41. self.send("exit")
  42. finally:
  43. self.sock.close()
  44. def send(self, cmd):
  45. """Send a command string to TCL RPC. Return the result that was read."""
  46. data = (cmd + OpenOcd.COMMAND_TOKEN).encode("utf-8")
  47. if self.verbose:
  48. print("<- ", data)
  49. self.sock.send(data)
  50. return self._recv()
  51. def _recv(self):
  52. """Read from the stream until the token (\x1a) was received."""
  53. data = bytes()
  54. while True:
  55. chunk = self.sock.recv(self.bufferSize)
  56. data += chunk
  57. if bytes(OpenOcd.COMMAND_TOKEN, encoding="utf-8") in chunk:
  58. break
  59. if self.verbose:
  60. print("-> ", data)
  61. data = data.decode("utf-8").strip()
  62. data = data[:-1] # strip trailing \x1a
  63. return data
  64. def readVariable(self, address):
  65. raw = self.send("ocd_mdw 0x%x" % address).split(": ")
  66. return None if (len(raw) < 2) else strToHex(raw[1])
  67. def readMemory(self, wordLen, address, n):
  68. self.send("array unset output") # better to clear the array before
  69. self.send("mem2array output %d 0x%x %d" % (wordLen, address, n))
  70. output = self.send("ocd_echo $output").split(" ")
  71. return [int(output[2*i+1]) for i in range(len(output)//2)]
  72. def writeVariable(self, address, value):
  73. assert value is not None
  74. self.send("mww 0x%x 0x%x" % (address, value))
  75. def writeMemory(self, wordLen, address, n, data):
  76. array = " ".join(["%d 0x%x" % (a, b) for a, b in enumerate(data)])
  77. self.send("array unset 1986ве1т") # better to clear the array before
  78. self.send("array set 1986ве1т { %s }" % array)
  79. self.send("array2mem 1986ве1т 0x%x %s %d" % (wordLen, address, n))
  80. if __name__ == "__main__":
  81. def show(*args):
  82. print(*args, end="\n\n")
  83. with OpenOcd() as ocd:
  84. ocd.send("reset")
  85. show(ocd.send("ocd_echo \"echo says hi!\"")[:-1])
  86. show(ocd.send("capture \"ocd_halt\"")[:-1])
  87. # Read the first few words at the RAM region (put starting adress of RAM
  88. # region into 'addr')
  89. addr = 0x10000000
  90. value = ocd.readVariable(addr)
  91. show("variable @ %s: %s" % (hexify(addr), hexify(value)))
  92. ocd.writeVariable(addr, 0xdeadc0de)
  93. show("variable @ %s: %s" % (hexify(addr), hexify(ocd.readVariable(addr))))
  94. data = [1, 0, 0xaaaaaaaa, 0x23, 0x42, 0xffff]
  95. wordlen = 32
  96. n = len(data)
  97. read = ocd.readMemory(wordlen, addr, n)
  98. show("memory (before):", list(map(hexify, read)))
  99. ocd.writeMemory(wordlen, addr, n, data)
  100. read = ocd.readMemory(wordlen, addr, n)
  101. show("memory (after):", list(map(hexify, read)))
  102. compareData(read, data)
  103. ocd.send("resume")