Skip to content

Commit e8b9bc8

Browse files
committed
sync
1 parent 6c73012 commit e8b9bc8

4 files changed

Lines changed: 246 additions & 0 deletions

File tree

src/emptool/cli.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import rawrepl
2+
import pypi
3+
4+
5+
def install_from_pip():
6+
pass
7+
8+
9+
def sync_folder(self):
10+
pass
11+
12+
13+
def main():
14+
pass

src/emptool/porter.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Porter():
2+
def __init__(self):
3+
pass
4+
5+
6+
def sync_folder(self):
7+
pass
8+
9+

src/emptool/pypi.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import requests
2+
import tarfile
3+
import os
4+
import json
5+
6+
7+
def download_pkg(pkg):
8+
url = "https://pypi.org/pypi/%s/json" % pkg
9+
meta_data = requests.get(url).json()
10+
link = meta_data['urls'][0]['url']
11+
pkg_name = link.split('/')[-1]
12+
zipped_pkg = requests.get(link)
13+
14+
with open(pkg_name, 'wb') as f:
15+
f.write(zipped_pkg.content)
16+
17+
return pkg_name
18+
19+
20+
def unzip_pkg(pkg):
21+
t = tarfile.open(pkg)
22+
t.extractall()
23+
24+
25+
def remove_trash(pkg):
26+
os.system('rm %s' % pkg)
27+
os.system('rm -rf %s' % pkg.replace('.tar.gz', ''))
28+
29+
30+
if __name__ == '__main__':
31+
# pkg_name = download_pkg('emp-ext')
32+
# unzip_pkg(pkg_name)
33+
pkg_name = 'emp-ext-1.13.tar.gz'
34+
remove_trash(pkg_name)

src/emptool/rawrepl.py

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
import ctypes
2+
import inspect
3+
import json
4+
import sys
5+
import textwrap
6+
import threading
7+
import time
8+
9+
import serial
10+
11+
BUFFER_SIZE = 1024
12+
13+
14+
class RawReplError(BaseException):
15+
pass
16+
17+
18+
class RawRepl():
19+
20+
def __init__(self, device, baudrate=115200, rawdelay=0):
21+
super().__init__()
22+
self._rawdelay = rawdelay
23+
24+
if isinstance(device, str):
25+
self.repl = serial.Serial(device, baudrate)
26+
elif isinstance(device, serial.Serial):
27+
self.repl = device
28+
else:
29+
raise RawReplError('can not init RawRepl')
30+
31+
def read_until(self, min_num_bytes, ending, timeout=10, data_consumer=None):
32+
data = self.repl.read(min_num_bytes)
33+
if data_consumer:
34+
data_consumer(data)
35+
timeout_count = 0
36+
while True:
37+
if data.endswith(ending):
38+
break
39+
elif self.repl.inWaiting() > 0:
40+
new_data = self.repl.read(1)
41+
data = data + new_data
42+
if data_consumer:
43+
data_consumer(new_data)
44+
timeout_count = 0
45+
else:
46+
timeout_count += 1
47+
if timeout is not None and timeout_count >= 100 * timeout:
48+
break
49+
time.sleep(0.01)
50+
return data
51+
52+
def enter_raw_repl(self):
53+
print('==> Entering Raw REPL')
54+
# Brief delay before sending RAW MODE char if requests
55+
if self._rawdelay > 0:
56+
time.sleep(self._rawdelay)
57+
58+
# ctrl-C twice: interrupt any running program
59+
self.repl.write(b'\r\x03\x03')
60+
61+
# flush input (without relying on serial.flushInput())
62+
n = self.repl.inWaiting()
63+
while n > 0:
64+
self.repl.read(n)
65+
n = self.repl.inWaiting()
66+
time.sleep(2)
67+
68+
self.repl.write(b'\r\x01') # ctrl-A: enter raw REPL
69+
data = self.read_until(1, b'raw REPL; CTRL-B to exit\r\n>')
70+
if not data.endswith(b'raw REPL; CTRL-B to exit\r\n>'):
71+
print(data)
72+
raise RawReplError('could not enter raw repl')
73+
print('---> now in rawrepl mode')
74+
75+
def exit_raw_repl(self):
76+
print('==> Exit Raw REPL')
77+
self.repl.write(b'\r\x02') # ctrl-B: enter friendly REPL
78+
79+
def follow(self, timeout, data_consumer=None):
80+
# wait for normal output
81+
data = self.read_until(1, b'\x04', timeout=timeout,
82+
data_consumer=data_consumer)
83+
if not data.endswith(b'\x04'):
84+
raise RawReplError('timeout waiting for first EOF reception')
85+
data = data[:-1]
86+
87+
# wait for error output
88+
data_err = self.read_until(1, b'\x04', timeout=timeout)
89+
if not data_err.endswith(b'\x04'):
90+
raise RawReplError('timeout waiting for second EOF reception')
91+
data_err = data_err[:-1]
92+
93+
# return normal and error output
94+
return data, data_err
95+
96+
def exec_raw_no_follow(self, command):
97+
if isinstance(command, bytes):
98+
command_bytes = command
99+
else:
100+
command_bytes = bytes(command, encoding='utf8')
101+
102+
# check we have a prompt
103+
# data = self.read_until(1, b'>')
104+
# if not data.endswith(b'>'):
105+
# raise RawReplError('could not enter raw repl')
106+
107+
# write command
108+
for i in range(0, len(command_bytes), 256):
109+
self.repl.write(
110+
command_bytes[i:min(i + 256, len(command_bytes))])
111+
time.sleep(0.01)
112+
self.repl.write(b'\x04')
113+
114+
# check if we could exec command
115+
# data = self.repl.read(2)
116+
# if data != b'OK':
117+
# raise RawReplError('could not exec command')
118+
119+
def exec_raw(self, command, timeout=10, data_consumer=None):
120+
self.exec_raw_no_follow(command)
121+
return self.follow(timeout, data_consumer)
122+
123+
def eval(self, expression):
124+
ret = self.exec__('print({})'.format(expression))
125+
ret = ret.strip()
126+
return ret
127+
128+
def exec__(self, command):
129+
ret, ret_err = self.exec_raw(command)
130+
if ret_err:
131+
raise RawReplError('exception', ret, ret_err)
132+
return ret
133+
134+
def execfile(self, filename):
135+
with open(filename, 'rb') as f:
136+
pyfile = f.read()
137+
return self.exec__(pyfile)
138+
139+
def get_file(self, filename):
140+
"""Retrieve the contents of the specified file and return its contents
141+
as a byte string.
142+
"""
143+
# Open the file and read it a few bytes at a time and print out the
144+
# raw bytes. Be careful not to overload the UART buffer so only write
145+
# a few bytes at a time, and don't use print since it adds newlines and
146+
# expects string data.
147+
command = """
148+
import sys
149+
with open('{0}', 'rb') as infile:
150+
while True:
151+
result = infile.read({1})
152+
if result == b'':
153+
break
154+
len = sys.stdout.write(result)
155+
""".format(
156+
filename, BUFFER_SIZE
157+
)
158+
self.enter_raw_repl()
159+
try:
160+
out = self.exec__(textwrap.dedent(command))
161+
except RawReplError as ex:
162+
# Check if this is an OSError #2, i.e. file doesn't exist and
163+
# rethrow it as something more descriptive.
164+
if ex.args[2].decode("utf-8").find("OSError: [Errno 2] ENOENT") != -1:
165+
raise RuntimeError("No such file: {0}".format(filename))
166+
else:
167+
raise ex
168+
self.exit_raw_repl()
169+
return out[2::]
170+
171+
def put_file(self, filename, data):
172+
"""Create or update the specified file with the provided data.
173+
"""
174+
175+
data = data.encode('utf-8')
176+
# Open the file for writing on the board and write chunks of data.
177+
# self.enter_raw_repl()
178+
self.exec__("f = open('{0}', 'wb')".format(filename))
179+
size = len(data)
180+
# Loop through and write a buffer size chunk of data at a time.
181+
for i in range(0, size, BUFFER_SIZE):
182+
chunk_size = min(BUFFER_SIZE, size - i)
183+
chunk = repr(data[i: i + chunk_size])
184+
# Make sure to send explicit byte strings (handles python 2 compatibility).
185+
if not chunk.startswith("b"):
186+
chunk = "b" + chunk
187+
self.exec__("f.write({0})".format(chunk))
188+
self.exec__("f.close()")
189+
self.exit_raw_repl()

0 commit comments

Comments
 (0)