def download_single_cpu(connection, jlink_device_name, guard_time_seconds, build_dir, env, printer, prompt): '''Assemble the call list''' # Note that we use JLink to do the download # rather than the default of nrfjprog since there # appears to be no way to prevent nrfjprog from # resetting the target after the download when # it is used under west (whereas when JLink is # used this is the default) call_list = [ "west", "flash", "-d", build_dir, "--runner", "jlink", "--erase", "--no-reset-after-load" ] tool_opt = "-Autoconnect 1 -ExitOnError 1 -NoGui 1" if jlink_device_name: call_list.extend(["--device", jlink_device_name]) # Add the options that have to go through "--tool-opt" if connection and "debugger" in connection and connection["debugger"]: tool_opt += " -USB " + connection["debugger"] if tool_opt: call_list.extend(["--tool-opt", tool_opt]) print_call_list(call_list, printer, prompt) # Call it return u_utils.exe_run(call_list, guard_time_seconds, printer, prompt, shell_cmd=True, set_env=env)
def download(connection, guard_time_seconds, hex_path, printer, prompt): '''Download the given hex file to an attached NRF52 board''' call_list = [] # Assemble the call list call_list.append("nrfjprog") call_list.append("-f") call_list.append("nrf52") call_list.append("--program") call_list.append(hex_path) call_list.append("--chiperase") call_list.append("--verify") if connection and "debugger" in connection and connection["debugger"]: call_list.append("-s") call_list.append(connection["debugger"]) # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Call it return u_utils.exe_run(call_list, guard_time_seconds, printer, prompt)
def create_lint_config(lint_platform_path, defines, printer, prompt): '''Create the Lint configuration files''' call_list = [] # Get the defines if defines: # Create the CFLAGS string cflags = "" for idx, define in enumerate(defines): if idx == 0: cflags = "-D" + define else: cflags += " -D" + define # Run make to create the configuration files call_list.append("make") if defines: call_list.append("CFLAGS=" + cflags) call_list.append("-f") call_list.append(lint_platform_path + os.sep + "co-gcc.mak") # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Call it return u_utils.exe_run(call_list, None, printer, prompt)
def set_env(printer, prompt): '''Run the batch files that set up the environment variables''' returned_env = {} returned_env1 = {} returned_env2 = {} count = 0 # It is possible for the process of extracting # the environment variables to fail due to machine # loading (see comments against EXE_RUN_QUEUE_WAIT_SECONDS # in exe_run) so give this up to three chances to succeed while not returned_env1 and (count < 3): # set shell to True to keep Jenkins happy u_utils.exe_run([ZEPHYR_ENV_CMD], None, printer, prompt, shell_cmd=True, returned_env=returned_env1) if not returned_env1: printer.string("{}warning: retrying {} to capture" \ " the environment variables...". format(prompt, ZEPHYR_ENV_CMD)) count += 1 count = 0 if returned_env1: while not returned_env2 and (count < 3): # set shell to True to keep Jenkins happy u_utils.exe_run([GIT_BASH_ENV_CMD], None, printer, prompt, shell_cmd=True, returned_env=returned_env2) if not returned_env2: printer.string("{}warning: retrying {} to capture" \ " the environment variables...". format(prompt, GIT_BASH_ENV_CMD)) count += 1 if returned_env2: returned_env = {**returned_env1, **returned_env2} return returned_env
def download(connection, jlink_device_name, guard_time_seconds, build_dir, env, printer, prompt): '''Download the given hex file''' call_list = [] tool_opt = "-Autoconnect 1 -ExitOnError 1 -NoGui 1" # Assemble the call list # Note that we use JLink to do the download # rather than the default of nrfjprog since there # appears to be no way to prevent nrfjprog from # resetting the target after the download when # it is used under west (whereas when JLink is # used this is the default) call_list.append("west") call_list.append("flash") call_list.append("--skip-rebuild") call_list.append("-d") call_list.append(build_dir) call_list.append("--runner") call_list.append("jlink") call_list.append("--erase") # Just to be sure call_list.append("--no-reset-after-load") if jlink_device_name: call_list.append("--device") call_list.append(jlink_device_name) # Add the options that have to go through "--tool-opt" if connection and "debugger" in connection and connection["debugger"]: tool_opt += " -USB " + connection["debugger"] if tool_opt: call_list.append("--tool-opt") call_list.append(tool_opt) # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Call it return u_utils.exe_run(call_list, guard_time_seconds, printer, prompt, shell_cmd=True, set_env=env)
def run_command(call_list, guard_time_seconds, printer, prompt, keep_going_flag): '''Run an external command''' # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Do it, setting shell to True to keep Jenkins happy return u_utils.exe_run(call_list, guard_time_seconds, printer, prompt, shell_cmd=True, keep_going_flag=keep_going_flag)
def download(esp_idf_dir, ubxlib_dir, build_dir, serial_port, env, printer, prompt): '''Download a build to the target''' call_list = [] # Assemble the call list for the download process call_list.append("python") call_list.append(esp_idf_dir + os.sep + "tools\\idf.py") call_list.append("-p") call_list.append(serial_port) call_list.append("-C") call_list.append(ubxlib_dir + os.sep + \ "port\\platform\\esp-idf\\mcu\\esp32" + os.sep + PROJECT_SUBDIR) call_list.append("-B") call_list.append(build_dir) call_list.append("flash") # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Give ourselves priority here or the download can fail psutil.Process().nice(psutil.HIGH_PRIORITY_CLASS) # Do the download, # set shell to True to keep Jenkins happy return_code = u_utils.exe_run(call_list, DOWNLOAD_GUARD_TIME_SECONDS, printer, prompt, shell_cmd=True, set_env=env) # Return priority to normal psutil.Process().nice(psutil.NORMAL_PRIORITY_CLASS) return return_code
def download(esp_idf_dir, ubxlib_dir, build_dir, serial_port, env, printer, prompt): '''Download a build to the target''' call_list = [] # Assemble the call list for the download process call_list.append("python") call_list.append(esp_idf_dir + os.sep + "tools" + os.sep + "idf.py") call_list.append("-p") call_list.append(serial_port) call_list.append("-C") call_list.append(ubxlib_dir + os.sep + ESP32_PORT_SUBDIR + os.sep + PROJECT_SUBDIR) call_list.append("-B") call_list.append(build_dir) call_list.append("flash") # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Give ourselves priority here or the download can fail u_utils.set_process_prio_high() # Do the download, # set shell to True to keep Jenkins happy return_code = u_utils.exe_run(call_list, DOWNLOAD_GUARD_TIME_SECONDS, printer, prompt, shell_cmd=True, set_env=env) # Return priority to normal u_utils.set_process_prio_normal() return return_code
def download(connection, guard_time_seconds, elf_path, printer, prompt): '''Download the given binary file''' call_list = [] call_list.append(STM32_PROGRAMMER_CLI_PATH) call_list.append("-q") # no progress bar call_list.append("-c") # connect call_list.append("port=SWD") # via SWD if connection and "debugger" in connection and connection["debugger"]: # Connect to the given debugger call_list.append("sn=" + connection["debugger"]) call_list.append("-w") # write the call_list.append(elf_path) # ELF file call_list.append("-rst") # and reset the target # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Call it return u_utils.exe_run(call_list, guard_time_seconds, printer, prompt)
def build_gcc(clean, build_subdir, ubxlib_dir, unity_dir, defines, printer, prompt, reporter, keep_going_flag): '''Build on GCC''' call_list = [] hex_file_path = None makefile = ubxlib_dir + os.sep + RUNNER_DIR_GCC + os.sep + "Makefile" outputdir = os.getcwd() + os.sep + build_subdir # The Nordic Makefile.common that is included by our Makefile # is quite limited and weird behaiviours: # 1. It is not possible to specify an OUTPUT_DIRECTORY that # is not on the same drive as the source code. In our case # the source code is mounted as a subst device in the Windows # case. # 2. Makefile.common expects having a "Makefile" in the current # directory. However, since we want the build output to be placed # outside the source tree and due to 1) we want to call our # Makefile using "make -f $UBXLIB_DIR/$RUNNER_DIR_GCC/Makefile" # from a workdir. In this case the Makefile will NOT be located # in current directory. So to get nRF5 SDK Makefile.common happy # we fake this Makefile with an empty file: Path('./Makefile').touch() # Clear the output folder if we're not just running if not clean or u_utils.deltree(outputdir, printer, prompt): if defines: # Create the CFLAGS string cflags = "" for idx, define in enumerate(defines): if idx == 0: cflags = "-D" + define else: cflags += " -D" + define # Note: when entering things from the command-line # if there is more than one CFLAGS parameter then # they must be quoted but that is specifically # NOT required here as the fact that CFLAGS # is passed in as one array entry is sufficient # Assemble the whole call list call_list += ["make", "-j8", "-f", makefile] call_list.append("NRF5_PATH=" + NRF5SDK_PATH) call_list.append("UNITY_PATH=" + unity_dir.replace("\\", "/")) if defines: call_list.append("CFLAGS=" + cflags) call_list.append("OUTPUT_DIRECTORY=" + build_subdir) call_list.append("GNU_VERSION=" + GNU_VERSION) call_list.append("GNU_PREFIX=" + GNU_PREFIX) call_list.append("GNU_INSTALL_ROOT=" + GNU_INSTALL_ROOT) # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Call make to do the build # Set shell to keep Jenkins happy if u_utils.exe_run(call_list, BUILD_GUARD_TIME_SECONDS, printer, prompt, shell_cmd=True, keep_going_flag=keep_going_flag): hex_file_path = outputdir + \ os.sep + "nrf52840_xxaa.hex" else: reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED, "unable to clean build directory") return hex_file_path
def build_ses(clean, ubxlib_dir, defines, printer, prompt, reporter): '''Build on SES''' call_list = [] ses_dir = ubxlib_dir + os.sep + RUNNER_DIR_SES output_dir = os.getcwd() + os.sep + BUILD_SUBDIR_SES too_many_defines = False hex_file_path = None # Put the path to SES builder at the front of the call list call_list.append(SES_PATH + os.sep + SES_NAME) # Then the -config switch with the configuration and project name call_list.append("-config") call_list.append("".join(SES_BUILD_CONFIGURATION)) call_list.append("".join( (ses_dir + os.sep + PROJECT_NAME_SES + ".emProject").replace( "\\", "/"))) # Set the output directory call_list.append("-property") call_list.append("".join( ("build_output_directory=" + output_dir).replace("\\", "/"))) call_list.append("-property") call_list.append("".join(("build_intermediate_directory=" + output_dir + os.sep + "obj").replace("\\", "/"))) # Add verbose echo otherwise SES builder can be a tad quiet call_list.append("-echo") call_list.append("-verbose") if defines: # Create the U_FLAGS entries for idx, define in enumerate(defines): if idx >= SES_MAX_NUM_DEFINES: too_many_defines = True string = "{}{} #defines supplied but only" \ " {} are supported by this Segger" \ " Embedded Studio project file". \ format(prompt, len(defines), SES_MAX_NUM_DEFINES) reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_ERROR, string) printer.string(string) break # Note that the quotes which are required on the # command-line when including a define of the format # BLAH=XXX are not required here. call_list.append("-D") call_list.append("U_FLAG" + str(idx) + "=" + define) if not too_many_defines: # Add the nRF5 SDK path and Unity paths, # making sure that SES gets "/" as it likes # and not "\" call_list.append("-D") call_list.append("NRF5_PATH=" + "".join(NRF5SDK_PATH.replace("\\", "/"))) call_list.append("-D") call_list.append("UNITY_PATH=" + "".join((os.getcwd() + os.sep + u_utils.UNITY_SUBDIR).replace("\\", "/"))) # Clear the output folder if we're not just running if not clean or u_utils.deltree(BUILD_SUBDIR_SES, printer, prompt): # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Call Segger Embedded Studio builder to do the build # Set shell to keep Jenkins happy if u_utils.exe_run(call_list, BUILD_GUARD_TIME_SECONDS, printer, prompt, shell_cmd=True): hex_file_path = output_dir + os.sep + PROJECT_NAME_SES + ".hex" else: reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_ERROR, "unable to clean build directory") return hex_file_path
def build_binary(mcu_dir, workspace_subdir, project_name, clean, defines, printer, prompt): '''Build''' call_list = [] build_dir = mcu_dir + os.sep + project_name + os.sep + PROJECT_CONFIGURATION num_defines = 0 too_many_defines = False elf_path = None # The STM32Cube IDE doesn't provide # a mechanism to override the build # output directory in the .cproject file # from the command-line so I'm afraid # all output will end up in a # sub-directory with the name of the # PROJECT_CONFIGURATION off the project # directory. <sigh> printer.string("{}building in {}.".format(prompt, build_dir)) if not clean or u_utils.deltree(build_dir, printer, prompt): for idx, define in enumerate(defines): # Add the #defines as environment variables # Note that these must be deleted afterwards # in case someone else is going to use the # worker that this was run in if idx >= MAX_NUM_DEFINES: too_many_defines = True printer.string("{}{} #defines" \ " supplied but only" \ " {} are supported by" \ " this STM32Cube IDE" \ " project file".format(prompt, len(defines), MAX_NUM_DEFINES)) break os.environ["U_FLAG" + str(idx)] = "-D" + define num_defines += 1 # Print the environment variables for debug purposes printer.string("{}environment is:".format(prompt)) text = subprocess.check_output([ "set", ], shell=True) for line in text.splitlines(): printer.string("{}{}".format(prompt, line.decode())) if not too_many_defines: # Delete the workspace sub-directory first if it is there # to avoid the small chance that the name has been used # previously, in which case the import would fail u_utils.deltree(workspace_subdir, printer, prompt) # Assemble the whole call list # # The documentation for command-line, AKA # headless, use of Eclipse can be found here: # https://gnu-mcu-eclipse.github.io/advanced/headless-builds/ # # And you can get help by running stm32cubeidec with # the command-line: # # stm32cubeidec.exe --launcher.suppressErrors -nosplash # -application org.eclipse.cdt.managedbuilder.core.headlessbuild # -data PATH_TO_YOUR_WORKSPACE -help # # This information found nailed to the door of the # bog in the basement underneath the "beware of the # leopard" sign call_list.append(STM32CUBE_IDE_PATH + os.sep + "stm32cubeidec.exe") call_list.append("--launcher.suppressErrors") call_list.append("-nosplash") call_list.append("-application") call_list.append( "org.eclipse.cdt.managedbuilder.core.headlessbuild") call_list.append("-data") call_list.append(workspace_subdir) call_list.append("-import") call_list.append(mcu_dir + os.sep + project_name) call_list.append("-no-indexer") call_list.append("-build") call_list.append(project_name + "/" + PROJECT_CONFIGURATION) call_list.append("-console") # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Call stm32cubeidec.exe to do the build if (u_utils.exe_run(call_list, BUILD_GUARD_TIME_SECONDS, printer, prompt)): # The binary should be elf_path = build_dir + os.sep + project_name + ".elf" # Delete the environment variables again while num_defines > 0: num_defines -= 1 del os.environ["U_FLAG" + str(num_defines)] return elf_path
def run(instance, defines, ubxlib_dir, working_dir, printer, reporter, keep_going_flag=None): '''Build to check static sizes''' return_value = -1 instance_text = u_utils.get_instance_text(instance) map_file_path = BUILD_SUBDIR + os.sep + MAP_FILE_NAME cflags = C_FLAGS prompt = PROMPT + instance_text + ": " # Print out what we've been told to do text = "running static size check from ubxlib directory \"" + ubxlib_dir + "\"" if working_dir: text += ", working directory \"" + working_dir + "\"" printer.string("{}{}.".format(prompt, text)) reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_START, "NoFloat") # Switch to the working directory with u_utils.ChangeDir(working_dir): # Add the #defines to C_FLAGS if defines: for define in defines: cflags += " -D" + define # Assemble the call list call_list = ["python"] call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep + "static_size.py") call_list.append("-p") call_list.append(GNU_INSTALL_ROOT) call_list.append("-u") call_list.append(ubxlib_dir) call_list.append("-c") call_list.append(cflags) call_list.append("-l") call_list.append(LD_FLAGS) call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep + "source.txt") call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep + "include.txt") # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Set shell to keep Jenkins happy if u_utils.exe_run(call_list, 0, printer, prompt, shell_cmd=True, keep_going_flag=keep_going_flag): reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_COMPLETE) reporter.event(u_report.EVENT_TYPE_TEST, u_report.EVENT_START) # Having performed the build, open the .map file printer.string("{} opening map file {}...".format( prompt, MAP_FILE_NAME)) if os.path.exists(map_file_path): map_file = open(map_file_path, "r") if map_file: # Parse the cross-reference section to seek # if any of the functions that indicate the # floating point has been introduced turn up got_xref = False got_fp = False for line in map_file.read().splitlines(): if got_xref: for function in FLOAT_FUNCTIONS: if line.startswith(function): printer.string("{} found {} in map file which" \ " indicates floating point is" \ " in use: {}".format(prompt, \ function, line)) got_fp = True else: if line.startswith("Cross Reference Table"): got_xref = True if not got_xref: reporter.event( u_report.EVENT_TYPE_TEST, u_report.EVENT_FAILED, "map file has no cross-reference section") else: if got_fp: reporter.event( u_report.EVENT_TYPE_TEST, u_report.EVENT_FAILED, "floating point seems to be in use") else: return_value = 0 reporter.event(u_report.EVENT_TYPE_TEST, u_report.EVENT_COMPLETE) map_file.close() else: reporter.event(u_report.EVENT_TYPE_TEST, u_report.EVENT_FAILED, "unable to open map file") else: reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_FAILED, "check debug log for details") return return_value
def build_gcc(clean, build_subdir, ubxlib_dir, defines, printer, prompt, reporter): '''Build on GCC''' call_list = [] hex_file_path = None # The Nordic Makefile can only handle a # single sub-directory name which # must be off the directory that # Makefile is located in, so need to be # in the Makefile directory for building # to work directory = ubxlib_dir + os.sep + RUNNER_DIR_GCC printer.string("{}CD to {}.".format(prompt, directory)) # Set the Unity path before we change though unity_path = os.getcwd() + os.sep + u_utils.UNITY_SUBDIR with u_utils.ChangeDir(directory): # Clear the output folder if we're not just running if not clean or u_utils.deltree(build_subdir, printer, prompt): if defines: # Create the CFLAGS string cflags = "" for idx, define in enumerate(defines): if idx == 0: cflags = "-D" + define else: cflags += " -D" + define # Note: when entering things from the command-line # if there is more than one CFLAGS parameter then # they must be quoted but that is specifically # NOT required here as the fact that CFLAGS # is passed in as one array entry is sufficient # Assemble the whole call list call_list.append("make") call_list.append("NRF5_PATH=" + NRF5SDK_PATH) call_list.append("UNITY_PATH=" + unity_path.replace("\\", "/")) if defines: call_list.append("CFLAGS=" + cflags) call_list.append("OUTPUT_DIRECTORY=" + build_subdir) call_list.append("GNU_VERSION=" + GNU_VERSION) call_list.append("GNU_PREFIX=" + GNU_PREFIX) call_list.append("GNU_INSTALL_ROOT=" + GNU_INSTALL_ROOT) # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Call make to do the build # Set shell to keep Jenkins happy if u_utils.exe_run(call_list, BUILD_GUARD_TIME_SECONDS, printer, prompt, shell_cmd=True): hex_file_path = os.getcwd() + os.sep + build_subdir + \ os.sep + "nrf52840_xxaa.hex" else: reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED, "unable to clean build directory") return hex_file_path
def build(board, clean, ubxlib_dir, defines, env, printer, prompt, reporter): '''Build using west''' call_list = [] defines_text = "" runner_dir = ubxlib_dir + os.sep + RUNNER_DIR output_dir = os.getcwd() + os.sep + BUILD_SUBDIR custom_board_dir = ubxlib_dir + os.sep + CUSTOM_BOARD_DIR custom_board_root = ubxlib_dir + os.sep + CUSTOM_BOARD_ROOT build_dir = None # Put west at the front of the call list call_list.append("west") # Make it verbose call_list.append("-v") # Do a build call_list.append("build") # Pick up .overlay and .conf files automatically call_list.append("-p") call_list.append("auto") # Board name call_list.append("-b") call_list.append((board).replace("\\", "/")) # Under Zephyr we may need to override the Zephyr board files # Check if this board has such an override board_files = os.listdir(custom_board_dir) for board_file in board_files: if board == board_file: call_list.append(runner_dir) call_list.append("-DBOARD_ROOT=" + custom_board_root) break # Build products directory call_list.append("-d") call_list.append((BUILD_SUBDIR).replace("\\", "/")) if clean: # Clean call_list.append("-p") call_list.append("always") # Now the path to build call_list.append((runner_dir).replace("\\", "/")) # CCACHE is a pain in the bum: falls over on Windows # path length issues randomly and doesn't say where. # Since we're generally doing clean builds, disable it env["CCACHE_DISABLE"] = "1" if defines: # Set up the U_FLAGS environment variables for idx, define in enumerate(defines): if idx == 0: defines_text += "-D" + define else: defines_text += " -D" + define printer.string("{}setting environment variables U_FLAGS={}".format( prompt, defines_text)) env["U_FLAGS"] = defines_text # Clear the output folder ourselves as well, just # to be completely sure if not clean or u_utils.deltree(BUILD_SUBDIR, printer, prompt): # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Call west to do the build # Set shell to keep Jenkins happy if u_utils.exe_run(call_list, BUILD_GUARD_TIME_SECONDS, printer, prompt, shell_cmd=True, set_env=env): build_dir = output_dir else: reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_ERROR, "unable to clean build directory") return build_dir
def download_nrf53(connection, guard_time_seconds, build_dir, env, printer, prompt): '''Download the given hex file(s) on NRF53''' cpunet_hex_path = os.path.join(build_dir, "hci_rpmsg", "zephyr", "merged_CPUNET.hex") success = True nrfjprog_cmd = [NRFJPROG, "-f", "NRF53"] if connection and "debugger" in connection and connection["debugger"]: nrfjprog_cmd.extend(["-s", connection["debugger"]]) # Disable read protection first if os.path.exists(cpunet_hex_path): printer.string("{}---- recover NETCPU ----".format(prompt)) call_list = nrfjprog_cmd + ["--coprocessor", "CP_NETWORK", "--recover"] print_call_list(call_list, printer, prompt) success = u_utils.exe_run(call_list, guard_time_seconds, printer, prompt, shell_cmd=True, set_env=env) if success: # Give nrfjprog some time to relax sleep(1) printer.string("{}--- recover APP ----".format(prompt)) call_list = nrfjprog_cmd + [ "--coprocessor", "CP_APPLICATION", "--recover" ] print_call_list(call_list, printer, prompt) success = u_utils.exe_run(call_list, guard_time_seconds, printer, prompt, shell_cmd=True, set_env=env) if success and os.path.exists(cpunet_hex_path): # Now flash network core # Give nrfjprog some time to relax sleep(1) printer.string("{}---- download NETCPU ----".format(prompt)) call_list = nrfjprog_cmd + [ "--coprocessor", "CP_NETWORK", "--chiperase", "--program", cpunet_hex_path ] print_call_list(call_list, printer, prompt) success = u_utils.exe_run(call_list, guard_time_seconds, printer, prompt, shell_cmd=True, set_env=env) if success: # Give nrfjprog some time to relax sleep(1) app_hex_path = os.path.join(build_dir, "zephyr", "merged.hex") printer.string("{}---- download APP ----".format(prompt)) call_list = nrfjprog_cmd + [ "--coprocessor", "CP_APPLICATION", "--chiperase", "--program", app_hex_path ] print_call_list(call_list, printer, prompt) success = u_utils.exe_run(call_list, guard_time_seconds, printer, prompt, shell_cmd=True, set_env=env) return success
def run(instance, defines, ubxlib_dir, working_dir, printer, reporter, keep_going_flag=None): '''Build to check static sizes''' return_value = -1 instance_text = u_utils.get_instance_text(instance) cflags = C_FLAGS prompt = PROMPT + instance_text + ": " # Print out what we've been told to do text = "running static size check from ubxlib directory \"" + ubxlib_dir + "\"" if working_dir: text += ", working directory \"" + working_dir + "\"" printer.string("{}{}.".format(prompt, text)) reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_START, "StaticSize") # Switch to the working directory with u_utils.ChangeDir(working_dir): # Add the #defines to C_FLAGS if defines: for define in defines: cflags += " -D" + define # Assemble the call list call_list = ["python"] call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep + "static_size.py") call_list.append("-p") call_list.append(GNU_INSTALL_ROOT) call_list.append("-u") call_list.append(ubxlib_dir) call_list.append("-c") call_list.append(cflags) call_list.append("-l") call_list.append(LD_FLAGS) call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep + "source.txt") call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep + "include.txt") # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Set shell to keep Jenkins happy if u_utils.exe_run(call_list, 0, printer, prompt, shell_cmd=True, keep_going_flag=keep_going_flag): return_value = 0 reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_COMPLETE) else: reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_FAILED, "check debug log for details") return return_value
def build(esp_idf_dir, ubxlib_dir, build_dir, defines, env, clean, printer, prompt, reporter): '''Build the code''' call_list = [] defines_text = "" success = False # Make sure that the build directory exists and is # cleaned if required if os.path.exists(build_dir): if clean: u_utils.deltree(build_dir, printer, prompt) os.makedirs(build_dir) # Note: used to delete sdkconfig here to # force it to be regenerated from the # sdkconfig.defaults file however we can't # do that with parallel builds as the file # might be in use. Just need to be sure # that none of our builds fiddle with # it (which they shouldn't for consistency # anyway). else: os.makedirs(build_dir) # CCACHE is a pain in the bum: falls over on Windows # path length issues randomly and doesn't say where. # Since we're generally doing clean builds, disable it env["CCACHE_DISABLE"] = "1" if os.path.exists(build_dir): printer.string("{}building code...".format(prompt)) # Set up the U_FLAGS environment variables for idx, define in enumerate(defines): if idx == 0: defines_text += "-D" + define else: defines_text += " -D" + define printer.string("{}setting environment variables U_FLAGS={}". format(prompt, defines_text)) env["U_FLAGS"] = defines_text # Assemble the call list for the build process call_list.append("python") call_list.append(esp_idf_dir + os.sep + "tools\\idf.py") call_list.append("-C") call_list.append(ubxlib_dir + os.sep + \ "port\\platform\\esp-idf\\mcu\\esp32" + os.sep + PROJECT_SUBDIR) call_list.append("-B") call_list.append(build_dir) call_list.append("-D") call_list.append("TEST_COMPONENTS=" + TEST_COMPONENT) call_list.append("size") call_list.append("build") # Print what we're gonna do tmp = "" for item in call_list: tmp += " " + item printer.string("{}in directory {} calling{}". \ format(prompt, os.getcwd(), tmp)) # Do the build, # set shell to True to keep Jenkins happy success = u_utils.exe_run(call_list, BUILD_GUARD_TIME_SECONDS, printer, prompt, shell_cmd=True, set_env=env) else: reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED, "could not create directory \"" + build_dir + "\"") return success
def install(esp_idf_url, esp_idf_dir, esp_idf_branch, system_lock, printer, prompt, reporter): '''Install the Espressif tools and ESP-IDF''' returned_env = {} count = 0 # Acquire the install lock as this is a global operation if u_utils.install_lock_acquire(system_lock, printer, prompt): # Fetch the repo if u_utils.fetch_repo(esp_idf_url, esp_idf_dir, esp_idf_branch, printer, prompt): # Set up the environment variable IDF_TOOLS_PATH my_env = os.environ my_env["IDF_TOOLS_PATH"] = IDF_TOOLS_PATH printer.string("{}installing the Espressif tools to \"{}\" and" \ " ESP-IDF to \"{}\".". \ format(prompt, IDF_TOOLS_PATH, esp_idf_dir)) # Switch to where the stuff should have already # been fetched to with u_utils.ChangeDir(esp_idf_dir): if not u_utils.has_admin(): printer.string("{}NOTE: if install.bat fails (the return" \ " code may still be 0), then try re-running" \ " as administrator.".format(prompt)) # First call install.bat # set shell to True to keep Jenkins happy if u_utils.exe_run(["install.bat"], INSTALL_GUARD_TIME_SECONDS, printer, prompt, shell_cmd=True): # ...then export.bat to set up paths etc. # which we return attached to returned_env. # It is possible for the process of extracting # the environment variables to fail due to machine # loading (see comments against EXE_RUN_QUEUE_WAIT_SECONDS # in exe_run) so give this up to three chances to succeed while not returned_env and (count < 3): # set shell to True to keep Jenkins happy u_utils.exe_run(["export.bat"], INSTALL_GUARD_TIME_SECONDS, printer, prompt, shell_cmd=True, returned_env=returned_env) if not returned_env: printer.string("{}warning: retrying export.bat to" \ " capture the environment variables...". format(prompt)) count += 1 if not returned_env: reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED, "export.bat failed") else: reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED, "install.bat failed") else: reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED, "unable to fetch " + esp_idf_url) u_utils.install_lock_release(system_lock, printer, prompt) else: reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED, "could not acquire install lock") return returned_env