@@ -22,41 +22,34 @@ def _djb2_file(file_path):
22
22
h = ((h << 5 ) + h + int .from_bytes (c ,'little' )) & 0xFFFFFFFF
23
23
return h
24
24
25
- # Used on pyboard to remove directories or files.
26
- def _rm_dir_or_file (i ):
27
- try :
28
- os .remove (i )
29
- except OSError :
30
- os .chdir (i )
31
- for j in os .listdir ():
32
- _rm_dir_or_file (j )
33
- os .chdir ('..' )
34
- os .rmdir (i )
35
-
36
- # Used on pyboard to clear filesystem.
37
- def _reset_pyb_filesystem ():
38
- os .chdir ('/flash' )
39
- for i in os .listdir ():
40
- if i not in ['System Volume Information' , 'boot.py' ]:
41
- _rm_dir_or_file (i )
25
+ # Used on pyboard to measure free space on filesystem.
26
+ def _fs_free_space (drive = '/flash' ):
27
+ fs_stat = os .statvfs (drive )
28
+ return fs_stat [0 ] * fs_stat [3 ]
42
29
43
30
# Used on pyboard for file transfer.
44
31
def _receive_file (file_path , file_size ):
45
- gc .collect ()
46
32
usb = pyb .USB_VCP ()
47
33
usb .setinterrupt (- 1 )
34
+ if file_size > _fs_free_space ():
35
+ usb .write (b'NS' )
36
+ return
37
+ else :
38
+ usb .write (b'OK' )
48
39
buf_size = 512
49
40
buf = bytearray (buf_size )
50
41
buf_mv = memoryview (buf )
51
42
bytes_remaining = file_size
52
- with open (file_path , 'wb' ) as f :
53
- while bytes_remaining > 0 :
54
- bytes_read = usb .recv (buf , timeout = 5 )
55
- usb .write (b'0' )
56
- if bytes_read :
57
- bytes_remaining -= bytes_read
58
- f .write (buf_mv [:bytes_read ])
59
- gc .collect ()
43
+ try :
44
+ with open (file_path , 'wb' ) as f :
45
+ while bytes_remaining > 0 :
46
+ bytes_read = usb .recv (buf , timeout = 5 )
47
+ usb .write (b'OK' )
48
+ if bytes_read :
49
+ bytes_remaining -= bytes_read
50
+ f .write (buf_mv [:bytes_read ])
51
+ except :
52
+ usb .write (b'ER' )
60
53
61
54
# ----------------------------------------------------------------------------------------
62
55
# Pycboard class.
@@ -101,8 +94,9 @@ def __init__(self, serial_port, baudrate=115200, verbose=True, print_func=print
101
94
def reset (self ):
102
95
'''Enter raw repl (soft reboots pyboard), import modules.'''
103
96
self .enter_raw_repl () # Soft resets pyboard.
104
- self .exec (inspect .getsource (_djb2_file )) # define djb2 hashing function.
97
+ self .exec (inspect .getsource (_djb2_file )) # define djb2 hashing function.
105
98
self .exec (inspect .getsource (_receive_file )) # define recieve file function.
99
+ self .exec (inspect .getsource (_fs_free_space )) # define file system free space function.
106
100
self .exec ('import os; import gc; import sys; import pyb' )
107
101
self .framework_running = False
108
102
error_message = None
@@ -191,27 +185,35 @@ def transfer_file(self, file_path, target_path=None):
191
185
target_path = os .path .split (file_path )[- 1 ]
192
186
file_size = os .path .getsize (file_path )
193
187
file_hash = _djb2_file (file_path )
194
- try :
195
- for i in range (10 ):
196
- if file_hash == self .get_file_hash (target_path ):
197
- return
198
- try :
199
- self .remove_file (file_path )
200
- except PyboardError :
201
- pass
202
- self .exec_raw_no_follow ("_receive_file('{}',{})"
203
- .format (target_path , file_size ))
204
- with open (file_path , 'rb' ) as f :
205
- while True :
206
- chunk = f .read (512 )
207
- if not chunk :
208
- break
209
- self .serial .write (chunk )
210
- self .serial .read (1 )
211
- self .follow (5 )
212
- except PyboardError :
213
- self .print ('\n \n Error: Unable to transfer file.' )
214
- raise PyboardError
188
+ for i in range (3 ):
189
+ if file_hash == self .get_file_hash (target_path ):
190
+ return
191
+ try :
192
+ self .remove_file (file_path )
193
+ time .sleep (0.01 )
194
+ except PyboardError :
195
+ pass
196
+ self .exec_raw_no_follow ("_receive_file('{}',{})"
197
+ .format (target_path , file_size ))
198
+ if not self .serial .read (2 ) == b'OK' :
199
+ self .print ('\n \n Insufficient space on pyboard filesystem to transfer file.' )
200
+ raise PyboardError
201
+ with open (file_path , 'rb' ) as f :
202
+ while True :
203
+ chunk = f .read (512 )
204
+ if not chunk :
205
+ break
206
+ self .serial .write (chunk )
207
+ response_bytes = self .serial .read (2 )
208
+ if response_bytes != b'OK' :
209
+ self .print ('\n \n Error: Unable to transfer file. See the troubleshooting docs:\n '
210
+ 'https://pycontrol.readthedocs.io/en/latest/user-guide/troubleshooting/' )
211
+
212
+ time .sleep (0.01 )
213
+ self .serial .reset_input_buffer ()
214
+ raise PyboardError
215
+ self .follow (3 )
216
+
215
217
216
218
def transfer_folder (self , folder_path , target_folder = None , file_type = 'all' ,
217
219
show_progress = False ):
@@ -238,16 +240,7 @@ def transfer_folder(self, folder_path, target_folder=None, file_type='all',
238
240
def remove_file (self , file_path ):
239
241
'''Remove a file from the pyboard.'''
240
242
self .exec ('os.remove({})' .format (repr (file_path )))
241
-
242
- def reset_filesystem (self ):
243
- '''Delete all files in the flash drive apart from boot.py'''
244
- self .print ('Resetting filesystem.' )
245
- self .reset ()
246
- self .exec (inspect .getsource (_rm_dir_or_file ))
247
- self .exec (inspect .getsource (_reset_pyb_filesystem ))
248
- self .exec_raw ('_reset_pyb_filesystem()' , timeout = 60 )
249
- self .hard_reset ()
250
-
243
+
251
244
# ------------------------------------------------------------------------------------
252
245
# pyControl operations.
253
246
# ------------------------------------------------------------------------------------
0 commit comments