| 56 |
benedikt93 |
1 |
#!/usr/bin/env python
|
|
|
2 |
#
|
|
|
3 |
#
|
|
|
4 |
# Copyright 2010 TheSeven, benedikt93
|
|
|
5 |
#
|
|
|
6 |
#
|
|
|
7 |
# This file is part of emBIOS.
|
|
|
8 |
#
|
|
|
9 |
# emBIOS is free software: you can redistribute it and/or
|
|
|
10 |
# modify it under the terms of the GNU General Public License as
|
|
|
11 |
# published by the Free Software Foundation, either version 2 of the
|
|
|
12 |
# License, or (at your option) any later version.
|
|
|
13 |
#
|
|
|
14 |
# emBIOS is distributed in the hope that it will be useful,
|
|
|
15 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
16 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
17 |
# See the GNU General Public License for more details.
|
|
|
18 |
#
|
|
|
19 |
# You should have received a copy of the GNU General Public License
|
|
|
20 |
# along with emBIOS. If not, see <http://www.gnu.org/licenses/>.
|
|
|
21 |
#
|
|
|
22 |
#
|
|
|
23 |
|
| 96 |
benedikt93 |
24 |
# note: handles commands 1 to 21
|
| 56 |
benedikt93 |
25 |
|
|
|
26 |
import sys
|
|
|
27 |
import math
|
|
|
28 |
import struct
|
|
|
29 |
import time
|
|
|
30 |
import usb
|
|
|
31 |
|
|
|
32 |
|
|
|
33 |
class embios:
|
|
|
34 |
def __init__(self, devtype = 0, type = 0):
|
|
|
35 |
busses = usb.busses()
|
|
|
36 |
|
|
|
37 |
for bus in busses:
|
|
|
38 |
devices = bus.devices
|
|
|
39 |
for dev in devices:
|
|
|
40 |
if dev.idVendor == 0xffff and dev.idProduct == 0xe000:
|
|
|
41 |
# get endpoints
|
|
|
42 |
self.__coutep = dev.configurations[0].interfaces[0][0].endpoints[0].address
|
|
|
43 |
self.__cinep = dev.configurations[0].interfaces[0][0].endpoints[1].address
|
|
|
44 |
self.__doutep = dev.configurations[0].interfaces[0][0].endpoints[2].address
|
|
|
45 |
self.__dinep = dev.configurations[0].interfaces[0][0].endpoints[3].address
|
|
|
46 |
|
|
|
47 |
handle = dev.open()
|
|
|
48 |
handle.setConfiguration(1)
|
|
|
49 |
handle.claimInterface(0)
|
|
|
50 |
|
|
|
51 |
# get version info
|
|
|
52 |
handle.bulkWrite(self.__coutep, struct.pack("<IIII", 1, 0, 0, 0))
|
|
|
53 |
response = self.__getbulk(handle, self.__cinep, 0x10)
|
|
|
54 |
self.__checkstatus(response)
|
|
|
55 |
i = struct.unpack("<IIBBBBI", response)
|
|
|
56 |
|
|
|
57 |
if devtype in [0, i[6]] and type in [0, i[5]]:
|
|
|
58 |
# correct device
|
|
|
59 |
self.handle = handle
|
|
|
60 |
self.dev = dev
|
|
|
61 |
|
| 82 |
benedikt93 |
62 |
self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:]
|
| 79 |
benedikt93 |
63 |
self.__myprint("Connected to emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \
|
| 64 |
benedikt93 |
64 |
% (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \
|
| 56 |
benedikt93 |
65 |
self.devtype2name(self.devtype), dev.deviceVersion))
|
|
|
66 |
|
|
|
67 |
# get packet size info
|
|
|
68 |
self.getinfo("packetsize", 1)
|
|
|
69 |
|
|
|
70 |
return
|
|
|
71 |
|
|
|
72 |
# wrong device
|
|
|
73 |
handle.releaseInterface()
|
|
|
74 |
|
|
|
75 |
raise Exception("Could not find specified device (devtype = %d, type = %d)" % (devtype, type))
|
|
|
76 |
|
|
|
77 |
|
|
|
78 |
#=====================================================================================
|
|
|
79 |
|
|
|
80 |
|
|
|
81 |
@staticmethod
|
|
|
82 |
def __myprint(data, silent = 0):
|
| 82 |
benedikt93 |
83 |
if not silent:
|
| 56 |
benedikt93 |
84 |
sys.stdout.write(data)
|
|
|
85 |
sys.stdout.flush()
|
|
|
86 |
|
|
|
87 |
|
|
|
88 |
@staticmethod
|
| 64 |
benedikt93 |
89 |
def __gethexviewprintout(data, title, showaddr):
|
| 56 |
benedikt93 |
90 |
printout_temp = struct.unpack("%dB" % (len(data)), data)
|
|
|
91 |
|
| 64 |
benedikt93 |
92 |
printout = title + ":\n"
|
| 56 |
benedikt93 |
93 |
pointer = 0
|
|
|
94 |
pointer2 = 0
|
|
|
95 |
|
| 64 |
benedikt93 |
96 |
while (pointer < len(printout_temp)):
|
| 56 |
benedikt93 |
97 |
pointer2 = 0
|
| 64 |
benedikt93 |
98 |
if (showaddr): printout += "0x%08x " % (pointer)
|
|
|
99 |
while (pointer2 < 0x10) and (pointer < len(printout_temp)):
|
|
|
100 |
printout += ("%2x " % (printout_temp[pointer]))
|
| 56 |
benedikt93 |
101 |
pointer += 1
|
|
|
102 |
pointer2 += 1
|
|
|
103 |
printout += "\n"
|
|
|
104 |
|
|
|
105 |
if (pointer2 != 0x10):
|
|
|
106 |
printout += "\n"
|
|
|
107 |
|
|
|
108 |
return printout
|
|
|
109 |
|
|
|
110 |
|
|
|
111 |
@staticmethod
|
|
|
112 |
def __getbulk(handle, endpoint, size):
|
|
|
113 |
data = handle.bulkRead(endpoint, size, 1000)
|
|
|
114 |
return struct.pack("%dB" % len(data), *data)
|
|
|
115 |
|
|
|
116 |
|
|
|
117 |
@staticmethod
|
|
|
118 |
def __checkstatus(data):
|
|
|
119 |
errorcode = struct.unpack("<I", data[:4])[0]
|
|
|
120 |
if errorcode == 1:
|
|
|
121 |
# everything went fine
|
|
|
122 |
return
|
|
|
123 |
elif errorcode == 2:
|
|
|
124 |
print("\nError: Device doesn't support this function!")
|
|
|
125 |
raise Exception("emBIOS device doesn't support this function!")
|
|
|
126 |
elif errorcode == 3:
|
|
|
127 |
print("\nError: Device is busy!")
|
|
|
128 |
raise Exception("emBIOS device is busy!")
|
|
|
129 |
else:
|
|
|
130 |
print("\nUnknown error %d" % errorcode)
|
|
|
131 |
raise Exception("Unknown emBIOS error %d" % errorcode)
|
|
|
132 |
|
|
|
133 |
|
|
|
134 |
@staticmethod
|
|
|
135 |
def type2name(type):
|
|
|
136 |
if type == 1: return "Debugger"
|
| 79 |
benedikt93 |
137 |
else: return "UNKNOWN (0x%08x)" % type
|
| 56 |
benedikt93 |
138 |
|
|
|
139 |
|
|
|
140 |
@staticmethod
|
|
|
141 |
def devtype2name(devtype):
|
|
|
142 |
if devtype == 0x47324e49: return "iPod Nano 2G"
|
|
|
143 |
if devtype == 0x47334e49: return "iPod Nano 3G"
|
|
|
144 |
if devtype == 0x47344e49: return "iPod Nano 4G"
|
|
|
145 |
if devtype == 0x4c435049: return "iPod Classic"
|
| 79 |
benedikt93 |
146 |
else: return "UNKNOWN (0x%08x)" % devtype
|
| 56 |
benedikt93 |
147 |
|
|
|
148 |
|
|
|
149 |
#=====================================================================================
|
|
|
150 |
|
|
|
151 |
|
|
|
152 |
def getinfo (self, infotype, silent = 0):
|
|
|
153 |
if (infotype == "version"):
|
|
|
154 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 1, 0, 0, 0))
|
|
|
155 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
156 |
self.__checkstatus(response)
|
|
|
157 |
|
|
|
158 |
i = struct.unpack("<IIBBBBI", response)
|
|
|
159 |
|
| 82 |
benedikt93 |
160 |
self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:]
|
| 56 |
benedikt93 |
161 |
|
|
|
162 |
self.__myprint("emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \
|
|
|
163 |
% (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \
|
| 93 |
benedikt93 |
164 |
self.devtype2name(self.devtype), self.dev.deviceVersion)\
|
| 56 |
benedikt93 |
165 |
, silent)
|
|
|
166 |
|
|
|
167 |
elif (infotype == "packetsize"):
|
|
|
168 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 1, 1, 0, 0))
|
|
|
169 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
170 |
self.__checkstatus(response)
|
|
|
171 |
|
|
|
172 |
i = struct.unpack("<IHHII", response)
|
|
|
173 |
|
|
|
174 |
self.cout_maxsize = i[1]
|
|
|
175 |
self.cin_maxsize = i[2]
|
|
|
176 |
self.dout_maxsize = i[3]
|
|
|
177 |
self.din_maxsize = i[4]
|
|
|
178 |
|
|
|
179 |
self.__myprint("Maximum packet sizes:\n Command out: %d bytes\n Command in: %d bytes\n Data out: %d bytes\n Data in: %d bytes\n" \
|
|
|
180 |
% (self.cout_maxsize, self.cin_maxsize, self.dout_maxsize, self.din_maxsize)
|
|
|
181 |
, silent)
|
|
|
182 |
|
|
|
183 |
elif (infotype == "usermemrange"):
|
|
|
184 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 1, 1, 0, 0))
|
|
|
185 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
186 |
self.__checkstatus(response)
|
|
|
187 |
|
|
|
188 |
i = struct.unpack("<IIII", response)
|
|
|
189 |
|
|
|
190 |
self.usermem_lower = i[1]
|
| 93 |
benedikt93 |
191 |
self.usermem_upper = i[2]
|
| 56 |
benedikt93 |
192 |
|
|
|
193 |
self.__myprint("User memory range:\n Lower bound (inclusive): %x\n Upper bound (exclusive) %x\n" \
|
|
|
194 |
% (self.usermem_lower, self.usermem_upper)
|
|
|
195 |
, silent)
|
|
|
196 |
|
|
|
197 |
else:
|
|
|
198 |
self.__myprint("Unsupported type of info: %d" % (infotype))
|
|
|
199 |
|
|
|
200 |
|
|
|
201 |
def reset(self, force, silent = 0):
|
|
|
202 |
""" Resets the device.
|
|
|
203 |
<force>: if 0, the reset will be gracefully, otherwise it will be forced.
|
|
|
204 |
<silent>: if not 0, nothing will be printed to the console window
|
|
|
205 |
"""
|
|
|
206 |
if (force == 0):
|
|
|
207 |
force = 1
|
|
|
208 |
else:
|
|
|
209 |
force = 0
|
|
|
210 |
|
|
|
211 |
self.__myprint("Resetting device...", silent)
|
|
|
212 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 2, force, 0, 0))
|
|
|
213 |
|
|
|
214 |
if (force == 1):
|
|
|
215 |
# reset not forced
|
|
|
216 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
217 |
self.__checkstatus(response)
|
|
|
218 |
|
|
|
219 |
self.__myprint(" done\n", silent)
|
|
|
220 |
|
|
|
221 |
|
|
|
222 |
def poweroff(self, force, silent = 0):
|
|
|
223 |
""" Powers the device off.
|
|
|
224 |
<force>: if 0, the poweroff will be gracefully, otherwise it will be forced.
|
|
|
225 |
<silent>: if not 0, nothing will be printed to the console window
|
|
|
226 |
"""
|
|
|
227 |
if (force == 0):
|
|
|
228 |
force = 1
|
|
|
229 |
else:
|
|
|
230 |
force = 0
|
|
|
231 |
|
|
|
232 |
self.__myprint("Powering device off...", silent)
|
|
|
233 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 3, force, 0, 0))
|
|
|
234 |
|
|
|
235 |
if (force == 1):
|
|
|
236 |
# shutdown not forced
|
|
|
237 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
238 |
self.__checkstatus(response)
|
|
|
239 |
|
|
|
240 |
self.__myprint(" done\n", silent)
|
|
|
241 |
|
|
|
242 |
|
|
|
243 |
#=====================================================================================
|
|
|
244 |
|
|
|
245 |
|
|
|
246 |
def write(self, offset, data, usedma, freezesched, *range):
|
|
|
247 |
boffset = 0
|
|
|
248 |
|
|
|
249 |
size = len(data)
|
|
|
250 |
|
|
|
251 |
if len(range) > 0:
|
|
|
252 |
boffset = range[0]
|
|
|
253 |
if len(range) > 1:
|
|
|
254 |
size = range[1]
|
|
|
255 |
|
|
|
256 |
if (size == 0):
|
|
|
257 |
return
|
|
|
258 |
|
|
|
259 |
# correct alignment
|
|
|
260 |
while (offset & 0xF) != 0:
|
| 97 |
benedikt93 |
261 |
blocklen = size
|
|
|
262 |
|
| 56 |
benedikt93 |
263 |
if (blocklen > size):
|
|
|
264 |
blocklen = size
|
|
|
265 |
if (blocklen > self.cout_maxsize - 0x10):
|
| 97 |
benedikt93 |
266 |
blocklen = self.cout_maxsize - 0x10
|
| 56 |
benedikt93 |
267 |
|
| 97 |
benedikt93 |
268 |
blocklen = (blocklen & 0xFFFFFFF0) + (offset & 0xF)
|
|
|
269 |
|
| 56 |
benedikt93 |
270 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 5, offset, blocklen, 0) + data[boffset:boffset+blocklen])
|
|
|
271 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
272 |
self.__checkstatus(response)
|
|
|
273 |
|
|
|
274 |
offset += blocklen
|
|
|
275 |
boffset += blocklen
|
|
|
276 |
size -= blocklen
|
|
|
277 |
|
|
|
278 |
# write data with DMA, if it makes sense (-> much data) and isn't forbidden
|
| 97 |
benedikt93 |
279 |
if (usedma) and (size > 2 * (self.cout_maxsize - 16)):
|
| 56 |
benedikt93 |
280 |
if (freezesched):
|
| 97 |
benedikt93 |
281 |
self.freezescheduler(1, 0)
|
| 56 |
benedikt93 |
282 |
|
| 97 |
benedikt93 |
283 |
while (size > (self.cout_maxsize - 16)):
|
| 56 |
benedikt93 |
284 |
blocklen = size
|
|
|
285 |
|
|
|
286 |
if (blocklen > self.dout_maxsize):
|
|
|
287 |
blocklen = self.dout_maxsize
|
|
|
288 |
|
|
|
289 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 7, offset, blocklen, 0))
|
|
|
290 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
291 |
self.__checkstatus(response)
|
|
|
292 |
|
|
|
293 |
self.handle.bulkWrite(self.__doutep, data[boffset:boffset+blocklen])
|
|
|
294 |
|
|
|
295 |
offset += blocklen
|
|
|
296 |
boffset += blocklen
|
|
|
297 |
size -= blocklen
|
|
|
298 |
|
|
|
299 |
if (freezesched):
|
| 97 |
benedikt93 |
300 |
self.freezescheduler(0, 0)
|
| 56 |
benedikt93 |
301 |
|
|
|
302 |
# write rest of data
|
|
|
303 |
while (size > 0):
|
|
|
304 |
blocklen = size
|
|
|
305 |
|
| 64 |
benedikt93 |
306 |
if (blocklen > self.cout_maxsize - 0x10):
|
| 97 |
benedikt93 |
307 |
blocklen = self.cout_maxsize - 0x10
|
| 56 |
benedikt93 |
308 |
|
|
|
309 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 5, offset, blocklen, 0) + data[boffset:boffset+blocklen])
|
|
|
310 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
311 |
self.__checkstatus(response)
|
|
|
312 |
|
|
|
313 |
offset += blocklen
|
|
|
314 |
boffset += blocklen
|
|
|
315 |
size -= blocklen
|
|
|
316 |
|
|
|
317 |
|
|
|
318 |
def read(self, offset, size, usedma, freezesched):
|
|
|
319 |
if (size == 0):
|
|
|
320 |
return
|
|
|
321 |
|
|
|
322 |
data = ""
|
|
|
323 |
|
|
|
324 |
# correct alignment
|
|
|
325 |
while (offset & 0xF) != 0:
|
| 97 |
benedikt93 |
326 |
blocklen = size
|
| 56 |
benedikt93 |
327 |
|
|
|
328 |
if (blocklen > size):
|
|
|
329 |
blocklen = size
|
|
|
330 |
if (blocklen > self.cin_maxsize - 0x10):
|
| 97 |
benedikt93 |
331 |
blocklen = self.cin_maxsize - 0x10
|
|
|
332 |
|
|
|
333 |
blocklen = (blocklen & 0xFFFFFFF0) + (offset & 0xF)
|
| 56 |
benedikt93 |
334 |
|
|
|
335 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 4, offset, blocklen, 0))
|
|
|
336 |
response = self.__getbulk(self.handle, self.__cinep, 0x10 + blocklen)
|
|
|
337 |
self.__checkstatus(response)
|
|
|
338 |
|
|
|
339 |
data += response[0x10:]
|
|
|
340 |
|
|
|
341 |
offset += blocklen
|
|
|
342 |
size -= blocklen
|
|
|
343 |
|
|
|
344 |
# read data with DMA, if it makes sense (-> much data) and isn't forbidden
|
| 97 |
benedikt93 |
345 |
if (usedma) and (size > 2 * (self.cin_maxsize - 16)):
|
| 56 |
benedikt93 |
346 |
if (freezesched):
|
| 97 |
benedikt93 |
347 |
self.freezescheduler(1, 0)
|
| 56 |
benedikt93 |
348 |
|
| 97 |
benedikt93 |
349 |
while (size > (self.cin_maxsize - 16)):
|
| 56 |
benedikt93 |
350 |
blocklen = size
|
|
|
351 |
|
|
|
352 |
if (blocklen > self.din_maxsize):
|
|
|
353 |
blocklen = self.din_maxsize
|
|
|
354 |
|
|
|
355 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 6, offset, blocklen, 0))
|
|
|
356 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
357 |
self.__checkstatus(response)
|
|
|
358 |
|
| 93 |
benedikt93 |
359 |
data += self.__getbulk(self.handle, self.__doutep, blocklen)
|
| 56 |
benedikt93 |
360 |
|
|
|
361 |
offset += blocklen
|
|
|
362 |
size -= blocklen
|
|
|
363 |
|
|
|
364 |
if (freezesched):
|
| 97 |
benedikt93 |
365 |
self.freezescheduler(0, 0)
|
| 56 |
benedikt93 |
366 |
|
|
|
367 |
# read rest of data
|
|
|
368 |
while (size > 0):
|
|
|
369 |
blocklen = size
|
|
|
370 |
|
| 64 |
benedikt93 |
371 |
if (blocklen > self.cin_maxsize - 0x10):
|
| 97 |
benedikt93 |
372 |
blocklen = self.cin_maxsize - 0x10
|
| 56 |
benedikt93 |
373 |
|
|
|
374 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 4, offset, blocklen, 0))
|
|
|
375 |
response = self.__getbulk(self.handle, self.__cinep, 0x10 + blocklen)
|
|
|
376 |
self.__checkstatus(response)
|
|
|
377 |
|
|
|
378 |
data += response[0x10:]
|
|
|
379 |
|
|
|
380 |
offset += blocklen
|
|
|
381 |
size -= blocklen
|
|
|
382 |
|
|
|
383 |
return data
|
|
|
384 |
|
|
|
385 |
|
|
|
386 |
def uploadfile(self, offset, file, usedma = 1, freezesched = 0, silent = 0):
|
| 94 |
benedikt93 |
387 |
self.__myprint("Uploading %s to 0x%08x..." % (file, offset), silent)
|
| 56 |
benedikt93 |
388 |
f = open(file, "rb")
|
|
|
389 |
|
|
|
390 |
while True:
|
|
|
391 |
data = f.read(262144)
|
|
|
392 |
if data == "": break
|
|
|
393 |
self.write(offset, data, usedma, freezesched)
|
|
|
394 |
offset += len(data)
|
|
|
395 |
self.__myprint(".")
|
|
|
396 |
|
|
|
397 |
self.__myprint(" done\n", silent)
|
|
|
398 |
|
|
|
399 |
|
|
|
400 |
def downloadfile(self, offset, size, file, usedma = 1, freezesched = 0, silent = 0):
|
| 94 |
benedikt93 |
401 |
self.__myprint("Downloading 0x%x bytes from 0x%08x to %s..." % (size, offset, file), silent)
|
| 56 |
benedikt93 |
402 |
f = open(file, "wb")
|
|
|
403 |
|
|
|
404 |
while True:
|
|
|
405 |
blocklen = size
|
|
|
406 |
if blocklen == 0: break
|
|
|
407 |
if blocklen > 262144: blocklen = 262144
|
|
|
408 |
f.write(self.read(offset, blocklen, usedma, freezesched))
|
|
|
409 |
offset += blocklen
|
|
|
410 |
size -= blocklen
|
|
|
411 |
self.__myprint(".")
|
|
|
412 |
|
|
|
413 |
self.__myprint(" done\n", silent)
|
|
|
414 |
|
|
|
415 |
|
|
|
416 |
def uploadint(self, offset, data, silent = 0):
|
| 94 |
benedikt93 |
417 |
self.__myprint("Uploading 0x%08x to 0x%08x..." % (data, offset), silent)
|
| 123 |
cmwslw |
418 |
data = struct.pack('<I', data)
|
| 56 |
benedikt93 |
419 |
self.write(offset, data, 0, 0)
|
|
|
420 |
self.__myprint(" done\n", silent)
|
|
|
421 |
|
|
|
422 |
|
|
|
423 |
def downloadint(self, offset, silent = 0):
|
| 104 |
benedikt93 |
424 |
self.__myprint("Downloading an integer from 0x%08x..." % (offset), silent)
|
| 106 |
benedikt93 |
425 |
data = self.read(offset, 4, 0, 0)
|
| 123 |
cmwslw |
426 |
number = struct.unpack('<I', data)
|
|
|
427 |
self.__myprint(" done\nValue was: 0x%08x\n" % (number), silent)
|
| 56 |
benedikt93 |
428 |
|
|
|
429 |
return data
|
|
|
430 |
|
|
|
431 |
|
|
|
432 |
#=====================================================================================
|
|
|
433 |
|
|
|
434 |
|
|
|
435 |
def i2crecv(self, bus, slave, addr, size, silent = 0):
|
|
|
436 |
if (size > self.cin_maxsize - 0x10) or (size > 0xFF):
|
|
|
437 |
raise Exception ("The data exceeds the maximum amount that can be received with this instruction.")
|
|
|
438 |
|
|
|
439 |
self.__myprint("Reading 0x%2x bytes from 0x%2x at I2C device at bus 0x%2x, slave adress 0x%2x ..." % (size, addr, bus, slave), silent)
|
|
|
440 |
|
|
|
441 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IBBBBII", 8, bus, slave, addr, size, 0, 0))
|
|
|
442 |
data = self.__getbulk(self.handle, self.__cinep, 0x10 + size)
|
| 67 |
benedikt93 |
443 |
self.__checkstatus(response)
|
| 56 |
benedikt93 |
444 |
|
| 67 |
benedikt93 |
445 |
self.__myprint(" done\n data was:\n%s\n" % (self.__gethexviewprintout(data[16:])), silent)
|
| 56 |
benedikt93 |
446 |
|
|
|
447 |
return data[16:]
|
|
|
448 |
|
|
|
449 |
|
|
|
450 |
def i2csend(self, bus, slave, addr, data, silent = 0):
|
| 67 |
benedikt93 |
451 |
size = len(data)
|
| 56 |
benedikt93 |
452 |
if (size > self.cout_maxsize - 0x10) or (size > 0xFF):
|
|
|
453 |
raise Exception ("The data exceeds the maximum amount that can be send with this instruction.")
|
|
|
454 |
|
|
|
455 |
self.__myprint("Writing 0x%2x bytes to 0x%2x at I2C device at bus 0x%2x, slave adress 0x%2x ..." % (size, addr, bus, slave), silent)
|
|
|
456 |
|
| 67 |
benedikt93 |
457 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IBBBBII", 9, bus, slave, addr, size, 0, 0) + data)
|
|
|
458 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
459 |
self.__checkstatus(response)
|
| 56 |
benedikt93 |
460 |
|
|
|
461 |
self.__myprint(" done\n", silent)
|
|
|
462 |
|
| 67 |
benedikt93 |
463 |
|
| 56 |
benedikt93 |
464 |
#=====================================================================================
|
|
|
465 |
|
|
|
466 |
def readusbcon(self, size, outtype = "", file = "", silent = 0):
|
|
|
467 |
""" reads from USB console
|
| 82 |
benedikt93 |
468 |
<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
|
| 56 |
benedikt93 |
469 |
<outtype>: how the data will be put out
|
|
|
470 |
"file" => writes data to file <file>
|
|
|
471 |
"printstring" => prints data as a string to the console window
|
|
|
472 |
"printhex" => prints a hexview view of the data to the console window
|
|
|
473 |
"" => only returns the data
|
|
|
474 |
<silent>: if 0, nothing will be written to the console window (even if <outtype> defines something else)
|
|
|
475 |
|
|
|
476 |
in every case, the data will be returned in an array with additional information
|
|
|
477 |
[len, buffersize, datainbuffer, data]
|
|
|
478 |
where len is the length of the data actually read,
|
|
|
479 |
buffersize is the on-device read buffer size,
|
| 82 |
benedikt93 |
480 |
datainbuffer is the number of bytes still left in the on device buffer,
|
| 56 |
benedikt93 |
481 |
data is the actual data
|
| 82 |
benedikt93 |
482 |
|
|
|
483 |
in case that within 5 secs, it's not possible to read <size> bytes, a timeout will occur
|
| 56 |
benedikt93 |
484 |
"""
|
| 82 |
benedikt93 |
485 |
out_data = ""
|
|
|
486 |
readbytes = 0
|
|
|
487 |
buffersize = 0
|
|
|
488 |
bytesleft = 0
|
|
|
489 |
timeoutcounter = 0
|
| 56 |
benedikt93 |
490 |
|
|
|
491 |
self.__myprint("Reading 0x%x bytes from USB console..." % (size), silent)
|
|
|
492 |
|
| 82 |
benedikt93 |
493 |
while size > 0 and timoutcounter < 50:
|
|
|
494 |
blocklen = size
|
|
|
495 |
|
|
|
496 |
if size > self.cin_maxsize - 0x10:
|
|
|
497 |
blocklen = self.cin_maxsize - 0x10
|
|
|
498 |
|
|
|
499 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 10, blocklen, 0, 0))
|
|
|
500 |
response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)
|
|
|
501 |
self.__checkstatus(response)
|
|
|
502 |
|
| 108 |
theseven |
503 |
readbytes, buffersize, bytesleft = struct.unpack("<III", response[4:])
|
| 82 |
benedikt93 |
504 |
out_data += response[0x10:0x10+readbytes]
|
|
|
505 |
size -= blocklen
|
|
|
506 |
|
|
|
507 |
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
|
|
|
508 |
timeoutcounter += 1
|
|
|
509 |
time.sleep(0.1)
|
|
|
510 |
else:
|
|
|
511 |
timeoutcounter -= 3
|
|
|
512 |
if timeoutcounter < 0:
|
|
|
513 |
timeoutcounter = 0
|
|
|
514 |
|
|
|
515 |
self.__myprint(" done\n", silent)
|
|
|
516 |
self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
|
|
|
517 |
% (len(out_data), buffersize, bytesleft)
|
|
|
518 |
, silent)
|
| 56 |
benedikt93 |
519 |
|
|
|
520 |
if (outtype == "file"):
|
|
|
521 |
f = open(file, "wb")
|
| 82 |
benedikt93 |
522 |
f.write(out_data)
|
| 56 |
benedikt93 |
523 |
|
|
|
524 |
elif (outtype == "printstring"):
|
| 82 |
benedikt93 |
525 |
self.__myprint(out_data, silent)
|
| 56 |
benedikt93 |
526 |
self.__myprint("\n\n", silent)
|
|
|
527 |
|
|
|
528 |
elif (outtype == "printhex"):
|
| 82 |
benedikt93 |
529 |
self.__myprint(self.__gethexviewprintout(out_data, "", 1), silent)
|
| 56 |
benedikt93 |
530 |
self.__myprint("\n\n", silent)
|
| 67 |
benedikt93 |
531 |
|
|
|
532 |
elif (outtype == ""):
|
|
|
533 |
pass # return only
|
| 82 |
benedikt93 |
534 |
|
| 67 |
benedikt93 |
535 |
else:
|
| 64 |
benedikt93 |
536 |
raise Exception ("Invalid argument for <outtype>: '%s'." % (outtype))
|
| 56 |
benedikt93 |
537 |
|
| 82 |
benedikt93 |
538 |
return [len(out_data), buffersize, bytesleft, out_data]
|
| 56 |
benedikt93 |
539 |
|
|
|
540 |
|
| 64 |
benedikt93 |
541 |
def writeusbcon(self, data, silent = 0, *range):
|
| 56 |
benedikt93 |
542 |
""" writes to USB console
|
|
|
543 |
<data>: the data to be written
|
|
|
544 |
<range>: the range in <data> that should be written, in the from [offset, length]
|
|
|
545 |
<silent>: if 0, nothing will be written to the console window
|
|
|
546 |
|
| 82 |
benedikt93 |
547 |
if the data to be written exceeds the Command Out endpoint packet size - 0x10, it will be written in several steps
|
| 56 |
benedikt93 |
548 |
"""
|
|
|
549 |
size = len(data)
|
|
|
550 |
boffset = 0
|
|
|
551 |
|
|
|
552 |
if len(range) > 0:
|
|
|
553 |
boffset = range[0]
|
|
|
554 |
if len(range) > 1:
|
|
|
555 |
size = range[1]
|
|
|
556 |
|
|
|
557 |
self.__myprint("Writing 0x%x bytes to USB console..." % (size), silent)
|
|
|
558 |
|
|
|
559 |
timeoutcounter = 0
|
|
|
560 |
|
| 82 |
benedikt93 |
561 |
while (size > 0) and (timeoutcounter < 50):
|
|
|
562 |
blocklen = size
|
|
|
563 |
if blocklen > self.cout_maxsize - 0x10:
|
|
|
564 |
blocklen = self.cout_maxsize - 0x10
|
|
|
565 |
|
|
|
566 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 11, size, 0, 0) + data[boffset:boffset+blocklen])
|
| 56 |
benedikt93 |
567 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
568 |
self.__checkstatus(response)
|
|
|
569 |
|
| 108 |
theseven |
570 |
sendbytes = struct.unpack("<I", response[4:])[0]
|
| 82 |
benedikt93 |
571 |
if sendbytes < blocklen: # not everything has been written, need to resent some stuff but wait a bit before doing so
|
|
|
572 |
time.sleep(0.1)
|
|
|
573 |
timeoutcounter += 1
|
|
|
574 |
elif timeoutcounter > 0: # lower timeoutcounter again
|
|
|
575 |
timeoutcounter -= 3
|
|
|
576 |
if timeoutcounter < 0:
|
|
|
577 |
timeoutcounter = 0
|
| 56 |
benedikt93 |
578 |
|
| 82 |
benedikt93 |
579 |
size -= sendbytes
|
|
|
580 |
boffset += sendbytes
|
|
|
581 |
|
| 56 |
benedikt93 |
582 |
|
| 82 |
benedikt93 |
583 |
if (timeoutcounter >=50):
|
|
|
584 |
raise Exception("Timeout, 0x%x bytes couldn't be send." % size)
|
| 56 |
benedikt93 |
585 |
|
|
|
586 |
self.__myprint(" done\n", silent)
|
|
|
587 |
|
| 82 |
benedikt93 |
588 |
return size # number of bytes that have not been sent
|
|
|
589 |
|
| 56 |
benedikt93 |
590 |
|
| 82 |
benedikt93 |
591 |
def readdevcon(self, bitmask, size, outtype = "", file = "", silent = 0):
|
|
|
592 |
""" reads from one or more of the device's consoles
|
|
|
593 |
<bitmask>: bitmask of consoles to be read from
|
|
|
594 |
<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
|
|
|
595 |
<outtype>: how the data will be put out
|
|
|
596 |
"file" => writes data to file <file>
|
|
|
597 |
"printstring" => prints data as a string to the console window
|
|
|
598 |
"printhex" => prints a hexview view of the data to the console window
|
|
|
599 |
"" => only returns the data
|
|
|
600 |
<silent>: if 0, nothing will be written to the console window (even if <outtype> defines something else)
|
|
|
601 |
|
|
|
602 |
in every case, the data will be returned
|
|
|
603 |
|
|
|
604 |
in case that within 5 secs, it's not possible to read <size> bytes, a timeout will occur
|
|
|
605 |
"""
|
|
|
606 |
out_data = ""
|
|
|
607 |
readbytes = 0
|
|
|
608 |
timeoutcounter = 0
|
|
|
609 |
|
|
|
610 |
self.__myprint("Reading 0x%x bytes from device's console(s)..." % (size), silent)
|
|
|
611 |
|
|
|
612 |
while size > 0 and timoutcounter < 50:
|
|
|
613 |
blocklen = size
|
|
|
614 |
|
|
|
615 |
if size > self.cin_maxsize - 0x10:
|
|
|
616 |
blocklen = self.cin_maxsize - 0x10
|
|
|
617 |
|
|
|
618 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 13, bitmask, blocklen, 0))
|
|
|
619 |
response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)
|
|
|
620 |
self.__checkstatus(response)
|
|
|
621 |
|
| 108 |
theseven |
622 |
readbytes = struct.unpack("<III", response[4:])[0]
|
| 82 |
benedikt93 |
623 |
out_data += response[0x10:0x10+readbytes]
|
|
|
624 |
size -= blocklen
|
|
|
625 |
|
|
|
626 |
if not readbytes > 0: # no data read => wait a bit and prevent an infinite loop trying to read data when there is none
|
|
|
627 |
timeoutcounter += 1
|
|
|
628 |
time.sleep(0.1)
|
|
|
629 |
else:
|
|
|
630 |
timeoutcounter -= 3
|
|
|
631 |
if timeoutcounter < 0:
|
|
|
632 |
timeoutcounter = 0
|
|
|
633 |
|
|
|
634 |
self.__myprint(" done\n", silent)
|
|
|
635 |
self.__myprint("\nBytes read: 0x%x\n\n" % (len(out_data)), silent)
|
|
|
636 |
|
|
|
637 |
if (outtype == "file"):
|
|
|
638 |
f = open(file, "wb")
|
|
|
639 |
f.write(out_data)
|
|
|
640 |
|
|
|
641 |
elif (outtype == "printstring"):
|
|
|
642 |
self.__myprint(out_data, silent)
|
|
|
643 |
self.__myprint("\n\n", silent)
|
|
|
644 |
|
|
|
645 |
elif (outtype == "printhex"):
|
|
|
646 |
self.__myprint(self.__gethexviewprintout(out_data, "", 1), silent)
|
|
|
647 |
self.__myprint("\n\n", silent)
|
|
|
648 |
|
|
|
649 |
elif (outtype == ""):
|
|
|
650 |
pass # return only
|
|
|
651 |
|
|
|
652 |
else:
|
|
|
653 |
raise Exception ("Invalid argument for <outtype>: '%s'." % (outtype))
|
|
|
654 |
|
|
|
655 |
return out_data
|
|
|
656 |
|
|
|
657 |
|
|
|
658 |
def writedevcon(self, bitmask, data, silent = 0, *range):
|
|
|
659 |
""" writes to USB console
|
|
|
660 |
<bitmask>: bitmask of consoles to be written to
|
|
|
661 |
<data>: the data to be written
|
|
|
662 |
<range>: the range in <data> that should be written, in the from [offset, length]
|
|
|
663 |
<silent>: if 0, nothing will be written to the console window
|
|
|
664 |
|
|
|
665 |
if the data to be written exceeds the Command Out endpoint packet size - 0x10, it will be written in several steps
|
|
|
666 |
"""
|
|
|
667 |
size = len(data)
|
|
|
668 |
boffset = 0
|
|
|
669 |
|
|
|
670 |
if len(range) > 0:
|
|
|
671 |
boffset = range[0]
|
|
|
672 |
if len(range) > 1:
|
|
|
673 |
size = range[1]
|
|
|
674 |
|
|
|
675 |
self.__myprint("Writing 0x%x bytes to device's console(s)..." % (size), silent)
|
|
|
676 |
|
|
|
677 |
timeoutcounter = 0
|
|
|
678 |
|
|
|
679 |
while size > 0:
|
|
|
680 |
blocklen = size
|
|
|
681 |
if blocklen > self.cout_maxsize - 0x10:
|
|
|
682 |
blocklen = self.cout_maxsize - 0x10
|
|
|
683 |
|
|
|
684 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 12, bitmask, size, 0) + data[boffset:boffset+blocklen])
|
|
|
685 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
686 |
self.__checkstatus(response)
|
|
|
687 |
|
|
|
688 |
size -= blocklen
|
|
|
689 |
boffset += blocklen
|
|
|
690 |
|
|
|
691 |
self.__myprint(" done\n", silent)
|
|
|
692 |
|
|
|
693 |
|
| 56 |
benedikt93 |
694 |
def flushconsolebuffers(self, bitmask, silent = 0):
|
|
|
695 |
self.__myprint("Flushing device console('s) buffer('s)...")
|
|
|
696 |
|
|
|
697 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 14, bitmask, 0, 0))
|
|
|
698 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
699 |
self.__checkstatus(response)
|
|
|
700 |
|
|
|
701 |
self.__myprint(" done\n")
|
|
|
702 |
|
|
|
703 |
|
|
|
704 |
#=====================================================================================
|
|
|
705 |
|
|
|
706 |
|
|
|
707 |
def freezescheduler(self, freeze, silent = 0):
|
|
|
708 |
if (freeze):
|
|
|
709 |
self.__myprint("Freezing scheduler...", silent)
|
|
|
710 |
freeze = 1
|
| 64 |
benedikt93 |
711 |
else:
|
| 56 |
benedikt93 |
712 |
self.__myprint("Unfreezing scheduler...", silent)
|
|
|
713 |
freeze = 0
|
|
|
714 |
|
|
|
715 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 16, freeze, 0, 0))
|
|
|
716 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
717 |
self.__checkstatus(response)
|
|
|
718 |
|
|
|
719 |
self.__myprint(" done\n", silent)
|
|
|
720 |
|
|
|
721 |
|
|
|
722 |
def suspendthread(self, suspend, threadid, silent = 0):
|
|
|
723 |
if (suspend):
|
| 94 |
benedikt93 |
724 |
self.__myprint("Suspending thread 0x%08x..." % threadid, silent)
|
| 56 |
benedikt93 |
725 |
suspend = 1
|
| 64 |
benedikt93 |
726 |
else:
|
| 94 |
benedikt93 |
727 |
self.__myprint("Unsuspending thread 0x%08x..." % threadid, silent)
|
| 56 |
benedikt93 |
728 |
suspend = 0
|
|
|
729 |
|
|
|
730 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 17, suspend, threadid, 0))
|
|
|
731 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
732 |
self.__checkstatus(response)
|
|
|
733 |
|
|
|
734 |
self.__myprint(" done\n", silent)
|
|
|
735 |
|
|
|
736 |
|
|
|
737 |
def killthread(self, threadid, silent = 0):
|
| 94 |
benedikt93 |
738 |
self.__myprint("Killing thread 0x%08x..." % threadid, silent)
|
| 56 |
benedikt93 |
739 |
|
|
|
740 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 18, threadid, 0, 0))
|
|
|
741 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
742 |
self.__checkstatus(response)
|
|
|
743 |
|
|
|
744 |
self.__myprint(" done\n", silent)
|
|
|
745 |
|
|
|
746 |
|
|
|
747 |
def createthread(self, namepointer, entrypoint, stackpointer, stacksize, type, priority, state, silent = 0):
|
|
|
748 |
self.__myprint("Creating thread...", silent)
|
|
|
749 |
|
|
|
750 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIIIIIII", 19, namepointer, entrypoint, stackpointer, stacksize, type, priority, state))
|
|
|
751 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
752 |
self.__checkstatus(response)
|
|
|
753 |
|
| 106 |
benedikt93 |
754 |
if (struct.unpack("<i", response[4:8])[0] < 0):
|
|
|
755 |
self.__myprint(" failed, error code: 0x%x" % (struct.unpack("<i", response[4:8])[0]), silent)
|
| 64 |
benedikt93 |
756 |
else:
|
| 106 |
benedikt93 |
757 |
self.__myprint(" done\n, thread ID: 0x%x" % (struct.unpack("<I", response[4:8])[0]), silent)
|
| 56 |
benedikt93 |
758 |
|
|
|
759 |
|
| 101 |
benedikt93 |
760 |
def getprocinfo(self, silent = 0):
|
| 56 |
benedikt93 |
761 |
"""
|
|
|
762 |
printout on console window:
|
|
|
763 |
<silent> = 0: Process information struct version, Process information table size
|
|
|
764 |
<silent> = 1: nothing
|
|
|
765 |
"""
|
| 137 |
benedikt93 |
766 |
# inline functions ----------------------------------------------
|
| 102 |
benedikt93 |
767 |
def procinfotolist(processinfo, structver):
|
| 101 |
benedikt93 |
768 |
if (structver == 1): # Process information struct version == 1
|
| 108 |
theseven |
769 |
ptr = 0
|
| 101 |
benedikt93 |
770 |
process_n = 0
|
|
|
771 |
retval = []
|
|
|
772 |
while ptr < len(processinfo):
|
| 139 |
benedikt93 |
773 |
if struct.unpack("<I", processinfo[ptr + 68:ptr + 72])[0] == 0: # THREAD_FREE
|
|
|
774 |
ptr += 120
|
|
|
775 |
process_n += 1
|
|
|
776 |
continue
|
| 137 |
benedikt93 |
777 |
|
| 101 |
benedikt93 |
778 |
retval.append({})
|
| 56 |
benedikt93 |
779 |
|
| 108 |
theseven |
780 |
retval[process_n]['regs'] = struct.unpack("<IIIIIIIIIIIIIIII", processinfo[ptr:ptr + 64])
|
| 101 |
benedikt93 |
781 |
ptr += 16 * 0x4
|
| 137 |
benedikt93 |
782 |
retval[process_n]['cpsr'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]
|
| 101 |
benedikt93 |
783 |
ptr += 1 * 0x4
|
| 137 |
benedikt93 |
784 |
retval[process_n]['state'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]
|
| 101 |
benedikt93 |
785 |
ptr += 1 * 0x4
|
| 137 |
benedikt93 |
786 |
retval[process_n]['name_ptr'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]
|
| 101 |
benedikt93 |
787 |
ptr += 1 * 0x4
|
| 137 |
benedikt93 |
788 |
retval[process_n]['cputime_current'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]
|
| 101 |
benedikt93 |
789 |
ptr += 1 * 0x4
|
| 108 |
theseven |
790 |
retval[process_n]['cputime_total'] = struct.unpack("<Q", processinfo[ptr:ptr + 8])[0]
|
| 101 |
benedikt93 |
791 |
ptr += 1 * 0x8
|
| 137 |
benedikt93 |
792 |
retval[process_n]['startusec'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]
|
| 101 |
benedikt93 |
793 |
ptr += 1 * 0x4
|
| 137 |
benedikt93 |
794 |
retval[process_n]['queue_next_ptr'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]
|
| 101 |
benedikt93 |
795 |
ptr += 1 * 0x4
|
| 137 |
benedikt93 |
796 |
retval[process_n]['timeout'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]
|
| 101 |
benedikt93 |
797 |
ptr += 1 * 0x4
|
| 137 |
benedikt93 |
798 |
retval[process_n]['blocked_since'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]
|
| 101 |
benedikt93 |
799 |
ptr += 1 * 0x4
|
| 137 |
benedikt93 |
800 |
retval[process_n]['blocked_by_ptr'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]
|
| 101 |
benedikt93 |
801 |
ptr += 1 * 0x4
|
| 137 |
benedikt93 |
802 |
retval[process_n]['stack_ptr'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]
|
| 101 |
benedikt93 |
803 |
ptr += 1 * 0x4
|
| 137 |
benedikt93 |
804 |
retval[process_n]['err_no'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]
|
| 101 |
benedikt93 |
805 |
ptr += 1 * 0x4
|
| 137 |
benedikt93 |
806 |
retval[process_n]['block_type'] = struct.unpack("<B", processinfo[ptr:ptr + 1])[0]
|
| 101 |
benedikt93 |
807 |
ptr += 1 * 0x1
|
| 137 |
benedikt93 |
808 |
retval[process_n]['thread_type'] = struct.unpack("<B", processinfo[ptr:ptr + 1])[0]
|
| 101 |
benedikt93 |
809 |
ptr += 1 * 0x1
|
| 137 |
benedikt93 |
810 |
retval[process_n]['priority'] = struct.unpack("<B", processinfo[ptr:ptr + 1])[0]
|
| 101 |
benedikt93 |
811 |
ptr += 1 * 0x1
|
| 137 |
benedikt93 |
812 |
retval[process_n]['cpuload'] = struct.unpack("<B", processinfo[ptr:ptr + 1])[0]
|
| 101 |
benedikt93 |
813 |
ptr += 1 * 0x1
|
| 56 |
benedikt93 |
814 |
|
| 101 |
benedikt93 |
815 |
process_n += 1
|
| 56 |
benedikt93 |
816 |
|
| 101 |
benedikt93 |
817 |
return retval
|
| 129 |
benedikt93 |
818 |
|
|
|
819 |
|
| 137 |
benedikt93 |
820 |
def state2name(state, structver):
|
|
|
821 |
if structver == 1:
|
|
|
822 |
if state == 0: return "THREAD_FREE"
|
|
|
823 |
elif state == 1: return "THREAD_SUSPENDED"
|
|
|
824 |
elif state == 2: return "THREAD_READY"
|
|
|
825 |
elif state == 3: return "THREAD_RUNNING"
|
|
|
826 |
elif state == 4: return "THREAD_BLOCKED"
|
|
|
827 |
elif state == 5: return "THREAD_DEFUNCT"
|
|
|
828 |
elif state == 6: return "THREAD_DEFUNCT_ACK"
|
|
|
829 |
else: return "UNKNOWN"
|
| 129 |
benedikt93 |
830 |
else: return "UNKNOWN"
|
|
|
831 |
|
| 137 |
benedikt93 |
832 |
def blocktype2name(blocktype, structver):
|
|
|
833 |
if structver == 1:
|
|
|
834 |
if blocktype == 0: return "THREAD_NOT_BLOCKED"
|
|
|
835 |
elif blocktype == 1: return "THREAD_BLOCK_SLEEP"
|
|
|
836 |
elif blocktype == 2: return "THREAD_BLOCK_MUTEX"
|
|
|
837 |
elif blocktype == 3: return "THREAD_BLOCK_WAKEUP"
|
|
|
838 |
elif blocktype == 4: return "THREAD_DEFUNCT_STKOV"
|
|
|
839 |
elif blocktype == 5: return "THREAD_DEFUNCT_PANIC"
|
|
|
840 |
else: return "UNKNOWN"
|
| 129 |
benedikt93 |
841 |
else: return "UNKNOWN"
|
|
|
842 |
|
| 137 |
benedikt93 |
843 |
def threadtype2name (threadtype, structver):
|
|
|
844 |
if structver == 1:
|
|
|
845 |
if threadtype == 0: return "USER_THREAD"
|
|
|
846 |
elif threadtype == 1: return "OS_THREAD"
|
|
|
847 |
elif threadtype == 2: return "CORE_THREAD"
|
|
|
848 |
else: return "UNKNOWN"
|
| 129 |
benedikt93 |
849 |
else: return "UNKNOWN"
|
|
|
850 |
|
| 102 |
benedikt93 |
851 |
def procinfotostring(procinfolist, structver):
|
| 101 |
benedikt93 |
852 |
processinfoprint = ""
|
|
|
853 |
ptr = 0
|
|
|
854 |
while structver == 1 and ptr < len(procinfolist): # Process information struct version == 1
|
| 119 |
benedikt93 |
855 |
processinfoprint += "--------------------------------------------------------------------------------\n"
|
|
|
856 |
processinfoprint += "R0: 0x%08x, R1: 0x%08x, R2: 0x%08x, R3: 0x%08x,\n"\
|
|
|
857 |
% (procinfolist[ptr]['regs'][0], procinfolist[ptr]['regs'][1], procinfolist[ptr]['regs'][2], procinfolist[ptr]['regs'][3])\
|
|
|
858 |
+ "R4: 0x%08x, R5: 0x%08x, R6: 0x%08x, R7: 0x%08x,\n"\
|
|
|
859 |
% (procinfolist[ptr]['regs'][4], procinfolist[ptr]['regs'][5], procinfolist[ptr]['regs'][6], procinfolist[ptr]['regs'][7])\
|
|
|
860 |
+ "R8: 0x%08x, R9: 0x%08x, R10: 0x%08x, R11: 0x%08x,\n"\
|
|
|
861 |
% (procinfolist[ptr]['regs'][8], procinfolist[ptr]['regs'][9], procinfolist[ptr]['regs'][10], procinfolist[ptr]['regs'][11])\
|
|
|
862 |
+ "R12: 0x%08x, SP: 0x%08x, LR: 0x%08x, PC: 0x%08x\n" \
|
|
|
863 |
% (procinfolist[ptr]['regs'][12], procinfolist[ptr]['regs'][13], procinfolist[ptr]['regs'][14], procinfolist[ptr]['regs'][15])
|
| 108 |
theseven |
864 |
processinfoprint += "cpsr: 0x%08x " % (procinfolist[ptr]['cpsr'])
|
| 137 |
benedikt93 |
865 |
processinfoprint += "state: %s " % (state2name([procinfolist[ptr]['state']], structver))
|
| 101 |
benedikt93 |
866 |
processinfoprint += "nameptr: 0x%08x\n" % (procinfolist[ptr]['name_ptr'])
|
|
|
867 |
processinfoprint += "current cpu time: 0x%08x " % (procinfolist[ptr]['cputime_current'])
|
|
|
868 |
processinfoprint += "total cpu time: 0x%016x\n" % (procinfolist[ptr]['cputime_total'])
|
|
|
869 |
processinfoprint += "startusec: 0x%08x " % (procinfolist[ptr]['startusec'])
|
|
|
870 |
processinfoprint += "queue next ptr: 0x%08x\n" % (procinfolist[ptr]['queue_next_ptr'])
|
|
|
871 |
processinfoprint += "timeout: 0x%08x\n" % (procinfolist[ptr]['timeout'])
|
|
|
872 |
processinfoprint += "blocked since: 0x%08x " % (procinfolist[ptr]['blocked_since'])
|
|
|
873 |
processinfoprint += "blocked by ptr: 0x%08x\n" % (procinfolist[ptr]['blocked_by_ptr'])
|
|
|
874 |
processinfoprint += "err_no: 0x%08x " % (procinfolist[ptr]['err_no'])
|
| 137 |
benedikt93 |
875 |
processinfoprint += "block type: %s\n" % (blocktype2name([procinfolist[ptr]['block_type']], structver))
|
|
|
876 |
processinfoprint += "thread type: %s\n" % (threadtype2name([procinfolist[ptr]['thread_type']], structver))
|
| 101 |
benedikt93 |
877 |
processinfoprint += "priority: 0x%02x " % (procinfolist[ptr]['priority'])
|
|
|
878 |
processinfoprint += "cpu load: 0x%02x\n" % (procinfolist[ptr]['cpuload'])
|
| 119 |
benedikt93 |
879 |
|
|
|
880 |
ptr += 1
|
| 67 |
benedikt93 |
881 |
|
| 119 |
benedikt93 |
882 |
processinfoprint += "--------------------------------------------------------------------------------\n"
|
|
|
883 |
|
| 101 |
benedikt93 |
884 |
return processinfoprint
|
| 102 |
benedikt93 |
885 |
|
| 137 |
benedikt93 |
886 |
# reading code --------------------------------------------------
|
| 102 |
benedikt93 |
887 |
self.__myprint("Retrieving process information...", silent)
|
| 56 |
benedikt93 |
888 |
|
| 102 |
benedikt93 |
889 |
offset = 0
|
| 108 |
theseven |
890 |
blocklen = tablesize = self.cin_maxsize - 0x10
|
| 102 |
benedikt93 |
891 |
procinfo = ""
|
|
|
892 |
structversion = 0
|
| 56 |
benedikt93 |
893 |
|
| 102 |
benedikt93 |
894 |
# reading loop
|
| 108 |
theseven |
895 |
while (offset < tablesize):
|
| 106 |
benedikt93 |
896 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 15, offset, blocklen, 0))
|
|
|
897 |
response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)
|
| 102 |
benedikt93 |
898 |
self.__checkstatus(response)
|
|
|
899 |
|
| 108 |
theseven |
900 |
tablesize = struct.unpack("<I", response[8:12])[0]
|
| 102 |
benedikt93 |
901 |
|
| 108 |
theseven |
902 |
if tablesize <= offset + blocklen:
|
| 119 |
benedikt93 |
903 |
blocklen = tablesize - offset
|
|
|
904 |
procinfo += response[0x10:0x10 + blocklen]
|
| 107 |
benedikt93 |
905 |
structversion = struct.unpack("<I", response[4:8])[0]
|
|
|
906 |
tablesize = struct.unpack("<I", response[8:12])[0]
|
| 119 |
benedikt93 |
907 |
else:
|
|
|
908 |
procinfo += response[0x10:0x10 + blocklen]
|
| 102 |
benedikt93 |
909 |
|
|
|
910 |
offset += blocklen
|
|
|
911 |
|
|
|
912 |
blocklen = self.cin_maxsize - 0x10
|
| 108 |
theseven |
913 |
if blocklen > tablesize - offset:
|
|
|
914 |
blocklen = tablesize - offset
|
| 56 |
benedikt93 |
915 |
|
|
|
916 |
|
| 102 |
benedikt93 |
917 |
out = (structversion, tablesize, procinfotolist(procinfo, structversion))
|
|
|
918 |
|
| 119 |
benedikt93 |
919 |
self.__myprint(" done\n"\
|
|
|
920 |
+ "Process information struct version: 0x%08x\n" % out[0]\
|
|
|
921 |
+ "Total size of process information table: 0x%08x\n" % out[1]\
|
|
|
922 |
+ procinfotostring(out[2], 1)\
|
|
|
923 |
+ "\n\n")
|
| 102 |
benedikt93 |
924 |
|
|
|
925 |
return out
|
|
|
926 |
|
|
|
927 |
|
| 96 |
benedikt93 |
928 |
def execimage(self, offset, silent = 0):
|
| 94 |
benedikt93 |
929 |
self.__myprint("Executing emBIOS executable image at 0x%08x..." % offset, silent)
|
|
|
930 |
|
| 99 |
theseven |
931 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 21, offset, 0, 0))
|
| 94 |
benedikt93 |
932 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
933 |
self.__checkstatus(response)
|
| 56 |
benedikt93 |
934 |
|
| 107 |
benedikt93 |
935 |
self.__myprint(" done\n execimage() return code: 0x%08x\n" % struct.unpack("<I", response[4:8])[0], silent)
|
| 94 |
benedikt93 |
936 |
|
| 107 |
benedikt93 |
937 |
return struct.unpack("<I", response[4:8])[0]
|
| 94 |
benedikt93 |
938 |
|
|
|
939 |
|
| 135 |
benedikt93 |
940 |
def execfirmware(self, offset, silent = 0):
|
|
|
941 |
self.__myprint("Executing firmware image at 0x%08x..." % offset, silent)
|
|
|
942 |
|
|
|
943 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 24, offset, 0, 0))
|
|
|
944 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
945 |
self.__checkstatus(response)
|
|
|
946 |
|
|
|
947 |
self.__myprint(" done\n", silent)
|
|
|
948 |
|
|
|
949 |
return
|
|
|
950 |
|
|
|
951 |
|
| 56 |
benedikt93 |
952 |
#=====================================================================================
|
|
|
953 |
|
| 96 |
benedikt93 |
954 |
|
|
|
955 |
def readrawbootflash(self, addr_bootflsh, addr_mem, size, silent = 0):
|
|
|
956 |
self.__myprint("Reading 0x%x bytes from 0x%08x at bootflash to 0x%08x..." % (size, addr_bootflsh, addr_mem), silent)
|
|
|
957 |
|
|
|
958 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 22, addr_mem, addr_bootflsh, size))
|
|
|
959 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
960 |
self.__checkstatus(response)
|
|
|
961 |
|
|
|
962 |
self.__myprint(" done\n", silent)
|
|
|
963 |
|
|
|
964 |
|
|
|
965 |
def writerawbootflash(self, addr_mem, addr_bootflsh, size, silent = 0):
|
|
|
966 |
self.__myprint("Writing 0x%x bytes from 0x%08x to bootflash at 0x%08x..." % (size, addr_fmem, addr_bootflsh), silent)
|
|
|
967 |
|
|
|
968 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 23, addr_mem, addr_bootflsh, size))
|
|
|
969 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
970 |
self.__checkstatus(response)
|
|
|
971 |
|
|
|
972 |
self.__myprint(" done\n", silent)
|
|
|
973 |
|
|
|
974 |
|
|
|
975 |
#=====================================================================================
|
|
|
976 |
|
| 56 |
benedikt93 |
977 |
|
|
|
978 |
def flushcaches(self, silent = 0):
|
|
|
979 |
self.__myprint("Flushing caches...", silent)
|
|
|
980 |
|
|
|
981 |
self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 20, 0, 0, 0))
|
|
|
982 |
response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
|
|
983 |
self.__checkstatus(response)
|
|
|
984 |
|
|
|
985 |
self.__myprint(" done\n", silent)
|
|
|
986 |
|
|
|
987 |
|
|
|
988 |
#======================================================================================
|
| 82 |
benedikt93 |
989 |
# backlight control, remnant from libibugger adjusted to work with libembios ==========
|
| 56 |
benedikt93 |
990 |
|
|
|
991 |
|
|
|
992 |
def backlighton(self, fade, brightness, silent = 0):
|
|
|
993 |
self.__myprint("Turning on backlight...", silent)
|
|
|
994 |
if self.devtype == 2:
|
|
|
995 |
self.i2csend(0, 0xe6, 0x2b, struct.pack("<B", fade), 1)
|
|
|
996 |
self.i2csend(0, 0xe6, 0x28, struct.pack("<B", int(brightness * 46)), 1)
|
|
|
997 |
self.i2csend(0, 0xe6, 0x29, struct.pack("<B", 1), 1)
|
|
|
998 |
self.__myprint(" done\n", silent)
|
|
|
999 |
elif self.devtype == 4:
|
|
|
1000 |
self.i2csend(0, 0xe6, 0x30, struct.pack("<B", int(brightness * 250)), 1)
|
|
|
1001 |
self.i2csend(0, 0xe6, 0x31, struct.pack("<B", 3), 1)
|
|
|
1002 |
self.__myprint(" done\n", silent)
|
|
|
1003 |
else: self.__myprint(" unsupported (%s)\n" % self.devtype2name(self.devtype), silent)
|
|
|
1004 |
|
|
|
1005 |
|
|
|
1006 |
def backlightoff(self, fade, silent = 0):
|
|
|
1007 |
self.__myprint("Turning off backlight...", silent)
|
|
|
1008 |
if self.devtype == 2:
|
|
|
1009 |
self.i2csend(0, 0xe6, 0x2b, struct.pack("<B", fade), 1)
|
|
|
1010 |
self.i2csend(0, 0xe6, 0x29, struct.pack("<B", 0), 1)
|
|
|
1011 |
self.__myprint(" done\n", silent)
|
|
|
1012 |
elif self.devtype == 4:
|
|
|
1013 |
self.i2csend(0, 0xe6, 0x31, struct.pack("<B", 2), 1)
|
|
|
1014 |
self.__myprint(" done\n", silent)
|
|
|
1015 |
else: self.__myprint(" unsupported (%s)\n" % self.devtype2name(self.devtype), silent)
|
| 123 |
cmwslw |
1016 |
|