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 update_cmakelist(self): 460 """Update CMakeLists.txt file""" 461 cmakelists_path = self.zephyr_module_serie_path / "CMakeLists.txt" 462 if cmakelists_path.exists(): 463 # build new CMakeLists.txt 464 with cmakelists_path.open("r") as cmakelists_old: 465 # this line is the copyright line 466 first_line = cmakelists_old.readline() 467 if "STMicroelectronics" in first_line: 468 first_line = "" 469 cmakelists_path.unlink() 470 else: 471 first_line = "" 472 473 logging.info("%s", "Create a new CMakeLists.txt file") 474 475 with cmakelists_path.open("w") as cmakelists_new: 476 if first_line: 477 cmakelists_new.write(first_line) 478 cmakelists_new.write("# Copyright (c) 2020 STMicroelectronics\n") 479 cmakelists_new.write("#\n") 480 cmakelists_new.write("# SPDX-License-Identifier: Apache-2.0\n") 481 cmakelists_new.write("\n") 482 483 src_path = self.stm32cube_temp_serie / "drivers" / "src" 484 source_files = list(src_path.iterdir()) 485 source_files.sort() 486 487 cmakelists_new.write( 488 f"zephyr_library_sources(soc/system_{self.stm32_seriexx}.c)\n" 489 ) 490 cmakelists_new.write( 491 f"zephyr_library_sources(drivers/src/{self.stm32_seriexx}_hal.c)\n" 492 ) 493 cmakelists_new.write( 494 f"zephyr_library_sources(drivers/src/{self.stm32_seriexx}_hal_rcc.c)\n" 495 ) 496 cmakelists_new.write( 497 "zephyr_library_sources(drivers/src/" 498 + f"{self.stm32_seriexx}_hal_rcc_ex.c)\n" 499 ) 500 501 for filename in source_files: 502 # also skipping '_xxx_hal.c' 503 if "template" in filename.name: 504 continue 505 506 # also skipping '_xxx_hal_rcc.c' and '_xxx_hal_rcc_ex.c' 507 if "_hal_rcc" in filename.name: 508 continue 509 510 if "_hal_" in filename.name: 511 # retrieve IP name from filename, like adc, 512 # which is delimited by 513 # * _hal_ on one side 514 # * and file extension on the other side 515 pattern = r".*_hal_(.*)\..*" 516 cmakelists_new.write( 517 "zephyr_library_sources_ifdef(CONFIG_USE_STM32_HAL_" 518 + re.sub(pattern, r"\1", filename.name).upper() 519 + " drivers/src/" 520 + filename.name 521 + ")\n" 522 ) 523 if "_ll_" in filename.name: 524 # retrieve IP name from filename, like adc, 525 # which is delimited by 526 # * _ll_ on one side 527 # * and file extension on the other side 528 pattern = r".*_ll_(.*)\..*" 529 cmakelists_new.write( 530 "zephyr_library_sources_ifdef(CONFIG_USE_STM32_LL_" 531 + re.sub(pattern, r"\1", filename.name).upper() 532 + " drivers/src/" 533 + filename.name 534 + ")\n" 535 ) 536 self.os_cmd(("dos2unix", str(cmakelists_path))) 537 538 def generate_assert_file(self): 539 """Remove stm32_assert_template.h file and create stm32_assert.h file""" 540 # remove stm32_assert_template.h 541 stm32_assert_template = ( 542 self.stm32cube_temp_serie 543 / "drivers" 544 / "include" 545 / "stm32_assert_template.h" 546 ) 547 if stm32_assert_template.exists(): 548 stm32_assert_template.unlink() 549 550 # create stm32_assert.h from Jinja2 template 551 # Create the jinja2 environment. 552 templates_dir = self.zephyr_hal_stm32_path / "scripts" 553 j2_env = Environment( 554 loader=FileSystemLoader(str(templates_dir)), 555 trim_blocks=True, 556 lstrip_blocks=True, 557 ) 558 stm32_assert_j2_template = j2_env.get_template("stm32_assert_template.txt") 559 stm32_assert_h = ( 560 self.stm32cube_temp_serie / "drivers" / "include" / "stm32_assert.h" 561 ) 562 563 with open(stm32_assert_h, "w") as stm32_assert_file: 564 stm32_assert_file.write( 565 stm32_assert_j2_template.render(stm32serie=self.stm32_serie) 566 ) 567 568 def build_from_version_update(self): 569 """Build a commit in temporary dir with STM32Cube version 570 corresponding to zephyr latest hal version 571 """ 572 # Checkout the latest version of the upstream STM32Cube repo 573 self.os_cmd( 574 ("git", "checkout", "-f", "--recurse-submodules", self.version_update), 575 cwd=self.stm32cube_serie_path, 576 ) 577 578 # Get the commit id of this latest version 579 self.update_commit = subprocess.check_output( 580 ("git", "rev-parse", "HEAD"), cwd=self.stm32cube_serie_path 581 ).decode("utf-8") 582 583 # clear previous version content before populating with latest version 584 shutil.rmtree( 585 str(self.stm32cube_temp_serie), onerror=common_utils.remove_readonly 586 ) 587 588 # populate temporary directory with latest version 589 self.extract_source() 590 591 # Commit files except log or patch files 592 self.os_cmd(("git", "add", "*"), cwd=self.stm32cube_serie_path) 593 self.os_cmd(("git", "reset", "--", "*.patch"), cwd=self.stm32cube_serie_path) 594 self.os_cmd(("git", "reset", "--", "*.log"), cwd=self.stm32cube_serie_path) 595 self.os_cmd( 596 ("git", "commit", "-am", '"module' + self.version_update + '"'), 597 cwd=self.stm32cube_temp_serie, 598 ) 599 600 def apply_zephyr_patch(self): 601 """Apply zephyr stm32 patch to latest stm32Cube version""" 602 logging.info("%s", "Apply zephyr patches to " + self.version_update) 603 604 # Copy from stm32cube_temp 605 shutil.rmtree( 606 str(self.zephyr_module_serie_path), 607 onerror=common_utils.remove_readonly, 608 ) 609 shutil.copytree(self.stm32cube_temp_serie, self.zephyr_module_serie_path) 610 611 # apply dos2unix to whole zephyr hal serie sub directory 612 for child in self.zephyr_module_serie_path.glob("**/*"): 613 if child.is_file: 614 self.os_cmd(("dos2unix", child), cwd=self.zephyr_module_serie_path) 615 616 # Remove file that will be fully created by zephyr patch 617 # (otherwise applying patch will report error) 618 for file in zephyr_file_created: 619 if Path(self.zephyr_module_serie_path, file).exists(): 620 Path(self.zephyr_module_serie_path, file).unlink() 621 622 # Apply patch from new repo 623 common_utils.apply_patch( 624 str(self.stm32cube_temp / self.module_patch), self.zephyr_hal_stm32_path 625 ) 626 627 # save patch file so that it can be analysed in case of error 628 patch_path = self.zephyr_hal_stm32_path / self.module_patch 629 if patch_path.exists(): 630 os.remove(patch_path) 631 shutil.copy(str(self.stm32cube_temp / self.module_patch), patch_path) 632 633 # Update README and CMakeList 634 self.update_readme(self.version_update, self.update_commit) 635 self.update_cmakelist() 636 637 # remove stm32_assert_template.h and create stm32_assert.h 638 self.generate_assert_file() 639 640 # Add files but do not commit 641 self.os_cmd(("git", "add", "*"), cwd=self.zephyr_hal_stm32_path) 642 self.os_cmd(("git", "reset", "--", "*.patch"), cwd=self.zephyr_hal_stm32_path) 643 self.os_cmd(("git", "reset", "--", "*.log"), cwd=self.zephyr_hal_stm32_path) 644 self.os_cmd(("git", "reset", "--", "*.rej"), cwd=self.zephyr_hal_stm32_path) 645 logging.warning( 646 "%s", 647 "README file : --> please check that the Patch list is still valid", 648 ) 649 650 def merge_commit(self, lib=False): 651 """Apply zephyr stm32 patch to latest stm32Cube version""" 652 # Merge & commit 653 # to clean the .rej files, uncomment line: reject() 654 # reject() 655 if lib: 656 logging.info("%s", "commit BLE library update") 657 commit_msg = "lib/stm32: " 658 else: 659 logging.info("%s", "commit HAL/LL Cube update ") 660 commit_msg = "stm32cube: " 661 662 commit_file_path = self.zephyr_module_serie_path / "commit.msg" 663 with open(commit_file_path, "w") as commit: 664 commit.write( 665 commit_msg 666 + "update " 667 + self.stm32_serie 668 + " to cube version " 669 + self.version_update.upper() 670 + "\n" 671 ) 672 673 commit.write("\n") 674 commit.write( 675 "Update Cube version for " + self.stm32_seriexx_upper + " series" + "\n" 676 ) 677 commit.write("on https://github.com/STMicroelectronics" + "\n") 678 commit.write(f"from version {self.current_version}\n") 679 commit.write(f"to version {self.version_update}\n") 680 self.os_cmd( 681 ("git", "commit", "-as", "-F", commit_file_path), 682 cwd=self.zephyr_module_serie_path, 683 ) 684 self.os_cmd( 685 ("git", "rebase", "--whitespace=fix", "HEAD~1"), 686 cwd=self.zephyr_module_serie_path, 687 ) 688 Path(commit_file_path).unlink() 689 690 def reject(self): 691 """Clean *.rej files""" 692 reject_files = [f for f in self.zephyr_module_serie_path.glob("**/*.rej")] 693 if reject_files: 694 for f in reject_files: 695 f.unlink() 696 697 def cleanup_stm32cube_repo(self): 698 """clean the STM32Cube repo""" 699 self.os_cmd(("git", "checkout", "-f", "--recurse-submodules", "HEAD"), 700 cwd=self.stm32cube_serie_path) 701 702 def clean_files(self): 703 """Clean repo file if required""" 704 # Remove temporary files unconditionally 705 os.chdir(os.getenv("HOME")) 706 shutil.rmtree(str(self.stm32cube_temp), onerror=common_utils.remove_readonly) 707 708 # remove STM32Cube repo only if required 709 if not self.noclean: 710 self.cleanup_stm32cube_repo() 711 shutil.rmtree( 712 str(self.stm32cube_repo_path), onerror=common_utils.remove_readonly 713 ) 714 else: 715 self.os_cmd( 716 ("git", "checkout", "-f", "--recurse-submodules", "HEAD"), 717 cwd=self.stm32cube_serie_path, 718 ) 719 720 def update_stm32_hal_serie(self): 721 """Update one single STM32Cube""" 722 # 1) clone full repo from github : get the repo STM32CubeXX 723 self.clone_cube_repo() 724 725 # 2) prepare a repo where to store module versions 726 self.os_cmd(("git", "init"), cwd=self.stm32cube_temp) 727 self.os_cmd( 728 ("git", "commit", "--allow-empty", "-m", "'Trigger notification'"), 729 cwd=self.stm32cube_temp, 730 ) 731 732 # 3) get the version of cube which is in the zephyr module 733 self.current_version = self.get_zephyr_current_version() 734 logging.info( 735 f"Version {self.current_version} is the current zephyr version for " 736 + self.zephyr_module_serie_path.name 737 ) 738 739 # do not process if versions are similar 740 if (self.current_version in self.version_update) or ( 741 self.version_update in self.current_version 742 ): 743 logging.warning( 744 "%s", 745 f"*** Update abandoned: identical versions {self.version_update} ***\n", 746 ) 747 self.clean_files() 748 return 749 logging.info( 750 f"*** Updating zephyr {self.stm32_serie} " 751 + f"from version {self.current_version} to {self.version_update}" 752 ) 753 754 # 4) build the module from this previous version 755 self.build_from_current_cube_version() 756 757 # 5) build the patch from the current zephyr version 758 self.build_patch_from_current_zephyr_version() 759 760 # 6) build the module from this latest version 761 self.build_from_version_update() 762 763 # 7) apply zephyr patch : in the zephyr module repo 764 self.apply_zephyr_patch() 765 self.merge_commit() 766 767 # 8) In case of stm32wb, update ble library 768 if self.stm32_serie == "stm32wb": 769 ble_library.update( 770 self.stm32cube_serie_path, 771 Path(self.zephyr_hal_stm32_path / "lib" / "stm32wb"), 772 self.stm32cube_temp, 773 self.current_version, 774 self.version_update, 775 self.update_commit, 776 self.stm32_serie 777 ) 778 self.merge_commit(lib=True) 779 780 # 9) In case of stm32wba, update hci library 781 elif self.stm32_serie == "stm32wba": 782 ble_library.update( 783 self.stm32cube_serie_path, 784 Path(self.zephyr_hal_stm32_path / "lib" / "stm32wba"), 785 self.stm32cube_temp, 786 self.current_version, 787 self.version_update, 788 self.update_commit, 789 self.stm32_serie 790 ) 791 self.merge_commit(lib=True) 792 793 # 10) clean 794 self.clean_files() 795 logging.info("%s", f"Done {self.stm32_serie}\n") 796