1#!/usr/bin/python 2""" 3SPDX-License-Identifier: Apache-2.0 4Copyright (c) 2024 STMicroelectronics. 5This script updates ble library 6""" 7 8import sys 9import os 10import shutil 11import subprocess 12from pathlib import Path 13import logging 14from common_utils import common_utils 15 16file_list_wb = [ 17 "Middlewares/ST/STM32_WPAN/ble/core/ble_bufsize.h", 18 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/hw.h", 19 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci/shci.c", 20 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci/shci.h", 21 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl.h", 22 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/mbox_def.h", 23 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/shci_tl_if.c", 24 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/shci_tl.c", 25 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/shci_tl.h", 26 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/tl.h", 27 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/tl_mbox.c", 28 "Middlewares/ST/STM32_WPAN/stm32_wpan_common.h", 29 "Middlewares/ST/STM32_WPAN/utilities/dbg_trace.h", 30 "Middlewares/ST/STM32_WPAN/utilities/stm_list.c", 31 "Middlewares/ST/STM32_WPAN/utilities/stm_list.h", 32 "Middlewares/ST/STM32_WPAN/utilities/utilities_common.h", 33 "Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_Hid/Core/Inc/app_common.h", 34 "Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_Hid/Core/Inc/app_conf.h", 35 "Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_Hid/Core/Inc/hw_if.h", 36 "Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_Hid/STM32_WPAN/Target/" 37 + "hw_ipcc.c", 38 "Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_Hid/STM32_WPAN/App/" 39 + "tl_dbg_conf.h", 40] 41 42ble_heartrate_app_path = "Projects/NUCLEO-WBA55CG/Applications/BLE/BLE_HeartRate" 43 44file_list_wba = { 45 "auto": ["Middlewares/ST/STM32_WPAN/ble/stack/include/auto/ble_types.h", 46 ], 47 "reg_files": ["Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/_40nm_reg_files/" 48 + "DWC_ble154combo.h", 49 ], 50 "ll": ["Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/bsp.h", 51 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/common_types.h", 52 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/event_manager.h", 53 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/evnt_schdlr_gnrc_if.h", 54 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/hci.h", 55 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/ll_intf.h", 56 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/mem_intf.h", 57 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/os_wrapper.h", 58 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/power_table.h", 59 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/config/ble_full/" 60 + "ll_fw_config.h", 61 ], 62 "hci": ["Middlewares/ST/STM32_WPAN/ble/stack/include/ble_bufsize.h", 63 "Middlewares/ST/STM32_WPAN/ble/stack/include/ble_const.h", 64 "Middlewares/ST/STM32_WPAN/ble/stack/include/ble_defs.h", 65 "Middlewares/ST/STM32_WPAN/ble/stack/include/ble_std.h", 66 "Middlewares/ST/STM32_WPAN/ble/stack/include/bleplat.h", 67 "Middlewares/ST/STM32_WPAN/ble/stack/include/blestack.h", 68 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/inc/linklayer_plat.h", 69 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/inc/ll_sys.h", 70 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/src/ll_sys_cs.c", 71 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/src/ll_sys_dp_slp.c", 72 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/src/ll_sys_intf.c", 73 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/src/ll_sys_startup.c", 74 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/inc/ll_sys_startup.h", 75 "Middlewares/ST/STM32_WPAN/stm32_wpan_common.h", 76 ble_heartrate_app_path + "/Core/Inc/app_common.h", 77 ble_heartrate_app_path + "/Core/Inc/app_conf.h", 78 ble_heartrate_app_path + "/Core/Inc/app_entry.h", 79 ble_heartrate_app_path + "/Core/Inc/utilities_conf.h", 80 ble_heartrate_app_path + "/Core/Inc/main.h", 81 ble_heartrate_app_path + "/System/Modules/Flash/rf_timing_synchro.c", 82 ble_heartrate_app_path + "/System/Modules/Flash/rf_timing_synchro.h", 83 ble_heartrate_app_path + "/System/Modules/Flash/flash_driver.c", 84 ble_heartrate_app_path + "/System/Modules/Flash/flash_driver.h", 85 ble_heartrate_app_path + "/System/Modules/Flash/flash_manager.c", 86 ble_heartrate_app_path + "/System/Modules/Flash/flash_manager.h", 87 ble_heartrate_app_path + "/System/Modules/RTDebug/debug_signals.h", 88 ble_heartrate_app_path + "/System/Modules/RTDebug/RTDebug.c", 89 ble_heartrate_app_path + "/System/Modules/RTDebug/RTDebug.h", 90 ble_heartrate_app_path + "/System/Modules/RTDebug/local_debug_tables.h", 91 ble_heartrate_app_path + "/System/Modules/scm.c", 92 ble_heartrate_app_path + "/System/Modules/scm.h", 93 ble_heartrate_app_path + "/System/Modules/stm_list.c", 94 ble_heartrate_app_path + "/System/Modules/stm_list.h", 95 ble_heartrate_app_path + "/System/Modules/utilities_common.h", 96 ble_heartrate_app_path + "/System/Interfaces/hw.h", 97 ble_heartrate_app_path + "/System/Interfaces/hw_aes.c", 98 ble_heartrate_app_path + "/System/Interfaces/hw_if.h", 99 ble_heartrate_app_path + "/System/Interfaces/hw_pka.c", 100 ble_heartrate_app_path + "/System/Interfaces/pka_p256.c", 101 ble_heartrate_app_path + "/System/Config/Log/log_module.c", 102 ble_heartrate_app_path + "/System/Config/Log/log_module.h", 103 ble_heartrate_app_path + "/System/Config/Debug_GPIO/app_debug.h", 104 ble_heartrate_app_path + "/System/Config/Debug_GPIO/debug_config.h", 105 ble_heartrate_app_path + "/STM32_WPAN/Target/power_table.c", 106 ble_heartrate_app_path + "/STM32_WPAN/Target/bpka.c", 107 ble_heartrate_app_path + "/STM32_WPAN/Target/bpka.h", 108 "Utilities/trace/adv_trace/stm32_adv_trace.h", 109 "Utilities/misc/stm32_mem.h", 110 "Utilities/tim_serv/stm32_timer.h", 111 "Utilities/misc/stm32_tiny_vsnprintf.h", 112 ], 113} 114 115 116def os_cmd(cmd, cwd=None, shell=False): 117 """Execute a command with subprocess.check_call() 118 Args: 119 cmd: string command to execute. 120 cwd: directory where to run command 121 shell: boolean to enable command interpretation by the shell 122 123 Returns: 124 return the returncode of the command after execution. 125 """ 126 logging.debug("%s", f"{str(cmd)} cwd:{str(cwd)}") 127 128 return subprocess.check_call( 129 cmd, 130 shell=shell, 131 cwd=cwd, 132 stdout=subprocess.DEVNULL, 133 stderr=subprocess.DEVNULL, 134 ) 135 136 137def copy_hci_files(src_repo_path, dest_lib_path, stm32_serie): 138 """Copy sources files from Cube Firmware to zephyr""" 139 # remove existing *.c and *.h files 140 hci_path = Path(dest_lib_path / "hci") 141 if hci_path.exists(): 142 for item in os.listdir(hci_path): 143 if item.endswith(".c") or item.endswith(".h"): 144 os.remove(hci_path / item) 145 146 if stm32_serie == "stm32wb": 147 if not hci_path.exists(): 148 hci_path.mkdir(parents=True) 149 150 for file in file_list_wb: 151 file_path = Path(src_repo_path / file) 152 file_name = file_path.name 153 if file_path.exists(): 154 # copy each file to destination 155 shutil.copy(file_path, Path(hci_path / file_name)) 156 else: 157 logging.error(f"File : {file_path} not found") 158 logging.error("Abort") 159 sys.exit() 160 161 elif stm32_serie == "stm32wba": 162 # remove existing *.c and *.h files 163 auto_path = Path(hci_path / "auto") 164 ll_path = Path(hci_path / "ll") 165 reg_files_path = Path(ll_path / "_40nm_reg_files") 166 dir_paths = {"hci": hci_path, "auto": auto_path, "ll": ll_path, 167 "reg_files": reg_files_path} 168 169 for dir_path in [auto_path, ll_path, reg_files_path]: 170 if dir_path.exists(): 171 for item in os.listdir(dir_path): 172 if item.endswith(".c") or item.endswith(".h"): 173 os.remove(dir_path / item) 174 175 for dir_name in file_list_wba: 176 if not dir_paths[dir_name].exists(): 177 dir_paths[dir_name].mkdir(parents=True) 178 179 for file in file_list_wba[dir_name]: 180 file_path = Path(src_repo_path / file) 181 file_name = file_path.name 182 if file_path.exists(): 183 # copy each file to destination 184 shutil.copy(file_path, Path(dir_paths[dir_name])) 185 else: 186 logging.error(f"File : {file_path} not found") 187 logging.error("Abort") 188 sys.exit() 189 190 191def update_ble_lib_readme(lib_path, make_version, make_commit): 192 """Update README file 193 194 Args: 195 dest_lib_path: library path 196 make_version: latest STM32Cube version. 197 make_commit: Commit corresponding to latest STM32Cube version. 198 """ 199 200 readme_path = Path(lib_path / "hci" / "README") 201 202 with readme_path.open(mode="r") as readme_prev: 203 lines = (x for x in readme_prev.read().splitlines()) 204 205 readme_path.unlink() 206 207 # Write README from previous one if exists 208 with open(str(readme_path), "w") as readme_file: 209 for line_item in lines: 210 # change version nb 211 if "status" in line_item.lower(): 212 readme_file.write("Status:\n") 213 readme_file.write(f" version {make_version}\n") 214 next(lines) # skip next line 215 elif "commit" in line_item.lower(): 216 readme_file.write("Commit:\n") 217 readme_file.write(f" {make_commit}") 218 next(lines) # skip next line 219 # change patch list with a link to the release_note.html 220 elif "Patch List" in line_item: 221 readme_file.write("Patch List:\n") 222 readme_file.write( 223 "--> please check that the following list " 224 + "is still valid:\n" 225 ) 226 else: 227 readme_file.write(f"{line_item}\n") 228 229 readme_file.flush() 230 231 232def build_patch_from_current_zephyr_version( 233 src_repo_path, temp_source_path, zephyr_lib_path, version, stm32_serie 234): 235 """ Rebuild zephyr patch compare to cube files (current zephyr version) """ 236 237 temp_source_lib_path = Path(temp_source_path / "lib" / stm32_serie) 238 239 # Checkout the current Zephyr version of the STM32Cube repo 240 os_cmd( 241 ("git", "checkout", "-f", "--recurse-submodules", version), 242 cwd=src_repo_path, 243 ) 244 245 # create Cube reference from zephyr version 246 shutil.rmtree(temp_source_path, onerror=common_utils.remove_readonly) 247 temp_source_lib_path.mkdir(parents=True) 248 249 copy_hci_files( 250 src_repo_path, 251 temp_source_lib_path, 252 stm32_serie, 253 ) 254 os_cmd(("git", "init"), cwd=temp_source_path) 255 os_cmd( 256 ("git", "commit", "--allow-empty", "-m", "'Trigger notification'"), 257 cwd=temp_source_path, 258 ) 259 os_cmd( 260 ("git", "add", "-A", Path(temp_source_lib_path / "*")), 261 cwd=temp_source_path, 262 ) 263 os_cmd( 264 ("git", "commit", "-am", "ble lib from zephyr version"), 265 cwd=temp_source_path, 266 ) 267 268 # Remove trailing whitespaces 269 os_cmd( 270 ("git", "rebase", "--whitespace=fix", "HEAD~1"), 271 cwd=temp_source_path, 272 ) 273 274 # copy zephyr files 275 shutil.rmtree(temp_source_lib_path, onerror=common_utils.remove_readonly) 276 shutil.copytree(zephyr_lib_path, temp_source_lib_path) 277 278 # remove all files at root dir (like readme and cmakelist) 279 # so that it is not part of the patch 280 for file in temp_source_lib_path.glob("*"): 281 if file.is_file(): 282 file.unlink() 283 if Path(temp_source_lib_path / "hci" / "README").exists(): 284 Path(temp_source_lib_path / "hci" / "README").unlink() 285 286 # commit this current zephyr library file 287 os_cmd(("git", "add", "*"), cwd=temp_source_path) 288 os_cmd(("git", "commit", "-am", '"module"'), cwd=temp_source_path) 289 290 # Remove trailing space 291 os_cmd( 292 ("git", "rebase", "--whitespace=fix", "HEAD~1"), 293 cwd=temp_source_path, 294 ) 295 296 # For unclear reason, using tuple ("git", "diff", ...) is failing on Linux 297 # especially for this command. Keep a single string. 298 os_cmd( 299 ( 300 "git diff --ignore-space-at-eol HEAD~1 --output=" 301 + str(zephyr_lib_path) 302 + "/ble_zephyr.patch" 303 ), 304 shell=True, 305 cwd=temp_source_path, 306 ) 307 os_cmd(("dos2unix", "ble_zephyr.patch"), cwd=zephyr_lib_path) 308 309 310def update( 311 src_repo_path, 312 dest_lib_path, 313 temp_source_path, 314 current_version, 315 update_version, 316 commit, 317 stm32_serie 318): 319 """Update ble library""" 320 logging.info(" ... Updating ble library ...") 321 if not dest_lib_path.exists(): 322 dest_lib_path.mkdir(parents=True) 323 324 build_patch_from_current_zephyr_version( 325 src_repo_path, temp_source_path, dest_lib_path, current_version, 326 stm32_serie 327 ) 328 # Checkout the latest version of the STM32Cube repo 329 os_cmd( 330 ("git", "checkout", "-f", "--recurse-submodules", update_version), 331 cwd=src_repo_path, 332 ) 333 copy_hci_files(src_repo_path, dest_lib_path, stm32_serie) 334 common_utils.apply_patch(dest_lib_path / "ble_zephyr.patch", dest_lib_path) 335 if Path(dest_lib_path / "hci" / "README").exists(): 336 update_ble_lib_readme( 337 dest_lib_path, update_version, commit) 338 339 340if __name__ == "__main__": 341 print("This script is not intend to be called directly\n") 342 print("It is used through serie_update.py\n") 343 sys.exit() 344