66#test:timeout 500
77#test:donotrun:gha
88#test:device each(D400*)
9+ #test:device D555
910
1011import sys
1112import os
1415import platform
1516import pyrealsense2 as rs
1617import pyrsutils as rsutils
17- from rspy import devices , log , test , file , repo
18+ from rspy import log , test , file , repo
1819import time
1920import argparse
2021
2122# Parse command-line arguments
2223parser = argparse .ArgumentParser (description = "Test firmware update" )
2324parser .add_argument ('--custom-fw-d400' , type = str , help = 'Path to custom firmware file' )
25+ parser .add_argument ('--custom-fw-d555' , type = str , help = 'Path to custom D555 firmware file' )
2426args = parser .parse_args ()
2527
2628custom_fw_d400_path = args .custom_fw_d400
29+ custom_fw_d555_path = args .custom_fw_d555
2730if custom_fw_d400_path :
28- log .i (f"Custom firmware path provided: { custom_fw_d400_path } " )
31+ log .i (f"Custom D400 firmware path provided: { custom_fw_d400_path } " )
32+ elif custom_fw_d555_path :
33+ log .i (f"Custom D555 firmware path provided: { custom_fw_d555_path } " )
2934else :
3035 log .i (f"No Custom firmware path provided. using bundled firmware" )
3136
32- # This is the first test running, discover acroname modules.
33- # Not relevant to MIPI devices running on jetson for LibCI
34- if 'jetson' not in test .context :
35- if not devices .hub :
36- log .i ( "No hub library found; skipping device FW update" )
37- sys .exit (0 )
38- # Following will throw if no acroname module is found
39- from rspy import device_hub
40-
41- if device_hub .create () is None :
42- log .f ("No hub found" )
43- # Remove acroname -- we're likely running inside run-unit-tests in which case the
44- # acroname hub is likely already connected-to from there and we'll get an error
45- # thrown ('failed to connect to acroname (result=11)'). We do not need it -- just
46- # needed to verify it is available above...
47- devices .hub = None
48-
4937
5038def send_hardware_monitor_command (device , command ):
5139 # byte_index = -1
@@ -73,7 +61,7 @@ def extract_version_from_filename(file_path):
7361 return None
7462
7563 filename = os .path .basename (file_path )
76- match = re .search (r'(\d+)_ (\d+)_ (\d+)_ (\d+)\.bin$ ' , filename )
64+ match = re .search (r'(\d+)[._] (\d+)[._] (\d+)[._] (\d+)' , filename )
7765 if match :
7866 groups = match .groups ()
7967 if groups [3 ] == '0' :
@@ -89,12 +77,15 @@ def extract_version_from_filename(file_path):
8977
9078def get_update_counter (device ):
9179 product_line = device .get_info (rs .camera_info .product_line )
80+ product_name = device .get_info (rs .camera_info .name )
9281 opcode = 0x09
9382 start_index = 0x30
9483 size = None
9584
9685 if product_line == "D400" :
9786 size = 0x2
87+ elif "D555" in product_name :
88+ return 0 # D555 does not have update counter
9889 else :
9990 log .f ( "Incompatible product line:" , product_line )
10091
@@ -163,16 +154,11 @@ def find_image_or_exit( product_name, fw_version_regex = r'(\d+\.){3}(\d+)' ):
163154if not fw_updater_exe :
164155 log .f ( "Could not find the update tool file (rs-fw-update.exe)" )
165156
166- devices .query ( monitor_changes = False )
167- sn_list = devices .all ()
168- # acroname should ensure there is always 1 available device
169- if len ( sn_list ) != 1 :
170- log .f ( "Expected 1 device, got" , len ( sn_list ) )
171- device = devices .get_first ( sn_list ).handle
172- log .d ( 'found:' , device )
157+ device , ctx = test .find_first_device_or_exit ()
173158product_line = device .get_info ( rs .camera_info .product_line )
174159product_name = device .get_info ( rs .camera_info .name )
175- log .d ( 'product line:' , product_line )
160+ serial_number = device .get_info (rs .camera_info .serial_number )
161+ log .d ( 'product line:' , product_line , 'serial number:' , serial_number )
176162###############################################################################
177163#
178164
@@ -185,7 +171,7 @@ def find_image_or_exit( product_name, fw_version_regex = r'(\d+\.){3}(\d+)' ):
185171 try :
186172 # always flash signed fw when device on recovery befre flashing anything else
187173 image_file = find_image_or_exit (product_name )
188- cmd = [fw_updater_exe , '-r' , '-f' , image_file ]
174+ cmd = [fw_updater_exe , '-r' , '-f' , image_file , '-s' , serial_number ]
189175 log .d ( 'running:' , cmd )
190176 subprocess .run ( cmd )
191177 recovered = True
@@ -199,19 +185,35 @@ def find_image_or_exit( product_name, fw_version_regex = r'(\d+\.){3}(\d+)' ):
199185 test .unexpected_exception ()
200186 log .f ( "Unexpected error while trying to recover device:" , e )
201187 else :
202- devices .query ( monitor_changes = False )
203- device = devices .get_first ( devices .all () ).handle
188+ device , ctx = test .find_first_device_or_exit ()
189+ # check we got the same serial number
190+ new_serial_number = device .get_info (rs .camera_info .serial_number )
191+ if new_serial_number != serial_number :
192+ log .f ( "Recovered device has different serial number:" , new_serial_number )
204193
205194current_fw_version = rsutils .version ( device .get_info ( rs .camera_info .firmware_version ))
206195log .d ( 'current FW version:' , current_fw_version )
207- bundled_fw_version = rsutils .version ( device .get_info ( rs .camera_info .recommended_firmware_version ) )
208- log .d ( 'bundled FW version:' , bundled_fw_version )
196+ bundled_fw_version = rsutils .version ("" )
197+ if device .supports ( rs .camera_info .recommended_firmware_version ): # currently, D500 does not support recommended FW
198+ bundled_fw_version = rsutils .version ( device .get_info ( rs .camera_info .recommended_firmware_version ) )
199+ log .d ( 'bundled FW version:' , bundled_fw_version )
209200custom_fw_d400_version = extract_version_from_filename (custom_fw_d400_path )
210201log .d ( 'custom FW D400 version:' , custom_fw_d400_version )
211-
212-
213- if (current_fw_version == bundled_fw_version and not custom_fw_d400_path ) or \
214- (current_fw_version == custom_fw_d400_version ):
202+ custom_fw_d555_version = extract_version_from_filename (custom_fw_d555_path )
203+ log .d ( 'custom FW D555 version:' , custom_fw_d555_version )
204+
205+ # Determine which custom firmware to use based on product
206+ custom_fw_path = None
207+ custom_fw_version = None
208+ if product_line == "D400" and custom_fw_d400_path :
209+ custom_fw_path = custom_fw_d400_path
210+ custom_fw_version = custom_fw_d400_version
211+ elif "D555" in product_name and custom_fw_d555_path :
212+ custom_fw_path = custom_fw_d555_path
213+ custom_fw_version = custom_fw_d555_version
214+
215+ if (current_fw_version == bundled_fw_version and not custom_fw_path ) or \
216+ (current_fw_version == custom_fw_version ):
215217 if recovered or 'nightly' not in test .context :
216218 log .d ('versions are same; skipping FW update' )
217219 test .finish ()
@@ -231,29 +233,33 @@ def find_image_or_exit( product_name, fw_version_regex = r'(\d+\.){3}(\d+)' ):
231233if not bundled_fw_version .build ():
232234 fw_version_regex += ".0" # version drops the build if 0
233235fw_version_regex = re .escape ( fw_version_regex )
234- image_file = find_image_or_exit (product_name , fw_version_regex ) if not custom_fw_d400_path else custom_fw_d400_path
236+ image_file = find_image_or_exit (product_name , fw_version_regex ) if not custom_fw_path else custom_fw_path
235237# finding file containing image for FW update
236238
237- cmd = [fw_updater_exe , '-f' , image_file ]
238- if custom_fw_d400_path :
239+ cmd = [fw_updater_exe , '-f' , image_file , '-s' , serial_number ]
240+ if custom_fw_path :
239241 # Add '-u' only if the path doesn't include 'signed'
240- if 'signed' not in custom_fw_d400_path .lower ():
242+ if ('signed' not in custom_fw_path .lower ()
243+ and "d555" not in product_name .lower ()): # currently -u is not supported for D555
241244 cmd .insert (1 , '-u' )
245+
246+ # for DDS devices we need to close device and context to detect it back after FW update
247+ del device , ctx
242248log .d ( 'running:' , cmd )
243249sys .stdout .flush ()
244250subprocess .run ( cmd ) # may throw
245251
246252# make sure update worked
247253time .sleep (3 ) # MIPI devices do not re-enumerate so we need to give them some time to restart
248- devices .query ( monitor_changes = False )
249- sn_list = devices .all ()
250- device = devices .get_first ( sn_list ).handle
254+ device , ctx = test .find_first_device_or_exit ()
251255current_fw_version = rsutils .version ( device .get_info ( rs .camera_info .firmware_version ))
252- test .check_equal (current_fw_version , bundled_fw_version if not custom_fw_d400_path else custom_fw_d400_version )
256+
257+ expected_fw_version = custom_fw_version if custom_fw_path else bundled_fw_version
258+ test .check_equal (current_fw_version , expected_fw_version )
253259new_update_counter = get_update_counter ( device )
254260# According to FW: "update counter zeros if you load newer FW than (ever) before"
255261# TODO: check why update counter is 255 when installing cutom fw
256- if new_update_counter > 0 and not custom_fw_d400_version :
262+ if new_update_counter > 0 and not custom_fw_version :
257263 test .check_equal ( new_update_counter , update_counter + 1 )
258264
259265test .finish ()
0 commit comments