@@ -64,7 +64,7 @@ def __init__(self, serial_port, baudrate=115200, verbose=True, print_func=print
64
64
self .print = print_func # Function used for print statements.
65
65
self .data_logger = data_logger # Instance of Data_logger class for saving and printing data.
66
66
self .status = {'serial' : None , 'framework' :None , 'usb_mode' :None }
67
- self .device_files_on_pyboard = [] # List of files in devices folder on pyboard.
67
+ self .device_files_on_pyboard = {} # Dict {file_name:file_hash} of files in devices folder on pyboard.
68
68
if not Pycboard .device_class2file : # Scan devices folder to find files where device classes are defined.
69
69
self .make_device_class2file_map ()
70
70
try :
@@ -109,7 +109,7 @@ def reset(self):
109
109
try :
110
110
self .exec ('from pyControl import *; import devices' )
111
111
self .status ['framework' ] = True # Framework imported OK.
112
- self .device_files_on_pyboard = self .get_folder_contents ('devices' )
112
+ self .device_files_on_pyboard = self .get_folder_contents ('devices' , get_hash = True )
113
113
except PyboardError as e :
114
114
error_message = e .args [2 ].decode ()
115
115
if (("ImportError: no module named 'pyControl'" in error_message ) or
@@ -260,19 +260,27 @@ def remove_file(self, file_path):
260
260
except PyboardError :
261
261
pass # File does not exist.
262
262
263
- def get_folder_contents (self , folder_path ):
264
- '''Get a list of the files in a folder on the pyboard.'''
265
- return eval (self .eval ('os.listdir({})' .format (repr (folder_path ))).decode ())
263
+ def get_folder_contents (self , folder_path , get_hash = False ):
264
+ '''Get a list of the files in a folder on the pyboard, if
265
+ get_hash=True a dict {file_name:file_hash} is returned instead'''
266
+ file_list = eval (self .eval ('os.listdir({})' .format (repr (folder_path ))).decode ())
267
+ if get_hash :
268
+ return {file_name : self .get_file_hash (folder_path + '/' + file_name )
269
+ for file_name in file_list }
270
+ else :
271
+ return file_list
266
272
267
273
# ------------------------------------------------------------------------------------
268
274
# pyControl operations.
269
275
# ------------------------------------------------------------------------------------
270
276
271
277
def load_framework (self ):
272
- '''Copy the pyControl framework folder to the board.'''
278
+ '''Copy the pyControl framework folder to the board, reset the devices folder
279
+ on pyboard by removing all devices files, and rebuild the device_class2file dict.'''
273
280
self .print ('\n Transferring pyControl framework to pyboard.' , end = '' )
274
281
self .transfer_folder (dirs ['framework' ], file_type = 'py' , show_progress = True )
275
- self .transfer_folder (dirs ['devices' ], files = ['__init__.py' ], remove_files = False , show_progress = True )
282
+ self .transfer_folder (dirs ['devices' ], files = ['__init__.py' ], remove_files = True , show_progress = True )
283
+ self .make_device_class2file_map ()
276
284
error_message = self .reset ()
277
285
if not self .status ['framework' ]:
278
286
self .print ('\n Error importing framework:' )
@@ -282,12 +290,9 @@ def load_framework(self):
282
290
return
283
291
284
292
def load_hardware_definition (self , hwd_path = os .path .join (dirs ['config' ], 'hardware_definition.py' )):
285
- '''Transfer a hardware definition file to pyboard. Device driver files needed for
286
- the hardware definition are transferred to the pyboard and any other device driver
287
- files on the pyboard are deleted.'''
293
+ '''Transfer a hardware definition file to pyboard.'''
288
294
if os .path .exists (hwd_path ):
289
- self .make_device_class2file_map ()
290
- self .transfer_device_files (hwd_path , reset_folder = True )
295
+ self .transfer_device_files (hwd_path )
291
296
self .print ('\n Transferring hardware definition to pyboard.' , end = '' )
292
297
self .transfer_file (hwd_path , target_path = 'hardware_definition.py' )
293
298
self .reset ()
@@ -301,35 +306,37 @@ def load_hardware_definition(self, hwd_path=os.path.join(dirs['config'], 'hardwa
301
306
else :
302
307
self .print ('Hardware definition file not found.' )
303
308
304
- def transfer_device_files (self , ref_file_path , reset_folder = False , return_filenames = False ):
305
- '''Transfer device driver files defining classes used in ref_file to the pyboard devices folder.
306
- If reset_folder=True then any files not used by ref_file are deleted from the pyboard filesystem,
307
- and any files that have changed on the computer are retransferred. If reset_folder=False then
308
- only files that are not already on the pyboard filesystem are transferred. If return_filenames=True
309
- then no files are transferred but a list of the filenames used in ref_file is returned.'''
309
+ def transfer_device_files (self , ref_file_path ):
310
+ '''Transfer device driver files defining classes used in ref_file to the pyboard devices folder.
311
+ Driver file that are already on the pyboard are only be transferred if they have changed
312
+ on the computer.'''
313
+ used_device_files = self ._get_used_device_files (ref_file_path )
314
+ files_to_transfer = []
315
+ for device_file in used_device_files : # File not on pyboard.
316
+ if device_file not in self .device_files_on_pyboard .keys ():
317
+ files_to_transfer .append (device_file )
318
+ else :
319
+ file_hash = _djb2_file (os .path .join (dirs ['devices' ],device_file ))
320
+ if file_hash != self .device_files_on_pyboard [device_file ]: # File has changed.
321
+ files_to_transfer .append (device_file )
322
+ if files_to_transfer :
323
+ self .print (f'\n Transfering device driver files { files_to_transfer } to pyboard' , end = '' )
324
+ self .transfer_folder (dirs ['devices' ], files = files_to_transfer , remove_files = False , show_progress = True )
325
+ self .reset ()
326
+ self .print (' OK' )
327
+
328
+ def _get_used_device_files (self , ref_file_path ):
329
+ '''Return a list of device driver file names containing device classes used in ref_file'''
310
330
ref_file_name = os .path .split (ref_file_path )[- 1 ]
311
331
with open (ref_file_path , 'r' ) as f :
312
332
file_content = f .read ()
313
- device_files = [Pycboard .device_class2file [device_class ] for device_class in
314
- Pycboard .device_class2file .keys () if device_class in file_content
315
- and not ref_file_name == Pycboard .device_class2file [device_class ]]
333
+ device_files = [device_file for device_class , device_file in Pycboard .device_class2file .items ()
334
+ if device_class in file_content and not ref_file_name == device_file ]
316
335
# Add any device driver files containing classes used in device_files.
317
336
for device_file in device_files .copy ():
318
- device_files += self .transfer_device_files (os .path .join (dirs ['devices' ], device_file ), return_filenames = True )
337
+ device_files += self ._get_used_device_files (os .path .join (dirs ['devices' ], device_file ))
319
338
device_files = list (set (device_files )) # Remove duplicates.
320
- if return_filenames :
321
- return device_files
322
- else :
323
- if reset_folder :
324
- device_files += ['__init__.py' ]
325
- else :
326
- device_files = list (set (device_files )- set (self .device_files_on_pyboard ))
327
- if device_files :
328
- self .print (f'\n Transfering device driver files { device_files } to pyboard' , end = '' )
329
- self .transfer_folder (dirs ['devices' ], files = device_files , remove_files = reset_folder , show_progress = True )
330
- self .reset ()
331
- self .print (' OK' )
332
-
339
+ return device_files
333
340
334
341
def make_device_class2file_map (self ):
335
342
'''Make dict mapping device class names to file in devices folder containing
0 commit comments