1#!/usr/bin/python 2""" 3SPDX-License-Identifier: Apache-2.0 4Copyright (c) 2019 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 branch = self.major_branch() 196 self.os_cmd( 197 ("git", "reset", "--hard", branch), 198 cwd=self.stm32cube_serie_path, 199 ) 200 else: 201 self.os_cmd( 202 ("git", "clone", repo_name), 203 cwd=self.stm32cube_repo_path, 204 ) 205 branch = self.major_branch() 206 207 logging.info("%s", f"Branch used: {branch}") 208 209 # get the latest version of cube, 210 # with the most recent one created being the last entry. 211 self.os_cmd(("git", "checkout", branch), cwd=self.stm32cube_serie_path) 212 self.version_tag = subprocess.check_output( 213 ("git", "tag", "-l"), cwd=self.stm32cube_serie_path 214 ).splitlines() 215 self.version_tag = [x.decode("utf-8") for x in self.version_tag] 216 # Search latest version 217 if self.version_update == "": 218 self.version_update = self.version_tag[0] 219 for tag in self.version_tag: 220 if version_tuple(tag) > version_tuple(self.version_update): 221 self.version_update = tag 222 223 def get_zephyr_current_version(self): 224 """Look for current zephyr hal version 225 226 Returns: 227 return previous zephyr cube version. 228 229 Raises: 230 ValueError: If version is not found. 231 """ 232 with open(str(self.readme_file_path), "r") as f: 233 for line in f: 234 # pattern : "version " follow by optional "v", 235 # followed by x.y or x.y.z x,y,z may represent several digits 236 # ex: 'version v1.8.9', 'version 10.20.25' 237 pattern = r".*version v?(\d+\.\d+\.?\d*).*$" 238 if re.match(pattern, line): 239 previous_version = re.sub(pattern, r"\1", line).rstrip("\n") 240 break 241 242 # Match previous version and list of existing tags 243 # which could be vx.y or x.y 244 pos_version = [ 245 i for i, a in enumerate(self.version_tag) if previous_version in a 246 ] 247 if pos_version: 248 # return previous zephyr version 249 return self.version_tag[pos_version[0]] 250 else: 251 self.clean_files() 252 raise ValueError( 253 f"Error: cannot find version {previous_version} in STM32Cube_repo" 254 ) 255 256 def extract_source(self): 257 """Extract sources and includes files from STM32Cube repo 258 and copy them in temporary directory 259 """ 260 # for CMSIS files 261 temp_cmsis_soc_path = self.stm32cube_temp_serie / "soc" 262 Path.mkdir(temp_cmsis_soc_path, parents=True) 263 stm32cube_cmsis_include_path = ( 264 self.stm32cube_serie_path 265 / "Drivers" 266 / "CMSIS" 267 / "Device" 268 / "ST" 269 / self.stm32_seriexx_upper 270 / "Include" 271 ) 272 shutil.rmtree(temp_cmsis_soc_path, onerror=common_utils.remove_readonly) 273 shutil.copytree(stm32cube_cmsis_include_path, temp_cmsis_soc_path) 274 275 stm32cube_cmsis_templates_path = ( 276 self.stm32cube_serie_path 277 / "Drivers" 278 / "CMSIS" 279 / "Device" 280 / "ST" 281 / self.stm32_seriexx_upper 282 / "Source" 283 / "Templates" 284 ) 285 for repo_file in stm32cube_cmsis_templates_path.iterdir(): 286 repo_src = stm32cube_cmsis_templates_path / repo_file 287 if repo_src.is_file(): 288 shutil.copy(str(repo_src), str(temp_cmsis_soc_path)) 289 290 # for hal and ll drivers 291 temp_drivers_include_path = self.stm32cube_temp_serie / "drivers" / "include" 292 temp_drivers_include_path.parent.mkdir(parents=True) 293 stm32cube_driver_inc = ( 294 self.stm32cube_serie_path 295 / "Drivers" 296 / Path(self.stm32_seriexx_upper + "_HAL_Driver") 297 / "Inc" 298 ) 299 if temp_drivers_include_path.exists(): 300 shutil.rmtree( 301 temp_drivers_include_path, onerror=common_utils.remove_readonly 302 ) 303 shutil.copytree(stm32cube_driver_inc, temp_drivers_include_path) 304 305 # except for _hal_conf_template.h which is renamed 306 self.rename_conf_template(temp_drivers_include_path) 307 308 temp_drivers_src_path = self.stm32cube_temp_serie / "drivers" / "src" 309 temp_drivers_src_path.mkdir() 310 stm32cube_drivers_src_path = ( 311 self.stm32cube_serie_path 312 / "Drivers" 313 / Path(self.stm32_seriexx_upper + "_HAL_Driver") 314 / "Src" 315 ) 316 shutil.rmtree(temp_drivers_src_path, onerror=common_utils.remove_readonly) 317 shutil.copytree(stm32cube_drivers_src_path, temp_drivers_src_path) 318 319 def build_from_current_cube_version(self): 320 """Build a commit in temporary dir with STM32Cube version 321 corresponding to zephyr current hal version 322 """ 323 # reset the STM32Cube repo to this current version 324 self.os_cmd( 325 ("git", "reset", "--hard", self.current_version), 326 cwd=self.stm32cube_serie_path, 327 ) 328 329 # build the zephyr module from the stm32cube 330 self.extract_source() 331 logging.info( 332 "%s", "Building module from STM32Cube_repo " + self.current_version 333 ) 334 335 if not self.stm32cube_temp_serie.parent.exists(): 336 self.stm32cube_temp_serie.parent.mkdir(parents=True) 337 338 self.os_cmd( 339 ("git", "add", "-A", "stm32cube/" + self.stm32_seriexx + "/*"), 340 cwd=self.stm32cube_temp, 341 ) 342 self.os_cmd( 343 ("git", "commit", "-am", '"module' + self.current_version + '"'), 344 cwd=self.stm32cube_temp, 345 ) 346 # Remove trailing whitespaces 347 self.os_cmd( 348 ("git", "rebase", "--whitespace=fix", "HEAD~1"), 349 cwd=self.stm32cube_temp, 350 ) 351 352 def build_patch_from_current_zephyr_version(self): 353 """Build patch between zephyr current hal version and 354 corresponding official STM32Cube version 355 """ 356 # clean-up the module 357 shutil.rmtree( 358 str(self.stm32cube_temp_serie), onerror=common_utils.remove_readonly 359 ) 360 361 # populate the new repo with this current zephyr module 362 shutil.copytree(self.zephyr_module_serie_path, self.stm32cube_temp_serie) 363 364 # commit this current version module 365 self.os_cmd(("git", "add", "*"), cwd=self.stm32cube_temp) 366 self.os_cmd(("git", "commit", "-am", '"module"'), cwd=self.stm32cube_temp) 367 368 # Remove trailing space 369 self.os_cmd( 370 ("git", "rebase", "--whitespace=fix", "HEAD~1"), 371 cwd=self.stm32cube_temp, 372 ) 373 374 # generate a patch for files and _hal.conf.h file in the module 375 logging.info( 376 "%s", 377 "Building patch from official " 378 + self.current_version 379 + " to current zephyr module", 380 ) 381 382 # For unclear reason, using tuple ("git", "diff", ...) is failing on Linux 383 # especially for this command. Keep a single string. 384 self.os_cmd( 385 ("git diff --ignore-space-at-eol HEAD~1 --output=" + self.module_patch), 386 shell=True, 387 cwd=self.stm32cube_temp, 388 ) 389 self.os_cmd(("dos2unix", self.module_patch), cwd=self.stm32cube_temp) 390 391 def update_readme(self, make_version, make_commit): 392 """Update README file 393 394 Args: 395 make_version: latest STM32Cube version. 396 make_commit: Commit corresponding to latest STM32Cube version. 397 """ 398 see_release_note = True 399 400 readme_path = self.zephyr_module_serie_path / "README" 401 402 with readme_path.open(mode="r") as readme_prev: 403 lines = (x for x in readme_prev.read().splitlines()) 404 405 readme_path.unlink() 406 407 # Write README from previous one if exists 408 with open(str(readme_path), "w") as readme_file: 409 for LineItem in lines: 410 # change version nb 411 if "status" in LineItem.lower(): 412 readme_file.write("Status:\n") 413 readme_file.write(f" version {make_version}\n") 414 next(lines) # skip next line 415 elif "commit" in LineItem.lower(): 416 readme_file.write("Commit:\n") 417 readme_file.write(f" {make_commit}") 418 next(lines) # skip next line 419 elif "URL" in LineItem.upper(): 420 readme_file.write("URL:\n") 421 readme_file.write( 422 " https://github.com/STMicroelectronics/" 423 + f"STM32Cube{self.serie}\n" 424 ) 425 next(lines) # skip next line 426 # change patch list with a link to the release_note.html 427 elif "Patch List" in LineItem: 428 readme_file.write("Patch List:\n") 429 readme_file.write( 430 "--> please check that the following list " 431 + "is still valid:\n" 432 ) 433 else: 434 if "See release_note.html from STM32Cube" in LineItem: 435 see_release_note = False 436 readme_file.write(f"{LineItem}\n") 437 438 # at the very end of the file : 439 if see_release_note: 440 readme_file.write("\n See release_note.html from STM32Cube\n") 441 readme_file.flush() 442 443 self.os_cmd(("dos2unix", str(readme_path))) 444 445 def copy_release_note(self): 446 """Copy release_note.html file from STM32Cube to zephyr""" 447 release_note_src = self.stm32cube_serie_path / "Release_Notes.html" 448 release_note_dst = self.zephyr_module_serie_path / "release_note.html" 449 if release_note_dst.exists(): 450 release_note_dst.unlink() 451 if release_note_src.exists: 452 release_note_src.rename(release_note_dst) 453 self.os_cmd(("dos2unix", str(release_note_dst))) 454 455 def update_cmakelist(self): 456 """Update CMakeLists.txt file""" 457 cmakelists_path = self.zephyr_module_serie_path / "CMakeLists.txt" 458 if cmakelists_path.exists(): 459 # build new CMakeLists.txt 460 with cmakelists_path.open("r") as cmakelists_old: 461 # this line is the copyright line 462 first_line = cmakelists_old.readline() 463 if "STMicroelectronics" in first_line: 464 first_line = "" 465 cmakelists_path.unlink() 466 else: 467 first_line = "" 468 469 logging.info("%s", "Create a new CMakeLists.txt file") 470 471 with cmakelists_path.open("w") as cmakelists_new: 472 if first_line: 473 cmakelists_new.write(first_line) 474 cmakelists_new.write("# Copyright (c) 2020 STMicroelectronics\n") 475 cmakelists_new.write("#\n") 476 cmakelists_new.write("# SPDX-License-Identifier: Apache-2.0\n") 477 cmakelists_new.write("\n") 478 479 src_path = self.stm32cube_temp_serie / "drivers" / "src" 480 source_files = list(src_path.iterdir()) 481 source_files.sort() 482 483 cmakelists_new.write( 484 f"zephyr_library_sources(soc/system_{self.stm32_seriexx}.c)\n" 485 ) 486 cmakelists_new.write( 487 f"zephyr_library_sources(drivers/src/{self.stm32_seriexx}_hal.c)\n" 488 ) 489 cmakelists_new.write( 490 f"zephyr_library_sources(drivers/src/{self.stm32_seriexx}_hal_rcc.c)\n" 491 ) 492 cmakelists_new.write( 493 "zephyr_library_sources(drivers/src/" 494 + f"{self.stm32_seriexx}_hal_rcc_ex.c)\n" 495 ) 496 497 for filename in source_files: 498 # also skipping '_xxx_hal.c' 499 if "template" in filename.name: 500 continue 501 502 # also skipping '_xxx_hal_rcc.c' and '_xxx_hal_rcc_ex.c' 503 if "_hal_rcc" in filename.name: 504 continue 505 506 if "_hal_" in filename.name: 507 # retrieve IP name from filename, like adc, 508 # which is delimited by 509 # * _hal_ on one side 510 # * and file extension on the other side 511 pattern = r".*_hal_(.*)\..*" 512 cmakelists_new.write( 513 "zephyr_library_sources_ifdef(CONFIG_USE_STM32_HAL_" 514 + re.sub(pattern, r"\1", filename.name).upper() 515 + " drivers/src/" 516 + filename.name 517 + ")\n" 518 ) 519 if "_ll_" in filename.name: 520 # retrieve IP name from filename, like adc, 521 # which is delimited by 522 # * _ll_ on one side 523 # * and file extension on the other side 524 pattern = r".*_ll_(.*)\..*" 525 cmakelists_new.write( 526 "zephyr_library_sources_ifdef(CONFIG_USE_STM32_LL_" 527 + re.sub(pattern, r"\1", filename.name).upper() 528 + " drivers/src/" 529 + filename.name 530 + ")\n" 531 ) 532 self.os_cmd(("dos2unix", str(cmakelists_path))) 533 534 def generate_assert_file(self): 535 """Remove stm32_assert_template.h file and create stm32_assert.h file""" 536 # remove stm32_assert_template.h 537 stm32_assert_template = ( 538 self.stm32cube_temp_serie 539 / "drivers" 540 / "include" 541 / "stm32_assert_template.h" 542 ) 543 if stm32_assert_template.exists(): 544 stm32_assert_template.unlink() 545 546 # create stm32_assert.h from Jinja2 template 547 # Create the jinja2 environment. 548 templates_dir = self.zephyr_hal_stm32_path / "scripts" 549 j2_env = Environment( 550 loader=FileSystemLoader(str(templates_dir)), 551 trim_blocks=True, 552 lstrip_blocks=True, 553 ) 554 stm32_assert_j2_template = j2_env.get_template("stm32_assert_template.txt") 555 stm32_assert_h = ( 556 self.stm32cube_temp_serie / "drivers" / "include" / "stm32_assert.h" 557 ) 558 559 with open(stm32_assert_h, "w") as stm32_assert_file: 560 stm32_assert_file.write( 561 stm32_assert_j2_template.render(stm32serie=self.stm32_serie) 562 ) 563 564 def build_from_version_update(self): 565 """Build a commit in temporary dir with STM32Cube version 566 corresponding to zephyr latest hal version 567 """ 568 # reset the STM32Cube repo to this latest version 569 self.os_cmd( 570 ("git", "reset", "--hard", self.version_update), 571 cwd=self.stm32cube_serie_path, 572 ) 573 574 # Get the commit id of this latest version 575 self.update_commit = subprocess.check_output( 576 ("git", "rev-parse", "HEAD"), cwd=self.stm32cube_serie_path 577 ).decode("utf-8") 578 579 # clear previous version content before populating with latest version 580 shutil.rmtree( 581 str(self.stm32cube_temp_serie), onerror=common_utils.remove_readonly 582 ) 583 584 # populate temporary directory with latest version 585 self.extract_source() 586 587 # Commit files except log or patch files 588 self.os_cmd(("git", "add", "*"), cwd=self.stm32cube_serie_path) 589 self.os_cmd(("git", "reset", "--", "*.patch"), cwd=self.stm32cube_serie_path) 590 self.os_cmd(("git", "reset", "--", "*.log"), cwd=self.stm32cube_serie_path) 591 self.os_cmd( 592 ("git", "commit", "-am", '"module' + self.version_update + '"'), 593 cwd=self.stm32cube_temp_serie, 594 ) 595 596 def apply_zephyr_patch(self): 597 """Apply zephyr stm32 patch to latest stm32Cube version""" 598 logging.info("%s", "Apply zephyr patches to " + self.version_update) 599 600 # Copy from stm32cube_temp 601 shutil.rmtree( 602 str(self.zephyr_module_serie_path), 603 onerror=common_utils.remove_readonly, 604 ) 605 shutil.copytree(self.stm32cube_temp_serie, self.zephyr_module_serie_path) 606 607 # apply dos2unix to whole zephyr hal serie sub directory 608 for child in self.zephyr_module_serie_path.glob("**/*"): 609 if child.is_file: 610 self.os_cmd(("dos2unix", child), cwd=self.zephyr_module_serie_path) 611 612 # Remove file that will be fully created by zephyr patch 613 # (otherwise applying patch will report error) 614 for file in zephyr_file_created: 615 if Path(self.zephyr_module_serie_path, file).exists(): 616 Path(self.zephyr_module_serie_path, file).unlink() 617 618 # Apply patch from new repo 619 common_utils.apply_patch( 620 str(self.stm32cube_temp / self.module_patch), self.zephyr_hal_stm32_path 621 ) 622 623 # save patch file so that it can be analysed in case of error 624 patch_path = self.zephyr_hal_stm32_path / self.module_patch 625 if patch_path.exists(): 626 os.remove(patch_path) 627 shutil.copy(str(self.stm32cube_temp / self.module_patch), patch_path) 628 629 # Update README and CMakeList, copy release note 630 self.update_readme(self.version_update, self.update_commit) 631 self.update_cmakelist() 632 self.copy_release_note() 633 634 # remove stm32_assert_template.h and create stm32_assert.h 635 self.generate_assert_file() 636 637 # Add files but do not commit 638 self.os_cmd(("git", "add", "*"), cwd=self.zephyr_hal_stm32_path) 639 self.os_cmd(("git", "reset", "--", "*.patch"), cwd=self.zephyr_hal_stm32_path) 640 self.os_cmd(("git", "reset", "--", "*.log"), cwd=self.zephyr_hal_stm32_path) 641 self.os_cmd(("git", "reset", "--", "*.rej"), cwd=self.zephyr_hal_stm32_path) 642 logging.warning( 643 "%s", 644 "README file : --> please check that the Patch list is still valid", 645 ) 646 647 def merge_commit(self, lib=False): 648 """Apply zephyr stm32 patch to latest stm32Cube version""" 649 # Merge & commit 650 # to clean the .rej files, uncomment line: reject() 651 # reject() 652 if lib: 653 logging.info("%s", "commit BLE library update") 654 commit_msg = "lib/stm32: " 655 else: 656 logging.info("%s", "commit HAL/LL Cube update ") 657 commit_msg = "stm32cube: " 658 659 commit_file_path = self.zephyr_module_serie_path / "commit.msg" 660 with open(commit_file_path, "w") as commit: 661 commit.write( 662 commit_msg 663 + "update " 664 + self.stm32_serie 665 + " to cube version " 666 + self.version_update.upper() 667 + "\n" 668 ) 669 670 commit.write("\n") 671 commit.write( 672 "Update Cube version for " + self.stm32_seriexx_upper + " series" + "\n" 673 ) 674 commit.write("on https://github.com/STMicroelectronics" + "\n") 675 commit.write(f"from version {self.current_version}\n") 676 commit.write(f"to version {self.version_update}\n") 677 self.os_cmd( 678 ("git", "commit", "-as", "-F", commit_file_path), 679 cwd=self.zephyr_module_serie_path, 680 ) 681 self.os_cmd( 682 ("git", "rebase", "--whitespace=fix", "HEAD~1"), 683 cwd=self.zephyr_module_serie_path, 684 ) 685 Path(commit_file_path).unlink() 686 687 def reject(self): 688 """Clean *.rej files""" 689 reject_files = [f for f in self.zephyr_module_serie_path.glob("**/*.rej")] 690 if reject_files: 691 for f in reject_files: 692 f.unlink() 693 694 def cleanup_stm32cube_repo(self): 695 """clean the STM32Cube repo""" 696 self.os_cmd(("git", "reset", "--hard", "HEAD"), cwd=self.stm32cube_serie_path) 697 698 def clean_files(self): 699 """Clean repo file if required""" 700 # Remove temporary files unconditionally 701 os.chdir(os.getenv("HOME")) 702 shutil.rmtree(str(self.stm32cube_temp), onerror=common_utils.remove_readonly) 703 704 # remove STM32Cube repo only if required 705 if not self.noclean: 706 self.cleanup_stm32cube_repo() 707 shutil.rmtree( 708 str(self.stm32cube_repo_path), onerror=common_utils.remove_readonly 709 ) 710 else: 711 self.os_cmd( 712 ("git", "reset", "--hard", "HEAD"), 713 cwd=self.stm32cube_serie_path, 714 ) 715 716 def update_stm32_hal_serie(self): 717 """Update one single STM32Cube""" 718 # 1) clone full repo from github : get the repo STM32CubeXX 719 self.clone_cube_repo() 720 721 # 2) prepare a repo where to store module versions 722 self.os_cmd(("git", "init"), cwd=self.stm32cube_temp) 723 self.os_cmd( 724 ("git", "commit", "--allow-empty", "-m", "'Trigger notification'"), 725 cwd=self.stm32cube_temp, 726 ) 727 728 # 3) get the version of cube which is in the zephyr module 729 self.current_version = self.get_zephyr_current_version() 730 logging.info( 731 f"Version {self.current_version} is the current zephyr version for " 732 + self.zephyr_module_serie_path.name 733 ) 734 735 # do not process if versions are similar 736 if (self.current_version in self.version_update) or ( 737 self.version_update in self.current_version 738 ): 739 logging.warning( 740 "%s", 741 f"*** Update abandoned: identical versions {self.version_update} ***\n", 742 ) 743 self.clean_files() 744 return 745 logging.info( 746 f"*** Updating zephyr {self.stm32_serie} " 747 + f"from version {self.current_version} to {self.version_update}" 748 ) 749 750 # 4) build the module from this previous version 751 self.build_from_current_cube_version() 752 753 # 5) build the patch from the current zephyr version 754 self.build_patch_from_current_zephyr_version() 755 756 # 6) build the module from this latest version 757 self.build_from_version_update() 758 759 # 7) apply zephyr patch : in the zephyr module repo 760 self.apply_zephyr_patch() 761 self.merge_commit() 762 763 # 8) In case of stm32wb, update ble library 764 if self.stm32_serie == "stm32wb": 765 ble_library.update( 766 self.stm32cube_serie_path, 767 Path(self.zephyr_hal_stm32_path / "lib"), 768 self.stm32cube_temp, 769 self.current_version, 770 self.version_update, 771 self.update_commit, 772 ) 773 self.merge_commit(lib=True) 774 775 # 9) clean 776 self.clean_files() 777 logging.info("%s", f"Done {self.stm32_serie}\n") 778