Esempio n. 1
0
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)
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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
Esempio n. 5
0
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)
Esempio n. 6
0
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)
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 9
0
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)
Esempio n. 10
0
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
Esempio n. 11
0
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
Esempio n. 12
0
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
Esempio n. 13
0
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
Esempio n. 14
0
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
Esempio n. 15
0
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
Esempio n. 16
0
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
Esempio n. 17
0
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
Esempio n. 18
0
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
Esempio n. 19
0
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