Index: embios/trunk/tools/embios.py |
— | — | @@ -1,25 +1,27 @@ |
| 2 | +#!/usr/bin/env python
|
2 | 3 | #
|
3 | 4 | #
|
4 | | -# Copyright 2010 benedikt93, partially derived from TheSeven's ipod tools
|
| 5 | +# Copyright 2010 TheSeven, benedikt93
|
5 | 6 | #
|
6 | 7 | #
|
7 | | -# This file is part of the freemyipod.org iPod tools.
|
| 8 | +# This file is part of emBIOS.
|
8 | 9 | #
|
9 | | -# FreeMyIPods' emBIOS and related tools are free software: you can redistribute it and/or
|
| 10 | +# emBIOS is free software: you can redistribute it and/or
|
10 | 11 | # modify it under the terms of the GNU General Public License as
|
11 | 12 | # published by the Free Software Foundation, either version 2 of the
|
12 | 13 | # License, or (at your option) any later version.
|
13 | 14 | #
|
14 | | -# FreeMyIPods' emBIOS and related tools are distributed in the hope that they will be useful,
|
| 15 | +# emBIOS is distributed in the hope that it will be useful,
|
15 | 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16 | 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
17 | 18 | # See the GNU General Public License for more details.
|
18 | 19 | #
|
19 | | -# You should have received a copy of the GNU General Public License along
|
20 | | -# with FreeMyIPods' emBIOS and related tools. If not, see <http://www.gnu.org/licenses/>.
|
| 20 | +# You should have received a copy of the GNU General Public License
|
| 21 | +# along with emBIOS. If not, see <http://www.gnu.org/licenses/>.
|
21 | 22 | #
|
22 | 23 | #
|
23 | 24 |
|
| 25 | +# note: handles commands 1 to 20
|
24 | 26 |
|
25 | 27 | import sys
|
26 | 28 | import time
|
— | — | @@ -46,6 +48,38 @@ |
47 | 49 | print " If <force> is 1, the poweroff will be forced, otherwise it will be gracefully,"
|
48 | 50 | print " which may take some time."
|
49 | 51 | print ""
|
| 52 | + print ""
|
| 53 | + print " uploadfile <offset> <file> <usedma> <freezescheduler>"
|
| 54 | + print " Uploads a file to the iPod"
|
| 55 | + print " <offset>: the address to upload the file to"
|
| 56 | + print " <file>: the path to the file"
|
| 57 | + print " <usedma>: if 0, DMA will not be used when uploading the file,"
|
| 58 | + print " otherwise it will be used. It can be omitted, default is then 1"
|
| 59 | + print " <freezescheduler>: if not 0, the scheduler will be frozen during DMA access"
|
| 60 | + print " to prevent non-consistent data after the transfer."
|
| 61 | + print " It can be omitted, default is then 0"
|
| 62 | + print ""
|
| 63 | + print " downloadfile <offset> <size> <file> <usedma> <freezescheduler>"
|
| 64 | + print " Uploads a file to the iPod"
|
| 65 | + print " <offset>: the address to upload the file to"
|
| 66 | + print " <size>: the number of bytes to be read"
|
| 67 | + print " <file>: the path to the file"
|
| 68 | + print " <usedma>: if 0, DMA will not be used when downloading the file,"
|
| 69 | + print " otherwise it will be used. It can be omitted, default is then 1"
|
| 70 | + print " <freezescheduler>: if not 0, the scheduler will be frozen during DMA access"
|
| 71 | + print " to prevent non-consistent data after the transfer"
|
| 72 | + print " It can be omitted, default is then 0"
|
| 73 | + print ""
|
| 74 | + print " uploadint <offset> <data>"
|
| 75 | + print " Uploads a single integer to the iPod"
|
| 76 | + print " <offset>: the address to upload the integer to"
|
| 77 | + print " <data>: the integer to upload"
|
| 78 | + print ""
|
| 79 | + print " downloadint <offset>"
|
| 80 | + print " Downloads a single integer from the iPod and prints it to the console window"
|
| 81 | + print " <offset>: the address to download the integer from"
|
| 82 | + print ""
|
| 83 | + print ""
|
50 | 84 | print " i2crecv <bus> <slave> <addr> <size>"
|
51 | 85 | print " Reads data from an I2C device"
|
52 | 86 | print " <bus> the bus index"
|
— | — | @@ -58,8 +92,49 @@ |
59 | 93 | print " <bus> the bus index"
|
60 | 94 | print " <slave> the slave address"
|
61 | 95 | print " <addr> the start address on the I2C device"
|
62 | | - print " <db1> ... <dbN> the data in single bytes, seperated by whitespaces, eg. 0x37 0x56 0x45 0x12"
|
| 96 | + print " <db1> ... <dbN> the data in single bytes, seperated by whitespaces,"
|
| 97 | + print " eg. 0x37 0x56 0x45 0x12"
|
63 | 98 | print ""
|
| 99 | + print ""
|
| 100 | + print " readusbconsole <size> <outtype> <file>"
|
| 101 | + print " Reads data from the USB console."
|
| 102 | + print " <size>: the number of bytes to read"
|
| 103 | + print " <outtype>: defines how to output the result:"
|
| 104 | + print " 'file': writes the result to file <file>"
|
| 105 | + print " 'printstring': writes the result as string to the console window"
|
| 106 | + print " 'printhex': writes the result in hexedit notation to the console window"
|
| 107 | + print " <file>: the file to write the result to, can be omitted"
|
| 108 | + print " if <outtype> is not 'file'"
|
| 109 | + print ""
|
| 110 | + print " writeusbconsole file <file> <offset> <length>"
|
| 111 | + print " Writes the file <file> to the USB console."
|
| 112 | + print " Optional params <offset> <length>: specify the range in <file> to write"
|
| 113 | + print " writeusbconsole direct <i1> <i2> ... <iN>"
|
| 114 | + print " Writes the integers <i1> ... <iN> to the USB console."
|
| 115 | + print ""
|
| 116 | + print " readdevconsole <bitmask> <size> <outtype> <file>"
|
| 117 | + print " Reads data from one or more of the device's consoles."
|
| 118 | + print " <bitmask>: the bitmask of the consoles to read from"
|
| 119 | + print " <size>: the number of bytes to read"
|
| 120 | + print " <outtype>: defines how to output the result:"
|
| 121 | + print " 'file': writes the result to file <file>"
|
| 122 | + print " 'printstring': writes the result as string to the console window"
|
| 123 | + print " 'printhex': writes the result in hexedit notation to the console window"
|
| 124 | + print " <file>: the file to write the result to, can be omitted"
|
| 125 | + print " if <outtype> is not 'file'"
|
| 126 | + print ""
|
| 127 | + print " writedevconsole file <bitmask> <file> <offset> <length>"
|
| 128 | + print " Writes the file <file> to the device consoles specified by <bitmask>"
|
| 129 | + print " Optional params <offset> <length>: specify the range in <file> to write"
|
| 130 | + print " writedevconsole direct <bitmask> <i1> <i2> ... <iN>"
|
| 131 | + print " Writes the integers <i1> ... <iN> to the device consoles specified"
|
| 132 | + print " by <bitmask>"
|
| 133 | + print ""
|
| 134 | + print " flushconsolebuffers <bitmask>"
|
| 135 | + print " flushes one or more of the device consoles' buffers."
|
| 136 | + print " <bitmask>: the bitmask of the consoles to be flushed"
|
| 137 | + print ""
|
| 138 | + print ""
|
64 | 139 | print " getprocessinformation <offset> <size> / getprocinfo <offset> <size>"
|
65 | 140 | print " Fetches data on the currently running processes"
|
66 | 141 | print " <offset> the offset in the data field"
|
— | — | @@ -93,6 +168,7 @@ |
94 | 169 | print " <priority> the priority of the thread, from 1 to 255"
|
95 | 170 | print " <state> the thread's initial state, valid are: 1 => ready, 0 => suspended"
|
96 | 171 | print ""
|
| 172 | + print ""
|
97 | 173 | print " flushcaches"
|
98 | 174 | print " Flushes the CPUs data and instruction caches."
|
99 | 175 | print ""
|
— | — | @@ -115,6 +191,42 @@ |
116 | 192 | if len(argv) != 3: usage()
|
117 | 193 | dev.poweroff(int(argv[2]))
|
118 | 194 |
|
| 195 | +
|
| 196 | + elif argv[1] == "uploadfile":
|
| 197 | + if len(argv) < 4 or len(argv) > 6: usage()
|
| 198 | + if len(argv) > 4:
|
| 199 | + usedma = argv[4]
|
| 200 | + if len(argv) > 5:
|
| 201 | + freezesched = argv[5]
|
| 202 | + else:
|
| 203 | + freezesched = 0
|
| 204 | + else:
|
| 205 | + freezesched = 0
|
| 206 | + usedma = 1
|
| 207 | + dev.uploadfile(int(argv[2]), argv[3], usedma, freezesched)
|
| 208 | +
|
| 209 | + elif argv[1] == "downloadfile":
|
| 210 | + if len(argv) < 5 or len(argv) > 7: usage()
|
| 211 | + if len(argv) > 5:
|
| 212 | + usedma = argv[5]
|
| 213 | + if len(argv) > 6:
|
| 214 | + freezesched = argv[6]
|
| 215 | + else:
|
| 216 | + freezesched = 0
|
| 217 | + else:
|
| 218 | + freezesched = 0
|
| 219 | + usedma = 1
|
| 220 | + dev.downloadfile(int(argv[2]), int(argv[3]), argv[4], usedma, freezesched)
|
| 221 | +
|
| 222 | + elif argv[1] == "uploadint":
|
| 223 | + if len(argv) != 4: usage()
|
| 224 | + dev.uploadint(int(argv[2]), int(argv[3]))
|
| 225 | +
|
| 226 | + elif argv[1] == "downloadint":
|
| 227 | + if len(argv) != 3: usage()
|
| 228 | + dev.downloadint(int(argv[2]))
|
| 229 | +
|
| 230 | +
|
119 | 231 | elif argv[1] == "i2cread":
|
120 | 232 | if len(argv) != 6: usage()
|
121 | 233 | dev.i2crecv(int(argv[2]), int(argv[3]), int(argv[4]), int(argv[5]))
|
— | — | @@ -127,7 +239,77 @@ |
128 | 240 | data += struct.pack("<B", int(argv[ptr]))
|
129 | 241 | ptr += 1
|
130 | 242 | dev.i2csend(int(argv[2]), int(argv[3]), int(argv[4]), data)
|
| 243 | +
|
| 244 | +
|
| 245 | + elif argv[1] == "readusbconsole":
|
| 246 | + if len(argv) not in [4, 5]: usage()
|
| 247 | + if len(argv) == 4: argv[4] = ""
|
| 248 | + dev.readusbcon(int(argv[2]), argv[3], argv[4])
|
| 249 | +
|
| 250 | + elif argv[1] == "writeusbconsole":
|
| 251 | + if len(argv) < 4: usage()
|
131 | 252 |
|
| 253 | + if argv[2] == "file":
|
| 254 | + f = open(argv[3], "rb")
|
| 255 | + data = f.read()
|
| 256 | +
|
| 257 | + if len(argv) > 4:
|
| 258 | + offset = int(argv[4])
|
| 259 | + else:
|
| 260 | + offset = 0
|
| 261 | + if len(argv) > 5:
|
| 262 | + size = int(argv[5])
|
| 263 | + else:
|
| 264 | + size = len(data)
|
| 265 | + if len(argv) > 6: usage()
|
| 266 | +
|
| 267 | + dev.writeusbcon(data, 0, offset, size)
|
| 268 | +
|
| 269 | + if argv[2] == "direct":
|
| 270 | + data = ""
|
| 271 | + ptr = 3
|
| 272 | + while ptr < len(argv):
|
| 273 | + data += struct.pack("<I", int(argv[ptr]))
|
| 274 | + ptr += 1
|
| 275 | + dev.writeusbcon(data)
|
| 276 | +
|
| 277 | + elif argv[1] == "readdevconsole":
|
| 278 | + if len(argv) not in [5, 6]: usage()
|
| 279 | + if len(argv) == 5: argv[5] = ""
|
| 280 | + dev.readusbcon(int(argv[2]), int(argv[3]), argv[4], argv[5])
|
| 281 | +
|
| 282 | + elif argv[1] == "writedevconsole":
|
| 283 | + if len(argv) < 5: usage()
|
| 284 | +
|
| 285 | + if argv[2] == "file":
|
| 286 | + f = open(argv[4], "rb")
|
| 287 | + data = f.read()
|
| 288 | +
|
| 289 | + if len(argv) > 5:
|
| 290 | + offset = int(argv[5])
|
| 291 | + else:
|
| 292 | + offset = 0
|
| 293 | + if len(argv) > 6:
|
| 294 | + size = int(argv[6])
|
| 295 | + else:
|
| 296 | + size = len(data)
|
| 297 | + if len(argv) > 7: usage()
|
| 298 | +
|
| 299 | + dev.writeusbcon(int(argv[3]), data, 0, offset, size)
|
| 300 | +
|
| 301 | + if argv[2] == "direct":
|
| 302 | + data = ""
|
| 303 | + ptr = 4
|
| 304 | + while ptr < len(argv):
|
| 305 | + data += struct.pack("<I", int(argv[ptr]))
|
| 306 | + ptr += 1
|
| 307 | + dev.writeusbcon(int(argv[3]), data)
|
| 308 | +
|
| 309 | + elif argv[1] == "flushconsolebuffers":
|
| 310 | + if len(argv) != 3: usage()
|
| 311 | + dev.flushconsolebuffers(int(argv[2]))
|
| 312 | +
|
| 313 | +
|
132 | 314 | elif argv[1] == "getprocessinformation" or argv[1] == "getprocinfo":
|
133 | 315 | if len(argv) != 4: usage()
|
134 | 316 | dev.getprocinfo(int(argv[2]), int(argv[3]))
|
— | — | @@ -156,6 +338,7 @@ |
157 | 339 | if len(argv) != 9: usage()
|
158 | 340 | dev.createthread(int(argv[2]), int(argv[3]), int(argv[4]), int(argv[5]), int(argv[6]), int(argv[7]), int(argv[8]))
|
159 | 341 |
|
| 342 | +
|
160 | 343 | elif argv[1] == "flushcaches":
|
161 | 344 | if len(argv) != 2: usage()
|
162 | 345 | dev.flushcaches()
|
Index: embios/trunk/tools/libembios.py |
— | — | @@ -21,7 +21,7 @@ |
22 | 22 | #
|
23 | 23 | #
|
24 | 24 |
|
25 | | -# note: handles commands 1,2,3,4,5,6,7,8,9,10,11, ,14,15,16,17,18,19,20
|
| 25 | +# note: handles commands 1 to 20
|
26 | 26 |
|
27 | 27 | import sys
|
28 | 28 | import math
|
— | — | @@ -59,7 +59,7 @@ |
60 | 60 | self.handle = handle
|
61 | 61 | self.dev = dev
|
62 | 62 |
|
63 | | - self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:6]
|
| 63 | + self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:]
|
64 | 64 | self.__myprint("Connected to emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \
|
65 | 65 | % (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \
|
66 | 66 | self.devtype2name(self.devtype), dev.deviceVersion))
|
— | — | @@ -80,7 +80,7 @@ |
81 | 81 |
|
82 | 82 | @staticmethod
|
83 | 83 | def __myprint(data, silent = 0):
|
84 | | - if (silent == 0):
|
| 84 | + if not silent:
|
85 | 85 | sys.stdout.write(data)
|
86 | 86 | sys.stdout.flush()
|
87 | 87 |
|
— | — | @@ -157,7 +157,7 @@ |
158 | 158 |
|
159 | 159 | i = struct.unpack("<IIBBBBI", response)
|
160 | 160 |
|
161 | | - self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:6]
|
| 161 | + self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:]
|
162 | 162 |
|
163 | 163 | self.__myprint("emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \
|
164 | 164 | % (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \
|
— | — | @@ -459,7 +459,7 @@ |
460 | 460 |
|
461 | 461 | def readusbcon(self, size, outtype = "", file = "", silent = 0):
|
462 | 462 | """ reads from USB console
|
463 | | - <size>: number of bytes to be read, cannot be more than the Command In endpoint packet size - 0x10
|
| 463 | + <size>: number of bytes to be read, if its length exceeds the Command In endpoint packet size - 0x10, it will be read in several steps
|
464 | 464 | <outtype>: how the data will be put out
|
465 | 465 | "file" => writes data to file <file>
|
466 | 466 | "printstring" => prints data as a string to the console window
|
— | — | @@ -471,51 +471,67 @@ |
472 | 472 | [len, buffersize, datainbuffer, data]
|
473 | 473 | where len is the length of the data actually read,
|
474 | 474 | buffersize is the on-device read buffer size,
|
475 | | - datainbuffer is the number of bytes still left in the on_device buffer,
|
| 475 | + datainbuffer is the number of bytes still left in the on device buffer,
|
476 | 476 | data is the actual data
|
| 477 | +
|
| 478 | + in case that within 5 secs, it's not possible to read <size> bytes, a timeout will occur
|
477 | 479 | """
|
478 | | - if size > self.cin_maxsize - 0x10:
|
479 | | - size = self.cin_maxsize - 0x10
|
| 480 | + out_data = ""
|
| 481 | + readbytes = 0
|
| 482 | + buffersize = 0
|
| 483 | + bytesleft = 0
|
| 484 | + timeoutcounter = 0
|
480 | 485 |
|
481 | 486 | self.__myprint("Reading 0x%x bytes from USB console..." % (size), silent)
|
482 | 487 |
|
483 | | - self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 10, size, 0, 0))
|
484 | | - response = self.__getbulk(self.handle, self.__cinep, size + 0x10)
|
485 | | - self.__checkstatus(response)
|
| 488 | + while size > 0 and timoutcounter < 50:
|
| 489 | + blocklen = size
|
| 490 | +
|
| 491 | + if size > self.cin_maxsize - 0x10:
|
| 492 | + blocklen = self.cin_maxsize - 0x10
|
| 493 | +
|
| 494 | + self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 10, blocklen, 0, 0))
|
| 495 | + response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)
|
| 496 | + self.__checkstatus(response)
|
| 497 | +
|
| 498 | + readbytes, buffersize, bytesleft = struct.unpack("<III", response[:12])
|
| 499 | + out_data += response[0x10:0x10+readbytes]
|
| 500 | + size -= blocklen
|
| 501 | +
|
| 502 | + if not bytesleft > 0: # no data left to read => wait a bit and prevent an infinite loop trying to read data when there is none
|
| 503 | + timeoutcounter += 1
|
| 504 | + time.sleep(0.1)
|
| 505 | + else:
|
| 506 | + timeoutcounter -= 3
|
| 507 | + if timeoutcounter < 0:
|
| 508 | + timeoutcounter = 0
|
| 509 | +
|
| 510 | + self.__myprint(" done\n", silent)
|
| 511 | + self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
|
| 512 | + % (len(out_data), buffersize, bytesleft)
|
| 513 | + , silent)
|
486 | 514 |
|
487 | 515 | if (outtype == "file"):
|
488 | 516 | f = open(file, "wb")
|
489 | | - f.write(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]])
|
| 517 | + f.write(out_data)
|
490 | 518 |
|
491 | 519 | elif (outtype == "printstring"):
|
492 | | - self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
|
493 | | - % (struct.unpack("<IIII", response[:0x10])[1],
|
494 | | - struct.unpack("<IIII", response[:0x10])[2],
|
495 | | - struct.unpack("<IIII", response[:0x10])[3])
|
496 | | - , silent)
|
497 | | - self.__myprint(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]], silent)
|
| 520 | + self.__myprint(out_data, silent)
|
498 | 521 | self.__myprint("\n\n", silent)
|
499 | 522 |
|
500 | 523 | elif (outtype == "printhex"):
|
501 | | - self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
|
502 | | - % (struct.unpack("<IIII", response[:0x10])[1],
|
503 | | - struct.unpack("<IIII", response[:0x10])[2],
|
504 | | - struct.unpack("<IIII", response[:0x10])[3])
|
505 | | - , silent)
|
506 | | - self.__myprint(self.__gethexviewprintout(response[0x10:], "", 1), silent)
|
| 524 | + self.__myprint(self.__gethexviewprintout(out_data, "", 1), silent)
|
507 | 525 | self.__myprint("\n\n", silent)
|
508 | 526 |
|
509 | 527 | elif (outtype == ""):
|
510 | 528 | pass # return only
|
| 529 | +
|
511 | 530 | else:
|
512 | 531 | raise Exception ("Invalid argument for <outtype>: '%s'." % (outtype))
|
513 | 532 |
|
514 | | - self.__myprint(" done\n", silent)
|
| 533 | + return [len(out_data), buffersize, bytesleft, out_data]
|
515 | 534 |
|
516 | | - # header data
|
517 | | - return struct.unpack("<IIII", response[:0x10]).extend(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]])
|
518 | 535 |
|
519 | | -
|
520 | 536 | def writeusbcon(self, data, silent = 0, *range):
|
521 | 537 | """ writes to USB console
|
522 | 538 | <data>: the data to be written
|
— | — | @@ -522,7 +538,7 @@ |
523 | 539 | <range>: the range in <data> that should be written, in the from [offset, length]
|
524 | 540 | <silent>: if 0, nothing will be written to the console window
|
525 | 541 |
|
526 | | - the data to be written can't exceed the Command Out endpoint packet size - 0x10
|
| 542 | + if the data to be written exceeds the Command Out endpoint packet size - 0x10, it will be written in several steps
|
527 | 543 | """
|
528 | 544 | size = len(data)
|
529 | 545 | boffset = 0
|
— | — | @@ -532,30 +548,143 @@ |
533 | 549 | if len(range) > 1:
|
534 | 550 | size = range[1]
|
535 | 551 |
|
536 | | - if size > self.cout_maxsize - 0x10:
|
537 | | - size = self.cout_maxsize - 0x10
|
538 | | -
|
539 | 552 | self.__myprint("Writing 0x%x bytes to USB console..." % (size), silent)
|
540 | 553 |
|
541 | 554 | timeoutcounter = 0
|
542 | 555 |
|
543 | | - while (size != 0) and (timeoutcounter < 10):
|
544 | | - self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 11, size, 0, 0) + data[boffset:boffset+size])
|
| 556 | + while (size > 0) and (timeoutcounter < 50):
|
| 557 | + blocklen = size
|
| 558 | + if blocklen > self.cout_maxsize - 0x10:
|
| 559 | + blocklen = self.cout_maxsize - 0x10
|
| 560 | +
|
| 561 | + self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 11, size, 0, 0) + data[boffset:boffset+blocklen])
|
545 | 562 | response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
546 | 563 | self.__checkstatus(response)
|
547 | 564 |
|
548 | | - size -= struct.unpack("<I", response[4:8])
|
549 | | - boffset += struct.unpack("<I", response[4:8])
|
| 565 | + sendbytes = struct.unpack("<I", response[4:8])
|
| 566 | + if sendbytes < blocklen: # not everything has been written, need to resent some stuff but wait a bit before doing so
|
| 567 | + time.sleep(0.1)
|
| 568 | + timeoutcounter += 1
|
| 569 | + elif timeoutcounter > 0: # lower timeoutcounter again
|
| 570 | + timeoutcounter -= 3
|
| 571 | + if timeoutcounter < 0:
|
| 572 | + timeoutcounter = 0
|
550 | 573 |
|
551 | | - time.sleep(0.1)
|
552 | | - timeoutcounter += 1
|
| 574 | + size -= sendbytes
|
| 575 | + boffset += sendbytes
|
| 576 | +
|
553 | 577 |
|
554 | | - if (timeoutcounter >=10):
|
555 | | - raise Exception("0x%x couldn't be send.")
|
| 578 | + if (timeoutcounter >=50):
|
| 579 | + raise Exception("Timeout, 0x%x bytes couldn't be send." % size)
|
556 | 580 |
|
557 | 581 | self.__myprint(" done\n", silent)
|
558 | 582 |
|
| 583 | + return size # number of bytes that have not been sent
|
| 584 | +
|
559 | 585 |
|
| 586 | + def readdevcon(self, bitmask, size, outtype = "", file = "", silent = 0):
|
| 587 | + """ reads from one or more of the device's consoles
|
| 588 | + <bitmask>: bitmask of consoles to be read from
|
| 589 | + <size>: number of bytes to be read, if its length exceeds the Command In endpoint packet size - 0x10, it will be read in several steps
|
| 590 | + <outtype>: how the data will be put out
|
| 591 | + "file" => writes data to file <file>
|
| 592 | + "printstring" => prints data as a string to the console window
|
| 593 | + "printhex" => prints a hexview view of the data to the console window
|
| 594 | + "" => only returns the data
|
| 595 | + <silent>: if 0, nothing will be written to the console window (even if <outtype> defines something else)
|
| 596 | +
|
| 597 | + in every case, the data will be returned
|
| 598 | +
|
| 599 | + in case that within 5 secs, it's not possible to read <size> bytes, a timeout will occur
|
| 600 | + """
|
| 601 | + out_data = ""
|
| 602 | + readbytes = 0
|
| 603 | + timeoutcounter = 0
|
| 604 | +
|
| 605 | + self.__myprint("Reading 0x%x bytes from device's console(s)..." % (size), silent)
|
| 606 | +
|
| 607 | + while size > 0 and timoutcounter < 50:
|
| 608 | + blocklen = size
|
| 609 | +
|
| 610 | + if size > self.cin_maxsize - 0x10:
|
| 611 | + blocklen = self.cin_maxsize - 0x10
|
| 612 | +
|
| 613 | + self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 13, bitmask, blocklen, 0))
|
| 614 | + response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)
|
| 615 | + self.__checkstatus(response)
|
| 616 | +
|
| 617 | + readbytes = struct.unpack("<III", response[4:8])
|
| 618 | + out_data += response[0x10:0x10+readbytes]
|
| 619 | + size -= blocklen
|
| 620 | +
|
| 621 | + if not readbytes > 0: # no data read => wait a bit and prevent an infinite loop trying to read data when there is none
|
| 622 | + timeoutcounter += 1
|
| 623 | + time.sleep(0.1)
|
| 624 | + else:
|
| 625 | + timeoutcounter -= 3
|
| 626 | + if timeoutcounter < 0:
|
| 627 | + timeoutcounter = 0
|
| 628 | +
|
| 629 | + self.__myprint(" done\n", silent)
|
| 630 | + self.__myprint("\nBytes read: 0x%x\n\n" % (len(out_data)), silent)
|
| 631 | +
|
| 632 | + if (outtype == "file"):
|
| 633 | + f = open(file, "wb")
|
| 634 | + f.write(out_data)
|
| 635 | +
|
| 636 | + elif (outtype == "printstring"):
|
| 637 | + self.__myprint(out_data, silent)
|
| 638 | + self.__myprint("\n\n", silent)
|
| 639 | +
|
| 640 | + elif (outtype == "printhex"):
|
| 641 | + self.__myprint(self.__gethexviewprintout(out_data, "", 1), silent)
|
| 642 | + self.__myprint("\n\n", silent)
|
| 643 | +
|
| 644 | + elif (outtype == ""):
|
| 645 | + pass # return only
|
| 646 | +
|
| 647 | + else:
|
| 648 | + raise Exception ("Invalid argument for <outtype>: '%s'." % (outtype))
|
| 649 | +
|
| 650 | + return out_data
|
| 651 | +
|
| 652 | +
|
| 653 | + def writedevcon(self, bitmask, data, silent = 0, *range):
|
| 654 | + """ writes to USB console
|
| 655 | + <bitmask>: bitmask of consoles to be written to
|
| 656 | + <data>: the data to be written
|
| 657 | + <range>: the range in <data> that should be written, in the from [offset, length]
|
| 658 | + <silent>: if 0, nothing will be written to the console window
|
| 659 | +
|
| 660 | + if the data to be written exceeds the Command Out endpoint packet size - 0x10, it will be written in several steps
|
| 661 | + """
|
| 662 | + size = len(data)
|
| 663 | + boffset = 0
|
| 664 | +
|
| 665 | + if len(range) > 0:
|
| 666 | + boffset = range[0]
|
| 667 | + if len(range) > 1:
|
| 668 | + size = range[1]
|
| 669 | +
|
| 670 | + self.__myprint("Writing 0x%x bytes to device's console(s)..." % (size), silent)
|
| 671 | +
|
| 672 | + timeoutcounter = 0
|
| 673 | +
|
| 674 | + while size > 0:
|
| 675 | + blocklen = size
|
| 676 | + if blocklen > self.cout_maxsize - 0x10:
|
| 677 | + blocklen = self.cout_maxsize - 0x10
|
| 678 | +
|
| 679 | + self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 12, bitmask, size, 0) + data[boffset:boffset+blocklen])
|
| 680 | + response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
| 681 | + self.__checkstatus(response)
|
| 682 | +
|
| 683 | + size -= blocklen
|
| 684 | + boffset += blocklen
|
| 685 | +
|
| 686 | + self.__myprint(" done\n", silent)
|
| 687 | +
|
| 688 | +
|
560 | 689 | def flushconsolebuffers(self, bitmask, silent = 0):
|
561 | 690 | self.__myprint("Flushing device console('s) buffer('s)...")
|
562 | 691 |
|
— | — | @@ -867,6 +996,8 @@ |
868 | 997 | processinfoprint += "priority: 0x%02x " % (out[i+3]['priority'])
|
869 | 998 | processinfoprint += "cpu load: 0x%02x\n" % (out[i+3]['cpuload'])
|
870 | 999 |
|
| 1000 | + i += 1
|
| 1001 | +
|
871 | 1002 | except IndexError:
|
872 | 1003 | processinfoprint += "--------------------------------------------------------------------------------"
|
873 | 1004 |
|
— | — | @@ -895,7 +1026,7 @@ |
896 | 1027 |
|
897 | 1028 |
|
898 | 1029 | #======================================================================================
|
899 | | -#======================================================================================
|
| 1030 | +# backlight control, remnant from libibugger adjusted to work with libembios ==========
|
900 | 1031 |
|
901 | 1032 |
|
902 | 1033 | def backlighton(self, fade, brightness, silent = 0):
|