| 82 |
benedikt93 |
1 |
#!/usr/bin/env python
|
| 64 |
benedikt93 |
2 |
#
|
|
|
3 |
#
|
| 171 |
farthen |
4 |
# Copyright 2010 TheSeven, benedikt93, Farthen
|
| 64 |
benedikt93 |
5 |
#
|
|
|
6 |
#
|
| 82 |
benedikt93 |
7 |
# This file is part of emBIOS.
|
| 64 |
benedikt93 |
8 |
#
|
| 82 |
benedikt93 |
9 |
# emBIOS is free software: you can redistribute it and/or
|
| 64 |
benedikt93 |
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 |
#
|
| 82 |
benedikt93 |
14 |
# emBIOS is distributed in the hope that it will be useful,
|
| 64 |
benedikt93 |
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 |
#
|
| 82 |
benedikt93 |
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/>.
|
| 64 |
benedikt93 |
21 |
#
|
|
|
22 |
#
|
|
|
23 |
|
| 171 |
farthen |
24 |
import sys
|
|
|
25 |
import os
|
|
|
26 |
import inspect
|
|
|
27 |
import re
|
| 64 |
benedikt93 |
28 |
|
|
|
29 |
import libembios
|
| 171 |
farthen |
30 |
from libembios import Error
|
|
|
31 |
import libembiosdata
|
| 64 |
benedikt93 |
32 |
|
| 171 |
farthen |
33 |
class NotImplementedError(Error):
|
|
|
34 |
pass
|
| 64 |
benedikt93 |
35 |
|
| 171 |
farthen |
36 |
class ArgumentError(Error):
|
|
|
37 |
pass
|
| 64 |
benedikt93 |
38 |
|
| 171 |
farthen |
39 |
class ArgumentTypeError(Error):
|
|
|
40 |
def __init__(self, expected, seen=False):
|
|
|
41 |
self.expected = expected
|
|
|
42 |
self.seen = seen
|
|
|
43 |
def __str__(self):
|
|
|
44 |
if self.seen:
|
|
|
45 |
return "Expected " + str(self.expected) + " but saw " + str(self.seen)
|
|
|
46 |
else:
|
|
|
47 |
return "Expected " + str(self.expected) + ", but saw something else"
|
| 64 |
benedikt93 |
48 |
|
|
|
49 |
|
| 171 |
farthen |
50 |
def usage(errormsg=None, specific=False):
|
|
|
51 |
"""
|
|
|
52 |
Prints the usage information.
|
|
|
53 |
It is auto generated from various places.
|
|
|
54 |
"""
|
|
|
55 |
logger = Logger()
|
|
|
56 |
cmddict= Commandline.cmddict
|
|
|
57 |
doc = {}
|
|
|
58 |
# This sorts the output of various internal functions
|
|
|
59 |
# and puts everything in easy readable form
|
|
|
60 |
for function in cmddict:
|
|
|
61 |
function = cmddict[function].func
|
|
|
62 |
docinfo = {}
|
|
|
63 |
name = function.__name__
|
|
|
64 |
args = inspect.getargspec(function)[0]
|
|
|
65 |
docinfo['varargs'] = False
|
|
|
66 |
if inspect.getargspec(function)[1]:
|
|
|
67 |
docinfo['varargs'] = True
|
|
|
68 |
kwargvalues = inspect.getargspec(function)[3]
|
|
|
69 |
kwargs = {}
|
|
|
70 |
if args:
|
|
|
71 |
if kwargvalues:
|
|
|
72 |
argnum = len(args) - len(kwargvalues)
|
|
|
73 |
kwargnum = len(kwargvalues)
|
|
|
74 |
kwargs = dict(zip(args[argnum:], kwargvalues))
|
|
|
75 |
else:
|
|
|
76 |
argnum = len(args)
|
|
|
77 |
else:
|
|
|
78 |
argnum = 0
|
|
|
79 |
docinfo['args'] = args[1:argnum]
|
|
|
80 |
docinfo['kwargs'] = kwargs
|
|
|
81 |
if function.__doc__:
|
|
|
82 |
# strip unneccessary whitespace
|
|
|
83 |
docinfo['documentation'] = re.sub(r'\n ', '\n', function.__doc__)
|
|
|
84 |
else:
|
|
|
85 |
docinfo['documentation'] = None
|
|
|
86 |
doc[name] = docinfo
|
| 64 |
benedikt93 |
87 |
|
| 171 |
farthen |
88 |
if not specific:
|
|
|
89 |
logger.log("Please provide a command and (if needed) parameters as command line arguments\n\n")
|
|
|
90 |
logger.log("Available commands:\n\n")
|
| 82 |
benedikt93 |
91 |
else:
|
| 171 |
farthen |
92 |
logger.log("\n")
|
|
|
93 |
for function in sorted(doc.items()):
|
|
|
94 |
function = function[0]
|
|
|
95 |
if specific == False or specific == function:
|
|
|
96 |
logger.log(" " + function + " ")
|
|
|
97 |
for arg in doc[function]['args']:
|
|
|
98 |
logger.log("<" + arg + "> ")
|
|
|
99 |
if doc[function]['kwargs']:
|
|
|
100 |
for kwarg in doc[function]['kwargs']:
|
|
|
101 |
logger.log("[" + kwarg + "] ")
|
|
|
102 |
if doc[function]['varargs']:
|
|
|
103 |
logger.log("<db1> ... <dbN>")
|
|
|
104 |
if doc[function]['documentation']:
|
|
|
105 |
logger.log(doc[function]['documentation']+"\n")
|
| 64 |
benedikt93 |
106 |
|
| 171 |
farthen |
107 |
logger.log("\n")
|
|
|
108 |
|
|
|
109 |
if errormsg:
|
|
|
110 |
logger.error(str(errormsg)+"\n")
|
|
|
111 |
exit(2)
|
|
|
112 |
|
|
|
113 |
|
|
|
114 |
class Logger(object):
|
|
|
115 |
"""
|
|
|
116 |
Simple stdout logger.
|
|
|
117 |
Loglevel 4 is most verbose, Loglevel 0 only say something if there is an error.
|
|
|
118 |
"""
|
|
|
119 |
def __init__(self):
|
|
|
120 |
# Possible values: 0 (only errors), 1 (warnings), 2 (info, recommended for production use), 3 and more (debug)
|
|
|
121 |
self.loglevel = 3
|
|
|
122 |
|
|
|
123 |
def log(self, text):
|
|
|
124 |
sys.stdout.write(text)
|
| 67 |
benedikt93 |
125 |
|
| 171 |
farthen |
126 |
def debug(self, text):
|
|
|
127 |
if self.loglevel >= 3:
|
|
|
128 |
self.log(text)
|
| 119 |
benedikt93 |
129 |
|
| 171 |
farthen |
130 |
def info(self, text):
|
|
|
131 |
if self.loglevel >= 2:
|
|
|
132 |
self.log(text)
|
| 82 |
benedikt93 |
133 |
|
| 171 |
farthen |
134 |
def warning(self, text):
|
|
|
135 |
if self.loglevel >= 1:
|
|
|
136 |
self.log("WARNING: " + text)
|
| 119 |
benedikt93 |
137 |
|
| 171 |
farthen |
138 |
def error(self, text):
|
|
|
139 |
self.log("ERROR: " + text)
|
|
|
140 |
|
|
|
141 |
|
|
|
142 |
def command(func):
|
|
|
143 |
"""
|
|
|
144 |
Decorator for all commands.
|
|
|
145 |
The decorated function is called with (self, all, other, arguments, ...)
|
|
|
146 |
"""
|
|
|
147 |
def decorator(args):
|
|
|
148 |
return func(args[0], *args[1:])
|
|
|
149 |
func._command = True
|
|
|
150 |
decorator.func = func
|
|
|
151 |
return decorator
|
|
|
152 |
|
|
|
153 |
|
|
|
154 |
def commandClass(cls):
|
|
|
155 |
"""
|
|
|
156 |
Decorator for the class. Sets the self.cmddict of the class
|
|
|
157 |
to all functions decorated with @command
|
|
|
158 |
"""
|
|
|
159 |
cls.cmddict = {}
|
|
|
160 |
for attr, value in cls.__dict__.iteritems():
|
|
|
161 |
if getattr(value, 'func', False):
|
|
|
162 |
if getattr(value.func, '_command', False):
|
|
|
163 |
cls.cmddict[value.func.__name__] = value
|
|
|
164 |
return cls
|
|
|
165 |
|
|
|
166 |
|
|
|
167 |
@commandClass
|
|
|
168 |
class Commandline(object):
|
|
|
169 |
"""
|
|
|
170 |
If you want to create a new commandline function you just need to
|
|
|
171 |
create a function with the name of it in this class and decorate
|
|
|
172 |
it with the decorator @command. If you don't want to call the desired
|
|
|
173 |
function (wrong arguments etc) just raise ArgumentError with or
|
|
|
174 |
without an error message or raise ArgumentCountError
|
|
|
175 |
"""
|
|
|
176 |
def __init__(self):
|
|
|
177 |
self.logger = Logger()
|
|
|
178 |
try:
|
|
|
179 |
self.embios = libembios.Embios()
|
|
|
180 |
except libembios.DeviceNotFoundError:
|
|
|
181 |
self.logger.error("No emBIOS device found!")
|
|
|
182 |
end(1)
|
|
|
183 |
|
|
|
184 |
def _parsecommand(self, func, args):
|
|
|
185 |
# adds self to the commandline args.
|
|
|
186 |
# this is needed because the functions need access to their class.
|
|
|
187 |
args.insert(0, self)
|
|
|
188 |
if func in self.cmddict:
|
|
|
189 |
try:
|
|
|
190 |
self.cmddict[func](args)
|
|
|
191 |
except ArgumentError, e:
|
|
|
192 |
usage(e)
|
|
|
193 |
except ArgumentError:
|
|
|
194 |
usage("Syntax Error in function '" + func + "'")
|
|
|
195 |
except ArgumentTypeError, e:
|
|
|
196 |
usage(e)
|
|
|
197 |
except NotImplementedError:
|
|
|
198 |
self.logger.error("This function is not implemented yet!")
|
|
|
199 |
except libembios.DeviceError, e:
|
|
|
200 |
self.logger.error(str(e))
|
|
|
201 |
except TypeError, e:
|
|
|
202 |
if str(e).split(" ", 1)[0] == func + "()":
|
|
|
203 |
self.logger.error(usage("Argument Error in '" + func + "': Wrong argument count", specific=func))
|
|
|
204 |
else:
|
|
|
205 |
raise
|
|
|
206 |
else:
|
|
|
207 |
usage("No such command")
|
| 67 |
benedikt93 |
208 |
|
| 171 |
farthen |
209 |
@staticmethod
|
|
|
210 |
def _bool(something):
|
|
|
211 |
"""
|
|
|
212 |
Converts quite everything into bool.
|
|
|
213 |
"""
|
|
|
214 |
if type(something) == bool:
|
|
|
215 |
return something
|
|
|
216 |
elif type(something) == int or type(something) == long:
|
|
|
217 |
return bool(something)
|
|
|
218 |
elif type(something == str):
|
|
|
219 |
truelist = ['true', '1', 't', 'y', 'yes']
|
|
|
220 |
falselist = ['false', '0', 'f', 'n', 'no']
|
|
|
221 |
if something.lower() in truelist:
|
|
|
222 |
return True
|
|
|
223 |
elif something.lower() in falselist:
|
|
|
224 |
return False
|
|
|
225 |
raise ArgumentTypeError("bool", "'"+str(something)+"'")
|
|
|
226 |
|
|
|
227 |
@staticmethod
|
|
|
228 |
def _hexint(something):
|
|
|
229 |
"""
|
|
|
230 |
Converts quite everything to a hexadecimal represented integer.
|
|
|
231 |
This works for default arguments too, because it returns
|
|
|
232 |
None when it found that it got a NoneType object.
|
|
|
233 |
"""
|
|
|
234 |
if type(something) == int or type(something) == long:
|
|
|
235 |
return something
|
|
|
236 |
elif type(something) == str:
|
|
|
237 |
try:
|
|
|
238 |
return int(something, 16)
|
|
|
239 |
except ValueError:
|
|
|
240 |
raise ArgumentTypeError("hexadecimal coded integer", "'"+str(something)+"'")
|
|
|
241 |
elif type(something) == NoneType:
|
|
|
242 |
return None
|
|
|
243 |
else:
|
|
|
244 |
raise ArgumentTypeError("hexadecimal coded integer", "'"+str(something)+"'")
|
|
|
245 |
|
|
|
246 |
@staticmethod
|
|
|
247 |
def _strcheck(string, values):
|
|
|
248 |
if string in values:
|
|
|
249 |
return string
|
|
|
250 |
else:
|
|
|
251 |
expected = ""
|
|
|
252 |
for item in values:
|
|
|
253 |
expected += "'" + item + "', "
|
|
|
254 |
expected = expected[:-2]
|
|
|
255 |
raise ArgumentTypeError("one out of " + expected, "'" + string + "'")
|
| 64 |
benedikt93 |
256 |
|
|
|
257 |
|
| 171 |
farthen |
258 |
@command
|
|
|
259 |
def getinfo(self, infotype):
|
|
|
260 |
"""
|
|
|
261 |
Get info on the running emBIOS.
|
|
|
262 |
<infotype> may be either of 'version', 'packetsize', 'usermemrange'.
|
|
|
263 |
"""
|
|
|
264 |
if infotype == "version":
|
|
|
265 |
resp = self.embios.getversioninfo()
|
|
|
266 |
self.logger.info(libembiosdata.swtypes[resp.swtypeid] + " v" + str(resp.majorv) + "." + str(resp.minorv) +
|
|
|
267 |
"." + str(resp.patchv) + " r" + str(resp.revision) + " running on " + libembiosdata.hwtypes[resp.hwtypeid] + "\n")
|
|
|
268 |
elif infotype == "packetsize":
|
|
|
269 |
resp = self.embios.getpacketsizeinfo()
|
|
|
270 |
self.logger.info("Maximum packet sizes: "+str(resp))
|
|
|
271 |
elif infotype == "usermemrange":
|
|
|
272 |
resp = self.embios.getusermemrange()
|
|
|
273 |
self.logger.info("The user memory range is "+hex(resp.lower)+" - "+hex(resp.upper-1))
|
|
|
274 |
else:
|
|
|
275 |
raise ArgumentTypeError("one out of 'version', 'packetsize', 'usermemrange'", infotype)
|
| 64 |
benedikt93 |
276 |
|
| 171 |
farthen |
277 |
@command
|
|
|
278 |
def reset(self, force=False):
|
|
|
279 |
"""
|
|
|
280 |
Resets the device"
|
|
|
281 |
If <force> is 1, the reset will be forced, otherwise it will be gracefully,
|
|
|
282 |
which may take some time.
|
|
|
283 |
"""
|
|
|
284 |
force = self._bool(force)
|
|
|
285 |
if force: self.logger.info("Resetting forcefully...\n")
|
|
|
286 |
else: self.logger.info("Resetting...\n")
|
|
|
287 |
self.embios.reset(force)
|
| 64 |
benedikt93 |
288 |
|
| 171 |
farthen |
289 |
@command
|
|
|
290 |
def poweroff(self, force=False):
|
|
|
291 |
"""
|
|
|
292 |
Powers the device off
|
|
|
293 |
If <force> is 1, the poweroff will be forced, otherwise it will be gracefully,
|
|
|
294 |
which may take some time.
|
|
|
295 |
"""
|
|
|
296 |
force = self._bool(force)
|
|
|
297 |
if force: self.logger.info("Resetting forcefully...\n")
|
|
|
298 |
else: self.logger.info("Resetting...\n")
|
|
|
299 |
self.embios.reset(force)
|
| 64 |
benedikt93 |
300 |
|
| 171 |
farthen |
301 |
@command
|
|
|
302 |
def uploadfile(self, addr, filename):
|
|
|
303 |
"""
|
|
|
304 |
Uploads a file to the device
|
|
|
305 |
<offset>: the address to upload the file to
|
|
|
306 |
<filename>: the path to the file
|
|
|
307 |
"""
|
|
|
308 |
addr = self._hexint(addr)
|
|
|
309 |
try:
|
|
|
310 |
f = open(filename, 'rb')
|
|
|
311 |
except IOError:
|
|
|
312 |
raise ArgumentError("File not readable. Does it exist?")
|
|
|
313 |
self.logger.info("Writing file '"+filename+"' to memory at "+hex(addr)+"...")
|
|
|
314 |
with f:
|
|
|
315 |
self.embios.write(addr, f.read())
|
|
|
316 |
self.logger.info("done\n")
|
|
|
317 |
|
|
|
318 |
|
|
|
319 |
|
|
|
320 |
@command
|
|
|
321 |
def downloadfile(self, addr, size, filename):
|
|
|
322 |
"""
|
|
|
323 |
Uploads a file to the device
|
|
|
324 |
<offset>: the address to upload the file to
|
|
|
325 |
<size>: the number of bytes to be read
|
|
|
326 |
<filename>: the path to the file
|
|
|
327 |
"""
|
|
|
328 |
addr = self._hexint(addr)
|
|
|
329 |
size = self._hexint(size)
|
|
|
330 |
try:
|
|
|
331 |
f = open(filename, 'wb')
|
|
|
332 |
except IOError:
|
|
|
333 |
raise ArgumentError("Can not open file for write!")
|
|
|
334 |
self.logger.info("Reading data from address "+hex(addr)+" with the size "+hex(size)+" to '"+filename+"'...")
|
|
|
335 |
with f:
|
|
|
336 |
f.write(self.embios.read(addr, size))
|
|
|
337 |
self.logger.info("done\n")
|
|
|
338 |
|
|
|
339 |
@command
|
|
|
340 |
def uploadint(self, addr, integer):
|
|
|
341 |
"""
|
|
|
342 |
Uploads a single integer to the device
|
|
|
343 |
<offset>: the address to upload the integer to
|
|
|
344 |
<data>: the integer to upload
|
|
|
345 |
"""
|
|
|
346 |
addr = self._hexint(addr)
|
|
|
347 |
integer = self._hexint(integer)
|
|
|
348 |
if integer > 0xFFFFFFFF:
|
|
|
349 |
raise ArgumentError("Specified integer too long")
|
|
|
350 |
data = chr(integer)
|
|
|
351 |
self.embios.writemem(addr, data)
|
|
|
352 |
self.logger.info("Integer '"+hex(integer)+"' written successfully to "+hex(addr))
|
|
|
353 |
|
|
|
354 |
@command
|
|
|
355 |
def downloadint(self, addr):
|
|
|
356 |
"""
|
|
|
357 |
Downloads a single integer from the device and prints it to the console window
|
|
|
358 |
<offset>: the address to download the integer from
|
|
|
359 |
"""
|
|
|
360 |
addr = self._hexint(addr)
|
|
|
361 |
data = self.embios.readmem(addr, 1)
|
|
|
362 |
integer = ord(data)
|
|
|
363 |
self.logger.info("Integer '"+hex(integer)+"' read from address "+hex(addr))
|
|
|
364 |
|
|
|
365 |
@command
|
|
|
366 |
def i2crecv(self, bus, slave, addr, size):
|
|
|
367 |
"""
|
|
|
368 |
Reads data from an I2C device
|
|
|
369 |
<bus> the bus index
|
|
|
370 |
<slave> the slave address
|
|
|
371 |
<addr> the start address on the I2C device
|
|
|
372 |
<size> the number of bytes to read
|
|
|
373 |
"""
|
|
|
374 |
bus = self._hexint(bus)
|
|
|
375 |
slave = self._hexint(slave)
|
|
|
376 |
addr = self._hexint(addr)
|
|
|
377 |
size = self._hexint(size)
|
|
|
378 |
raise NotImplementedError
|
|
|
379 |
|
|
|
380 |
@command
|
|
|
381 |
def i2csend(self, bus, slave, addr, *args):
|
|
|
382 |
"""
|
|
|
383 |
Writes data to an I2C device
|
|
|
384 |
<bus> the bus index
|
|
|
385 |
<slave> the slave address
|
|
|
386 |
<addr> the start address on the I2C device
|
|
|
387 |
<db1> ... <dbN> the data in single bytes, seperated by whitespaces,
|
|
|
388 |
eg. 0x37 0x56 0x45 0x12
|
|
|
389 |
"""
|
|
|
390 |
bus = self._hexint(bus)
|
|
|
391 |
slave = self._hexint(slave)
|
|
|
392 |
addr = self._hexint(addr)
|
|
|
393 |
data = []
|
|
|
394 |
for arg in args:
|
|
|
395 |
data.append(self._hexint(arg))
|
|
|
396 |
raise NotImplementedError
|
|
|
397 |
|
|
|
398 |
@command
|
|
|
399 |
def readusbconsole(self, size, outtype):
|
|
|
400 |
"""
|
|
|
401 |
Reads data from the USB console.
|
|
|
402 |
<size>: the number of bytes to read
|
|
|
403 |
<outtype>: defines how to output the result:
|
|
|
404 |
'file': writes the result to file <file>
|
|
|
405 |
'printstring': writes the result as string to the console window
|
|
|
406 |
'printhex': writes the result in hexedit notation to the console window
|
|
|
407 |
<file>: the file to write the result to, can be omitted
|
|
|
408 |
if <outtype> is not 'file'
|
|
|
409 |
"""
|
|
|
410 |
size = self._hexint(size)
|
|
|
411 |
raise NotImplementedError
|
|
|
412 |
|
|
|
413 |
|
|
|
414 |
@command
|
|
|
415 |
def writeusbconsole_file(self, file, offset=0, length=None):
|
|
|
416 |
"""
|
|
|
417 |
Writes the file <file> to the USB console.
|
|
|
418 |
Optional params <offset> <length>: specify the range in <file> to write
|
|
|
419 |
"""
|
|
|
420 |
# We don't care about file here, this is done when opening it
|
|
|
421 |
offset = self._hexint(offset)
|
|
|
422 |
length = self._hexint(length)
|
|
|
423 |
raise NotImplementedError
|
|
|
424 |
|
|
|
425 |
@command
|
|
|
426 |
def writeusbconsole_direct(self, *args):
|
|
|
427 |
"""
|
|
|
428 |
Writes the strings <db1> ... <dbN> to the USB console."
|
|
|
429 |
"""
|
|
|
430 |
raise NotImplementedError
|
|
|
431 |
|
|
|
432 |
@command
|
|
|
433 |
def readdevconsole(self, bitmask, size, outtype, file=None):
|
|
|
434 |
"""
|
|
|
435 |
Reads data from one or more of the device's consoles.
|
|
|
436 |
<bitmask>: the bitmask of the consoles to read from
|
|
|
437 |
<size>: the number of bytes to read
|
|
|
438 |
<outtype>: defines how to output the result:
|
|
|
439 |
'file': writes the result to file <file>
|
|
|
440 |
'printstring': writes the result as string to the console window
|
|
|
441 |
'printhex': writes the result in hexedit notation to the console window
|
|
|
442 |
<file>: the file to write the result to, can be omitted
|
|
|
443 |
if <outtype> is not 'file'
|
|
|
444 |
"""
|
|
|
445 |
bitmask = self._hexint(bitmask)
|
|
|
446 |
size = self._hexint(size)
|
|
|
447 |
outtype = self._strcheck(['file', 'printstring', 'printhex'])
|
|
|
448 |
raise NotImplementedError
|
|
|
449 |
|
|
|
450 |
@command
|
|
|
451 |
def writedevconsole_file(self, bitmask, file, offset=0, length=None):
|
|
|
452 |
"""
|
|
|
453 |
Writes the file <file> to the device consoles specified by <bitmask>
|
|
|
454 |
Optional params <offset> <length>: specify the range in <file> to write
|
|
|
455 |
"""
|
|
|
456 |
bitmask = self._hexint(bitmask)
|
|
|
457 |
# We don't care about file here, this is done when opening it
|
|
|
458 |
offset = self._hexint(offset)
|
|
|
459 |
length = self._hexint(length)
|
|
|
460 |
raise NotImplementedError
|
|
|
461 |
|
|
|
462 |
@command
|
|
|
463 |
def writedevconsole_direct(self, bitmask, *args):
|
|
|
464 |
"""
|
|
|
465 |
Writes the integers <db1> ... <dbN> to the device consoles specified
|
|
|
466 |
by <bitmask>
|
|
|
467 |
"""
|
|
|
468 |
bitmask = self._hexint(bitmask)
|
|
|
469 |
data = []
|
|
|
470 |
for arg in args:
|
|
|
471 |
data.append(self._hexint(arg))
|
|
|
472 |
raise NotImplementedError
|
|
|
473 |
|
|
|
474 |
@command
|
|
|
475 |
def flushconsolebuffers(self, bitmask):
|
|
|
476 |
"""
|
|
|
477 |
flushes one or more of the device consoles' buffers.
|
|
|
478 |
<bitmask>: the bitmask of the consoles to be flushed
|
|
|
479 |
"""
|
|
|
480 |
bitmask = self._hexint(bitmask)
|
|
|
481 |
raise NotImplementedError
|
|
|
482 |
|
|
|
483 |
@command
|
|
|
484 |
def getprocinfo(self):
|
|
|
485 |
"""
|
|
|
486 |
Fetches data on the currently running processes
|
|
|
487 |
ATTENTION: this function will be print the information to the console window.
|
|
|
488 |
If several threads are running this might overflow the window,
|
|
|
489 |
causing not everything to be shown.
|
|
|
490 |
"""
|
|
|
491 |
raise NotImplementedError
|
|
|
492 |
|
|
|
493 |
@command
|
|
|
494 |
def lockscheduler(self):
|
|
|
495 |
"""
|
|
|
496 |
Locks (freezes) the scheduler
|
|
|
497 |
"""
|
|
|
498 |
raise NotImplementedError
|
|
|
499 |
|
|
|
500 |
@command
|
|
|
501 |
def unlockscheduler(self):
|
|
|
502 |
"""
|
|
|
503 |
Unlocks (unfreezes) the scheduler
|
|
|
504 |
"""
|
|
|
505 |
raise NotImplementedError
|
|
|
506 |
|
|
|
507 |
@command
|
|
|
508 |
def suspendthread(self, threadid):
|
|
|
509 |
"""
|
|
|
510 |
Suspends/resumes the thread with thread ID <threadid>
|
|
|
511 |
"""
|
|
|
512 |
threadid = self._hexint(threadid)
|
|
|
513 |
raise NotImplementedError
|
|
|
514 |
|
|
|
515 |
@command
|
|
|
516 |
def resumethread(self, threadid):
|
|
|
517 |
"""
|
|
|
518 |
Resumes the thread with thread ID <threadid>
|
|
|
519 |
"""
|
|
|
520 |
threadid = self._hexint(threadid)
|
|
|
521 |
raise NotImplementedError
|
|
|
522 |
|
|
|
523 |
@command
|
|
|
524 |
def killthread(self, threadid):
|
|
|
525 |
"""
|
|
|
526 |
Kills the thread with thread ID <threadid>
|
|
|
527 |
"""
|
|
|
528 |
threadid = self._hexint(threadid)
|
|
|
529 |
raise NotImplementedError
|
|
|
530 |
|
|
|
531 |
@command
|
|
|
532 |
def createthread(self, nameptr, entrypoint, stackptr, stacksize, threadtype, priority, state):
|
|
|
533 |
"""
|
|
|
534 |
Creates a new thread and returns its thread ID
|
|
|
535 |
<namepointer> a pointer to the thread's name
|
|
|
536 |
<entrypoint> a pointer to the entrypoint of the thread
|
|
|
537 |
<stackpointer> a pointer to the stack of the thread
|
|
|
538 |
<stacksize> the size of the thread's stack
|
|
|
539 |
<type> the thread type, vaild are: 0 => user thread, 1 => system thread
|
|
|
540 |
<priority> the priority of the thread, from 1 to 255
|
|
|
541 |
<state> the thread's initial state, valid are: 1 => ready, 0 => suspended
|
|
|
542 |
"""
|
|
|
543 |
nameptr = self._hexint(nameptr)
|
|
|
544 |
entrypoint = self._hexint(entrypoint)
|
|
|
545 |
stackpointer = self._hexint(stackpointer)
|
|
|
546 |
stacksize = self._hexint(stacksize)
|
|
|
547 |
priority = self._hexint(priority)
|
|
|
548 |
self.embios.createthread(nameptr, entrypoint, stackptr, stacksize, type, priority, state)
|
|
|
549 |
|
|
|
550 |
@command
|
|
|
551 |
def run(self, address):
|
|
|
552 |
"""
|
|
|
553 |
Executes the emBIOS application at <address>.
|
|
|
554 |
"""
|
|
|
555 |
address = self._hexint(address)
|
|
|
556 |
raise NotImplementedError
|
|
|
557 |
|
|
|
558 |
@command
|
|
|
559 |
def readrawbootflash(self, addr_flash, addr_mem, size):
|
|
|
560 |
"""
|
|
|
561 |
Reads <size> bytes from bootflash to memory.
|
|
|
562 |
<addr_bootflsh>: the address in bootflash to read from
|
|
|
563 |
<addr_mem>: the address in memory to copy the data to
|
|
|
564 |
"""
|
|
|
565 |
addr_flash = self._hexint(addr_flash)
|
|
|
566 |
addr_mem = self._hexint(addr_mem)
|
|
|
567 |
size = self._hexint(size)
|
|
|
568 |
raise NotImplementedError
|
|
|
569 |
|
|
|
570 |
@command
|
|
|
571 |
def writerawbootflash(self, addr_flash, addr_mem, size):
|
|
|
572 |
"""
|
|
|
573 |
Writes <size> bytes from memory to bootflash.
|
|
|
574 |
ATTENTION: Don't call this unless you really know what you're doing!
|
|
|
575 |
This may BRICK your device (unless it has a good recovery option)
|
|
|
576 |
<addr_mem>: the address in memory to copy the data from
|
|
|
577 |
<addr_bootflsh>: the address in bootflash to write to
|
|
|
578 |
"""
|
|
|
579 |
addr_flash = self._hexint(addr_flash)
|
|
|
580 |
addr_mem = self._hexint(addr_mem)
|
|
|
581 |
size = self._hexint(size)
|
|
|
582 |
raise NotImplementedError
|
|
|
583 |
|
|
|
584 |
@command
|
|
|
585 |
def flushcaches(self):
|
|
|
586 |
"""
|
|
|
587 |
Flushes the CPUs data and instruction caches.
|
|
|
588 |
"""
|
|
|
589 |
raise NotImplementedError
|
| 64 |
benedikt93 |
590 |
|
| 171 |
farthen |
591 |
@command
|
|
|
592 |
def aesencrypt(self, addr, size, keyindex):
|
|
|
593 |
"""
|
|
|
594 |
Encrypt a buffer using a hardware key
|
|
|
595 |
"""
|
|
|
596 |
addr = self._hexint(addr)
|
|
|
597 |
size = self._hexint(size)
|
|
|
598 |
keyindex = self._hexint(keyindex)
|
|
|
599 |
self.embios.aesencrypt(addr, size, keyindex)
|
| 82 |
benedikt93 |
600 |
|
| 171 |
farthen |
601 |
@command
|
|
|
602 |
def aesdecrypt(self, addr, size, keyindex):
|
|
|
603 |
"""
|
|
|
604 |
Decrypt a buffer using a hardware key
|
|
|
605 |
"""
|
|
|
606 |
addr = self._hexint(addr)
|
|
|
607 |
size = self._hexint(size)
|
|
|
608 |
keyindex = self._hexint(keyindex)
|
|
|
609 |
self.embios.aesdecrypt(addr, size, keyindex)
|
| 64 |
benedikt93 |
610 |
|
| 171 |
farthen |
611 |
if __name__ == "__main__":
|
|
|
612 |
if len(sys.argv) < 2:
|
|
|
613 |
usage("No command specified")
|
|
|
614 |
interface = Commandline()
|
|
|
615 |
interface._parsecommand(sys.argv[1], sys.argv[2:])
|