1#!/usr/bin/python 2""" 3SPDX-License-Identifier: Apache-2.0 4Copyright (c) 2024 STMicroelectronics. 5This script define Stm32SerieUpdate class 6to be used by update_stm32_package.py 7""" 8 9import os 10import shutil 11import subprocess 12import re 13from pathlib import Path 14import logging 15from jinja2 import Environment, FileSystemLoader 16import ble_library 17from common_utils import common_utils 18 19STM32_CUBE_REPO_BASE = "https://github.com/STMicroelectronics/STM32Cube" 20"""GitHub URL to get STM32Cube""" 21 22SCRIPT_DIR = Path(__file__).absolute().parent 23"""Script directory.""" 24 25REPO_ROOT = SCRIPT_DIR / ".." 26"""Repository root (used for input/output default folders).""" 27 28# list of created files. It is necessary to remove all of them 29# as they are fully created when applying zephyr patch 30zephyr_file_created = [ 31 "CMakeLists.txt", 32 "README", 33 "drivers/include/stm32_assert.h", 34] 35 36 37def version_tuple(version): 38 """Remove 'v' in front of version and convert it to tuple, 39 so that versions can be compared 40 """ 41 v = re.sub("v", r"", version) 42 return tuple(map(int, (v.split(".")))) 43 44 45class Stm32SerieUpdate: 46 """class Stm32SerieUpdate""" 47 48 def __init__( 49 self, 50 stm32_serie, 51 stm32cube_repo_path, 52 noclean, 53 version_update, 54 debug, 55 ): 56 """Class Stm32SerieUpdate constructor 57 58 Args: 59 stm32_serie: stm32 serie ex:stm32f3xx 60 stm32cube_repo_path: directory path where to fetch github repo 61 noclean: boolean to clean or not github repo after update done 62 version_update: string to force a specified version to be updated 63 debug: boolean to set log debug level 64 65 Returns: 66 return previous zephyr cube version. 67 68 Raises: 69 ValueError: If stm32 serie is not recognised. 70 FileNotFoundError: If Zphyr STM32 cube path is not found 71 """ 72 if not stm32_serie.startswith("stm32"): 73 raise ValueError( 74 f"Error: Unknown stm32 serie: {stm32_serie}. Must start with 'stm32'" 75 ) 76 77 # Set serie variables 78 self.stm32_serie = stm32_serie 79 self.stm32_seriexx = stm32_serie + "xx" # ex:stm32f3xx 80 self.stm32_serie_upper = stm32_serie.upper() # ex:STM32F3 81 self.stm32_seriexx_upper = self.stm32_serie_upper + "xx" # ex:STM32F3xx 82 self.serie = self.stm32_serie_upper[5:] 83 self.noclean = noclean 84 self.version_update = version_update 85 self.debug = debug 86 self.module_patch = f"module_{self.stm32_serie}.patch" 87 88 # ##### 3 root directories to work with ######## 89 # 1: STM32Cube repo Default $HOME/STM32Cube_repo 90 # 2: zephyr stm32 path : ex: .../zephyr_project/module/hal/stm32 91 # 3: Temporary directory to construct the update 92 # (within STM32Cube repo dir) 93 self.stm32cube_repo_path = stm32cube_repo_path 94 if not self.stm32cube_repo_path.exists(): 95 self.stm32cube_repo_path.mkdir() 96 97 self.zephyr_hal_stm32_path = REPO_ROOT 98 if not self.zephyr_hal_stm32_path.exists(): 99 raise FileNotFoundError("Error: cannot find zephyr project") 100 101 self.stm32cube_temp = self.stm32cube_repo_path / "temp_stm32xx_update" 102 if self.stm32cube_temp.exists(): 103 shutil.rmtree( 104 str(self.stm32cube_temp), onerror=common_utils.remove_readonly 105 ) 106 self.stm32cube_temp.mkdir() 107 108 # subdir specific to a stm32 serie 109 self.stm32cube_serie_path = self.stm32cube_repo_path / Path( 110 "STM32Cube" + self.serie 111 ) 112 self.zephyr_module_serie_path = ( 113 self.zephyr_hal_stm32_path / "stm32cube" / self.stm32_seriexx 114 ) 115 self.stm32cube_temp_serie = ( 116 self.stm32cube_temp / "stm32cube" / self.stm32_seriexx 117 ) 118 shutil.rmtree(str(self.stm32cube_temp), onerror=common_utils.remove_readonly) 119 self.stm32cube_temp_serie.mkdir(parents=True) 120 121 self.readme_file_path = self.zephyr_module_serie_path / "README" 122 self.version_tag = [] 123 self.current_version = "" 124 self.update_commit = "" 125 126 if self.debug: 127 logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.DEBUG) 128 self.std_dest = None 129 else: 130 logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.INFO) 131 self.std_dest = subprocess.DEVNULL 132 133 def os_cmd(self, cmd, cwd=None, shell=False): 134 """Execute a command with subprocess.check_call() 135 Args: 136 cmd: string command to execute. 137 cwd: directory where to run command 138 shell: boolean to enable command interpretation by the shell 139 140 Returns: 141 return the returncode of the command after execution. 142 """ 143 logging.debug("%s", f"{str(cmd)} cwd:{str(cwd)}") 144 145 return subprocess.check_call( 146 cmd, 147 shell=shell, 148 stdout=self.std_dest, 149 stderr=self.std_dest, 150 cwd=cwd, 151 ) 152 153 def rename_conf_template(self, path): 154 """renames hal_conf_template.h to hal_conf.h ... 155 Args: 156 path: path where to apply the files processing 157 """ 158 # except for _hal_conf_template.h which is renamed 159 hal_conf_template_fullpath = Path( 160 path / (self.stm32_seriexx + "_hal_conf_template.h") 161 ) 162 if hal_conf_template_fullpath.is_file(): 163 hal_conf_fullpath = Path( 164 re.sub("_template", r"", str(hal_conf_template_fullpath)) 165 ) 166 if hal_conf_fullpath.exists(): 167 hal_conf_fullpath.unlink() 168 hal_conf_template_fullpath.rename(hal_conf_fullpath) 169 170 def major_branch(self): 171 # check whether master branch exist, otherwise use main branch 172 master_branch_exist = subprocess.check_output( 173 ("git", "ls-remote", "--heads", "origin", "master"), 174 cwd=self.stm32cube_serie_path, 175 ).decode("utf-8") 176 if master_branch_exist: 177 return "master" 178 else: 179 return "main" 180 181 def clone_cube_repo(self): 182 """Clone or fetch a stm32 serie repo""" 183 repo_name = STM32_CUBE_REPO_BASE + self.serie + ".git" 184 logging.info( 185 "%s", 186 "Cloning/fetching repo " 187 + repo_name 188 + " in " 189 + str(self.stm32cube_serie_path), 190 ) 191 if self.stm32cube_serie_path.exists(): 192 # if already exists, then just clean and fetch 193 self.os_cmd(("git", "clean", "-fdx"), cwd=self.stm32cube_serie_path) 194 self.os_cmd(("git", "fetch"), cwd=self.stm32cube_serie_path) 195 # this is useful when HAL/CMSIS Device drivers submodules are not 196 # already present locally, otherwise "git fetch" is sufficient 197 self.os_cmd(("git", "submodule", "update", "--init"), 198 cwd=self.stm32cube_serie_path) 199 branch = self.major_branch() 200 # "Using --recurse-submodules will update the content of all active 201 # submodules according to the commit recorded in the superproject. 202 # If local modifications in a submodule would be overwritten the 203 # checkout will fail unless -f is used." 204 # https://git-scm.com/docs/git-checkout 205 self.os_cmd( 206 ("git", "checkout", "-f", "--recurse-submodules", branch), 207 cwd=self.stm32cube_serie_path, 208 ) 209 else: 210 # HAL & CMSIS Device drivers are now included as git submodules in 211 # upstream STM32Cube GitHub repositories 212 # So to get them too, --recursive or --recurse-submodules is needed 213 self.os_cmd( 214 ("git", "clone", "--recursive", repo_name), 215 cwd=self.stm32cube_repo_path, 216 ) 217 branch = self.major_branch() 218 219 logging.info("%s", f"Branch used: {branch}") 220 221 # get the latest version of cube, 222 # with the most recent one created being the last entry. 223 self.os_cmd(("git", "checkout", branch), cwd=self.stm32cube_serie_path) 224 self.version_tag = subprocess.check_output( 225 ("git", "tag", "-l"), cwd=self.stm32cube_serie_path 226 ).splitlines() 227 self.version_tag = [x.decode("utf-8") for x in self.version_tag] 228 # Search latest version 229 if self.version_update == "": 230 self.version_update = self.version_tag[0] 231 for tag in self.version_tag: 232 if version_tuple(tag) > version_tuple(self.version_update): 233 self.version_update = tag 234 235 def get_zephyr_current_version(self): 236 """Look for current zephyr hal version 237 238 Returns: 239 return previous zephyr cube version. 240 241 Raises: 242 ValueError: If version is not found. 243 """ 244 with open(str(self.readme_file_path), "r") as f: 245 for line in f: 246 # pattern : "version " follow by optional "v", 247 # followed by x.y or x.y.z x,y,z may represent several digits 248 # ex: 'version v1.8.9', 'version 10.20.25' 249 pattern = r".*version v?(\d+\.\d+\.?\d*).*$" 250 if re.match(pattern, line): 251 previous_version = re.sub(pattern, r"\1", line).rstrip("\n") 252 break 253 254 # Match previous version and list of existing tags 255 # which could be vx.y or x.y 256 pos_version = [ 257 i for i, a in enumerate(self.version_tag) if previous_version in a 258 ] 259 if pos_version: 260 # return previous zephyr version 261 return self.version_tag[pos_version[0]] 262 else: 263 self.clean_files() 264 raise ValueError( 265 f"Error: cannot find version {previous_version} in STM32Cube_repo" 266 ) 267 268 def extract_source(self): 269 """Extract sources and includes files from STM32Cube repo 270 and copy them in temporary directory 271 """ 272 # for CMSIS files 273 temp_cmsis_soc_path = self.stm32cube_temp_serie / "soc" 274 Path.mkdir(temp_cmsis_soc_path, parents=True) 275 276 stm32cube_cmsis_include_path = ( 277 self.stm32cube_serie_path 278 / "Drivers" 279 / "CMSIS" 280 / "Device" 281 / "ST" 282 / self.stm32_seriexx_upper 283 / "Include" 284 ) 285 shutil.rmtree(temp_cmsis_soc_path, onerror=common_utils.remove_readonly) 286 shutil.copytree(stm32cube_cmsis_include_path, temp_cmsis_soc_path) 287 288 stm32cube_cmsis_templates_path = ( 289 self.stm32cube_serie_path 290 / "Drivers" 291 / "CMSIS" 292 / "Device" 293 / "ST" 294 / self.stm32_seriexx_upper 295 / "Source" 296 / "Templates" 297 ) 298 for repo_file in stm32cube_cmsis_templates_path.iterdir(): 299 repo_src = stm32cube_cmsis_templates_path / repo_file 300 if repo_src.is_file(): 301 shutil.copy(str(repo_src), str(temp_cmsis_soc_path)) 302 303 # for hal and ll drivers 304 temp_drivers_include_path = self.stm32cube_temp_serie / "drivers" / "include" 305 temp_drivers_include_path.parent.mkdir(parents=True) 306 307 stm32cube_driver_inc = ( 308 self.stm32cube_serie_path 309 / "Drivers" 310 / Path(self.stm32_seriexx_upper + "_HAL_Driver") 311 / "Inc" 312 ) 313 if temp_drivers_include_path.exists(): 314 shutil.rmtree( 315 temp_drivers_include_path, onerror=common_utils.remove_readonly 316 ) 317 shutil.copytree(stm32cube_driver_inc, temp_drivers_include_path) 318 319 # except for _hal_conf_template.h which is renamed 320 self.rename_conf_template(temp_drivers_include_path) 321 322 temp_drivers_src_path = self.stm32cube_temp_serie / "drivers" / "src" 323 temp_drivers_src_path.mkdir() 324 stm32cube_drivers_src_path = ( 325 self.stm32cube_serie_path 326 / "Drivers" 327 / Path(self.stm32_seriexx_upper + "_HAL_Driver") 328 / "Src" 329 ) 330 shutil.rmtree(temp_drivers_src_path, onerror=common_utils.remove_readonly) 331 shutil.copytree(stm32cube_drivers_src_path, temp_drivers_src_path) 332 333 def build_from_current_cube_version(self): 334 """Build a commit in temporary dir with STM32Cube version 335 corresponding to zephyr current hal version 336 """ 337 # Checkout the current Zephyr version of the STM32Cube repo 338 self.os_cmd( 339 ("git", "checkout", "-f", "--recurse-submodules", self.current_version), 340 cwd=self.stm32cube_serie_path, 341 ) 342 343 # build the zephyr module from the stm32cube 344 self.extract_source() 345 logging.info( 346 "%s", "Building module from STM32Cube_repo " + self.current_version 347 ) 348 349 if not self.stm32cube_temp_serie.parent.exists(): 350 self.stm32cube_temp_serie.parent.mkdir(parents=True) 351 352 self.os_cmd( 353 ("git", "add", "-A", "stm32cube/" + self.stm32_seriexx + "/*"), 354 cwd=self.stm32cube_temp, 355 ) 356 self.os_cmd( 357 ("git", "commit", "-am", '"module' + self.current_version + '"'), 358 cwd=self.stm32cube_temp, 359 ) 360 # Remove trailing whitespaces 361 self.os_cmd( 362 ("git", "rebase", "--whitespace=fix", "HEAD~1"), 363 cwd=self.stm32cube_temp, 364 ) 365 366 def build_patch_from_current_zephyr_version(self): 367 """Build patch between zephyr current hal version and 368 corresponding official STM32Cube version 369 """ 370 # clean-up the module 371 shutil.rmtree( 372 str(self.stm32cube_temp_serie), onerror=common_utils.remove_readonly 373 ) 374 375 # populate the new repo with this current zephyr module 376 shutil.copytree(self.zephyr_module_serie_path, self.stm32cube_temp_serie) 377 378 # commit this current version module 379 self.os_cmd(("git", "add", "*"), cwd=self.stm32cube_temp) 380 self.os_cmd(("git", "commit", "-am", '"module"'), cwd=self.stm32cube_temp) 381 382 # Remove trailing space 383 self.os_cmd( 384 ("git", "rebase", "--whitespace=fix", "HEAD~1"), 385 cwd=self.stm32cube_temp, 386 ) 387 388 # generate a patch for files and _hal.conf.h file in the module 389 logging.info( 390 "%s", 391 "Building patch from official " 392 + self.current_version 393 + " to current zephyr module", 394 ) 395 396 # For unclear reason, using tuple ("git", "diff", ...) is failing on Linux 397 # especially for this command. Keep a single string. 398 self.os_cmd( 399 ("git diff --ignore-space-at-eol HEAD~1 --output=" + self.module_patch), 400 shell=True, 401 cwd=self.stm32cube_temp, 402 ) 403 self.os_cmd(("dos2unix", self.module_patch), cwd=self.stm32cube_temp) 404 405 def update_readme(self, make_version, make_commit): 406 """Update README file 407 408 Args: 409 make_version: latest STM32Cube version. 410 make_commit: Commit corresponding to latest STM32Cube version. 411 """ 412 see_release_note = True 413 414 readme_path = self.zephyr_module_serie_path / "README" 415 416 with readme_path.open(mode="r") as readme_prev: 417 lines = (x for x in readme_prev.read().splitlines()) 418 419 readme_path.unlink() 420 421 # Write README from previous one if exists 422 with open(str(readme_path), "w") as readme_file: 423 for LineItem in lines: 424 # change version nb 425 if "status" in LineItem.lower(): 426 readme_file.write("Status:\n") 427 readme_file.write(f" version {make_version}\n") 428 next(lines) # skip next line 429 elif "commit" in LineItem.lower(): 430 readme_file.write("Commit:\n") 431 readme_file.write(f" {make_commit}") 432 next(lines) # skip next line 433 elif "URL" in LineItem.upper(): 434 readme_file.write("URL:\n") 435 readme_file.write( 436 " https://github.com/STMicroelectronics/" 437 + f"STM32Cube{self.serie}\n" 438 ) 439 next(lines) # skip next line 440 # change patch list with a link to the release_note.html 441 elif "Patch List" in LineItem: 442 readme_file.write("Patch List:\n") 443 readme_file.write( 444 "--> please check that the following list " 445 + "is still valid:\n" 446 ) 447 else: 448 if "See release_note.html from STM32Cube" in LineItem: 449 see_release_note = False 450 readme_file.write(f"{LineItem}\n") 451 452 # at the very end of the file : 453 if see_release_note: 454 readme_file.write("\n See release_note.html from STM32Cube\n") 455 readme_file.flush() 456 457 self.os_cmd(("dos2unix", str(readme_path))) 458 459 def copy_release_note(self): 460 """Copy release_note.html file from STM32Cube to zephyr""" 461 release_note_src = self.stm32cube_serie_path / "Release_Notes.html" 462 release_note_dst = self.zephyr_module_serie_path / "release_note.html" 463 if release_note_dst.exists(): 464 release_note_dst.unlink() 465 if release_note_src.exists: 466 release_note_src.rename(release_note_dst) 467 self.os_cmd(("dos2unix", str(release_note_dst))) 468 469 def update_cmakelist(self): 470 """Update CMakeLists.txt file""" 471 cmakelists_path = self.zephyr_module_serie_path / "CMakeLists.txt" 472 if cmakelists_path.exists(): 473 # build new CMakeLists.txt 474 with cmakelists_path.open("r") as cmakelists_old: 475 # this line is the copyright line 476 first_line = cmakelists_old.readline() 477 if "STMicroelectronics" in first_line: 478 first_line = "" 479 cmakelists_path.unlink() 480 else: 481 first_line = "" 482 483 logging.info("%s", "Create a new CMakeLists.txt file") 484 485 with cmakelists_path.open("w") as cmakelists_new: 486 if first_line: 487 cmakelists_new.write(first_line) 488 cmakelists_new.write("# Copyright (c) 2020 STMicroelectronics\n") 489 cmakelists_new.write("#\n") 490 cmakelists_new.write("# SPDX-License-Identifier: Apache-2.0\n") 491 cmakelists_new.write("\n") 492 493 src_path = self.stm32cube_temp_serie / "drivers" / "src" 494 source_files = list(src_path.iterdir()) 495 source_files.sort() 496 497 cmakelists_new.write( 498 f"zephyr_library_sources(soc/system_{self.stm32_seriexx}.c)\n" 499 ) 500 cmakelists_new.write( 501 f"zephyr_library_sources(drivers/src/{self.stm32_seriexx}_hal.c)\n" 502 ) 503 cmakelists_new.write( 504 f"zephyr_library_sources(drivers/src/{self.stm32_seriexx}_hal_rcc.c)\n" 505 ) 506 cmakelists_new.write( 507 "zephyr_library_sources(drivers/src/" 508 + f"{self.stm32_seriexx}_hal_rcc_ex.c)\n" 509 ) 510 511 for filename in source_files: 512 # also skipping '_xxx_hal.c' 513 if "template" in filename.name: 514 continue 515 516 # also skipping '_xxx_hal_rcc.c' and '_xxx_hal_rcc_ex.c' 517 if "_hal_rcc" in filename.name: 518 continue 519 520 if "_hal_" in filename.name: 521 # retrieve IP name from filename, like adc, 522 # which is delimited by 523 # * _hal_ on one side 524 # * and file extension on the other side 525 pattern = r".*_hal_(.*)\..*" 526 cmakelists_new.write( 527 "zephyr_library_sources_ifdef(CONFIG_USE_STM32_HAL_" 528 + re.sub(pattern, r"\1", filename.name).upper() 529 + " drivers/src/" 530 + filename.name 531 + ")\n" 532 ) 533 if "_ll_" in filename.name: 534 # retrieve IP name from filename, like adc, 535 # which is delimited by 536 # * _ll_ on one side 537 # * and file extension on the other side 538 pattern = r".*_ll_(.*)\..*" 539 cmakelists_new.write( 540 "zephyr_library_sources_ifdef(CONFIG_USE_STM32_LL_" 541 + re.sub(pattern, r"\1", filename.name).upper() 542 + " drivers/src/" 543 + filename.name 544 + ")\n" 545 ) 546 self.os_cmd(("dos2unix", str(cmakelists_path))) 547 548 def generate_assert_file(self): 549 """Remove stm32_assert_template.h file and create stm32_assert.h file""" 550 # remove stm32_assert_template.h 551 stm32_assert_template = ( 552 self.stm32cube_temp_serie 553 / "drivers" 554 / "include" 555 / "stm32_assert_template.h" 556 ) 557 if stm32_assert_template.exists(): 558 stm32_assert_template.unlink() 559 560 # create stm32_assert.h from Jinja2 template 561 # Create the jinja2 environment. 562 templates_dir = self.zephyr_hal_stm32_path / "scripts" 563 j2_env = Environment( 564 loader=FileSystemLoader(str(templates_dir)), 565 trim_blocks=True, 566 lstrip_blocks=True, 567 ) 568 stm32_assert_j2_template = j2_env.get_template("stm32_assert_template.txt") 569 stm32_assert_h = ( 570 self.stm32cube_temp_serie / "drivers" / "include" / "stm32_assert.h" 571 ) 572 573 with open(stm32_assert_h, "w") as stm32_assert_file: 574 stm32_assert_file.write( 575 stm32_assert_j2_template.render(stm32serie=self.stm32_serie) 576 ) 577 578 def build_from_version_update(self): 579 """Build a commit in temporary dir with STM32Cube version 580 corresponding to zephyr latest hal version 581 """ 582 # Checkout the latest version of the upstream STM32Cube repo 583 self.os_cmd( 584 ("git", "checkout", "-f", "--recurse-submodules", self.version_update), 585 cwd=self.stm32cube_serie_path, 586 ) 587 588 # Get the commit id of this latest version 589 self.update_commit = subprocess.check_output( 590 ("git", "rev-parse", "HEAD"), cwd=self.stm32cube_serie_path 591 ).decode("utf-8") 592 593 # clear previous version content before populating with latest version 594 shutil.rmtree( 595 str(self.stm32cube_temp_serie), onerror=common_utils.remove_readonly 596 ) 597 598 # populate temporary directory with latest version 599 self.extract_source() 600 601 # Commit files except log or patch files 602 self.os_cmd(("git", "add", "*"), cwd=self.stm32cube_serie_path) 603 self.os_cmd(("git", "reset", "--", "*.patch"), cwd=self.stm32cube_serie_path) 604 self.os_cmd(("git", "reset", "--", "*.log"), cwd=self.stm32cube_serie_path) 605 self.os_cmd( 606 ("git", "commit", "-am", '"module' + self.version_update + '"'), 607 cwd=self.stm32cube_temp_serie, 608 ) 609 610 def apply_zephyr_patch(self): 611 """Apply zephyr stm32 patch to latest stm32Cube version""" 612 logging.info("%s", "Apply zephyr patches to " + self.version_update) 613 614 # Copy from stm32cube_temp 615 shutil.rmtree( 616 str(self.zephyr_module_serie_path), 617 onerror=common_utils.remove_readonly, 618 ) 619 shutil.copytree(self.stm32cube_temp_serie, self.zephyr_module_serie_path) 620 621 # apply dos2unix to whole zephyr hal serie sub directory 622 for child in self.zephyr_module_serie_path.glob("**/*"): 623 if child.is_file: 624 self.os_cmd(("dos2unix", child), cwd=self.zephyr_module_serie_path) 625 626 # Remove file that will be fully created by zephyr patch 627 # (otherwise applying patch will report error) 628 for file in zephyr_file_created: 629 if Path(self.zephyr_module_serie_path, file).exists(): 630 Path(self.zephyr_module_serie_path, file).unlink() 631 632 # Apply patch from new repo 633 common_utils.apply_patch( 634 str(self.stm32cube_temp / self.module_patch), self.zephyr_hal_stm32_path 635 ) 636 637 # save patch file so that it can be analysed in case of error 638 patch_path = self.zephyr_hal_stm32_path / self.module_patch 639 if patch_path.exists(): 640 os.remove(patch_path) 641 shutil.copy(str(self.stm32cube_temp / self.module_patch), patch_path) 642 643 # Update README and CMakeList, copy release note 644 self.update_readme(self.version_update, self.update_commit) 645 self.update_cmakelist() 646 self.copy_release_note() 647 648 # remove stm32_assert_template.h and create stm32_assert.h 649 self.generate_assert_file() 650 651 # Add files but do not commit 652 self.os_cmd(("git", "add", "*"), cwd=self.zephyr_hal_stm32_path) 653 self.os_cmd(("git", "reset", "--", "*.patch"), cwd=self.zephyr_hal_stm32_path) 654 self.os_cmd(("git", "reset", "--", "*.log"), cwd=self.zephyr_hal_stm32_path) 655 self.os_cmd(("git", "reset", "--", "*.rej"), cwd=self.zephyr_hal_stm32_path) 656 logging.warning( 657 "%s", 658 "README file : --> please check that the Patch list is still valid", 659 ) 660 661 def merge_commit(self, lib=False): 662 """Apply zephyr stm32 patch to latest stm32Cube version""" 663 # Merge & commit 664 # to clean the .rej files, uncomment line: reject() 665 # reject() 666 if lib: 667 logging.info("%s", "commit BLE library update") 668 commit_msg = "lib/stm32: " 669 else: 670 logging.info("%s", "commit HAL/LL Cube update ") 671 commit_msg = "stm32cube: " 672 673 commit_file_path = self.zephyr_module_serie_path / "commit.msg" 674 with open(commit_file_path, "w") as commit: 675 commit.write( 676 commit_msg 677 + "update " 678 + self.stm32_serie 679 + " to cube version " 680 + self.version_update.upper() 681 + "\n" 682 ) 683 684 commit.write("\n") 685 commit.write( 686 "Update Cube version for " + self.stm32_seriexx_upper + " series" + "\n" 687 ) 688 commit.write("on https://github.com/STMicroelectronics" + "\n") 689 commit.write(f"from version {self.current_version}\n") 690 commit.write(f"to version {self.version_update}\n") 691 self.os_cmd( 692 ("git", "commit", "-as", "-F", commit_file_path), 693 cwd=self.zephyr_module_serie_path, 694 ) 695 self.os_cmd( 696 ("git", "rebase", "--whitespace=fix", "HEAD~1"), 697 cwd=self.zephyr_module_serie_path, 698 ) 699 Path(commit_file_path).unlink() 700 701 def reject(self): 702 """Clean *.rej files""" 703 reject_files = [f for f in self.zephyr_module_serie_path.glob("**/*.rej")] 704 if reject_files: 705 for f in reject_files: 706 f.unlink() 707 708 def cleanup_stm32cube_repo(self): 709 """clean the STM32Cube repo""" 710 self.os_cmd(("git", "checkout", "-f", "--recurse-submodules", "HEAD"), 711 cwd=self.stm32cube_serie_path) 712 713 def clean_files(self): 714 """Clean repo file if required""" 715 # Remove temporary files unconditionally 716 os.chdir(os.getenv("HOME")) 717 shutil.rmtree(str(self.stm32cube_temp), onerror=common_utils.remove_readonly) 718 719 # remove STM32Cube repo only if required 720 if not self.noclean: 721 self.cleanup_stm32cube_repo() 722 shutil.rmtree( 723 str(self.stm32cube_repo_path), onerror=common_utils.remove_readonly 724 ) 725 else: 726 self.os_cmd( 727 ("git", "checkout", "-f", "--recurse-submodules", "HEAD"), 728 cwd=self.stm32cube_serie_path, 729 ) 730 731 def update_stm32_hal_serie(self): 732 """Update one single STM32Cube""" 733 # 1) clone full repo from github : get the repo STM32CubeXX 734 self.clone_cube_repo() 735 736 # 2) prepare a repo where to store module versions 737 self.os_cmd(("git", "init"), cwd=self.stm32cube_temp) 738 self.os_cmd( 739 ("git", "commit", "--allow-empty", "-m", "'Trigger notification'"), 740 cwd=self.stm32cube_temp, 741 ) 742 743 # 3) get the version of cube which is in the zephyr module 744 self.current_version = self.get_zephyr_current_version() 745 logging.info( 746 f"Version {self.current_version} is the current zephyr version for " 747 + self.zephyr_module_serie_path.name 748 ) 749 750 # do not process if versions are similar 751 if (self.current_version in self.version_update) or ( 752 self.version_update in self.current_version 753 ): 754 logging.warning( 755 "%s", 756 f"*** Update abandoned: identical versions {self.version_update} ***\n", 757 ) 758 self.clean_files() 759 return 760 logging.info( 761 f"*** Updating zephyr {self.stm32_serie} " 762 + f"from version {self.current_version} to {self.version_update}" 763 ) 764 765 # 4) build the module from this previous version 766 self.build_from_current_cube_version() 767 768 # 5) build the patch from the current zephyr version 769 self.build_patch_from_current_zephyr_version() 770 771 # 6) build the module from this latest version 772 self.build_from_version_update() 773 774 # 7) apply zephyr patch : in the zephyr module repo 775 self.apply_zephyr_patch() 776 self.merge_commit() 777 778 # 8) In case of stm32wb, update ble library 779 if self.stm32_serie == "stm32wb": 780 ble_library.update( 781 self.stm32cube_serie_path, 782 Path(self.zephyr_hal_stm32_path / "lib" / "stm32wb"), 783 self.stm32cube_temp, 784 self.current_version, 785 self.version_update, 786 self.update_commit, 787 self.stm32_serie 788 ) 789 self.merge_commit(lib=True) 790 791 # 9) In case of stm32wba, update hci library 792 elif self.stm32_serie == "stm32wba": 793 ble_library.update( 794 self.stm32cube_serie_path, 795 Path(self.zephyr_hal_stm32_path / "lib" / "stm32wba"), 796 self.stm32cube_temp, 797 self.current_version, 798 self.version_update, 799 self.update_commit, 800 self.stm32_serie 801 ) 802 self.merge_commit(lib=True) 803 804 # 10) clean 805 self.clean_files() 806 logging.info("%s", f"Done {self.stm32_serie}\n") 807