Esempio n. 1
0
 def __init__(self, target):
     DeviceCMSIS.__init__(self, target)
     dev_format = "$$Device:{0}${1}"
     self.svd = ''
     if self.debug_svd:
         self.svd = dev_format.format(self.dname, self.debug_svd)
     self.debug_interface = self.uv_debug()
     self.flash_dll = self.generate_flash_dll()
Esempio n. 2
0
 def __init__(self, target):
     DeviceCMSIS.__init__(self, target)
     dev_format = "$$Device:{0}${1}"
     self.svd = ''
     if self.debug_svd:
         self.svd = dev_format.format(self.dname, self.debug_svd)
     self.reg_file = dev_format.format(self.dname, self.compile_header)
     self.debug_interface = self.uv_debug()
     self.flash_dll = self.generate_flash_dll()
Esempio n. 3
0
    def is_target_supported(cls, target_name):
        target = TARGET_MAP[target_name]
        if not target.is_TFM_target:
            if int(target.build_tools_metadata["version"]) > 0:
                if not len(
                        set(target.supported_toolchains).intersection(
                            set(["ARM", "ARMC6"]))) > 0:
                    return False
            else:
                if "ARMC6" not in target.supported_toolchains:
                    return False

            if not DeviceCMSIS.check_supported(target_name):
                return False
            if "Cortex-A" in target.core:
                return False
            if not hasattr(target, "post_binary_hook"):
                return True
            if target.post_binary_hook[
                    'function'] in cls.POST_BINARY_WHITELIST:
                return True
            else:
                return False
        else:
            return False
Esempio n. 4
0
    def is_target_supported(cls, target_name):
        target = TARGET_MAP[target_name]
        if not target.is_TFM_target:
            if int(target.build_tools_metadata["version"]) > 0:
                # Just check for ARMC5 as ARMC5 must be there irrespective of whether uARM is there or not if the target is staying with ARMC5
                if "ARMC5" not in target.supported_toolchains:
                    return False
            else:
                if not (set(target.supported_toolchains).intersection(
                        set(["ARM", "uARM"]))):
                    return False

            if not DeviceCMSIS.check_supported(target_name):
                return False
            if "Cortex-A" in target.core:
                return False
            if not hasattr(target, "post_binary_hook"):
                return True
            if target.post_binary_hook[
                    'function'] in cls.POST_BINARY_WHITELIST:
                return True
            else:
                return False
        else:
            return False
Esempio n. 5
0
    def generate(self):
        """Generate the .eww, .ewd, and .ewp files"""
        srcs = self.resources.headers + self.resources.s_sources + \
               self.resources.c_sources + self.resources.cpp_sources + \
               self.resources.objects + self.resources.libraries
        flags = self.flags
        c_flags = list(set(flags['common_flags']
                                    + flags['c_flags']
                                    + flags['cxx_flags']))
        # Flags set in template to be set by user in IDE
        template = ["--vla", "--no_static_destruction"]
        # Flag invalid if set in template
        # Optimizations are also set in template
        invalid_flag = lambda x: x in template or re.match("-O(\d|time|n)", x)
        flags['c_flags'] = [flag for flag in c_flags if not invalid_flag(flag)]

        try:
            debugger = DeviceCMSIS(self.target).debug.replace('-','').upper()
        except TargetNotSupportedException:
            debugger = "CMSISDAP"

        ctx = {
            'name': self.project_name,
            'groups': self.iar_groups(self.format_src(srcs)),
            'linker_script': self.format_file(self.resources.linker_script),
            'include_paths': [self.format_file(src) for src in self.resources.inc_dirs],
            'device': self.iar_device(),
            'ewp': sep+self.project_name + ".ewp",
            'debugger': debugger
        }
        ctx.update(flags)

        self.gen_file('iar/eww.tmpl', ctx, self.project_name + ".eww")
        self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd")
        self.gen_file('iar/ewp.tmpl', ctx, self.project_name + ".ewp")
Esempio n. 6
0
    def generate(self):
        """Generate the .eww, .ewd, and .ewp files"""
        srcs = self.resources.headers + self.resources.s_sources + \
               self.resources.c_sources + self.resources.cpp_sources + \
               self.resources.objects + self.resources.libraries
        flags = self.flags
        flags['c_flags'] = list(set(flags['common_flags']
                                    + flags['c_flags']
                                    + flags['cxx_flags']))
        if '--vla' in flags['c_flags']:
            flags['c_flags'].remove('--vla')
        if '--no_static_destruction' in flags['c_flags']:
            flags['c_flags'].remove('--no_static_destruction')
        #Optimizations
        if '-Oh' in flags['c_flags']:
            flags['c_flags'].remove('-Oh')
        ctx = {
            'name': self.project_name,
            'groups': self.iar_groups(self.format_src(srcs)),
            'linker_script': self.format_file(self.resources.linker_script),
            'include_paths': [self.format_file(src) for src in self.resources.inc_dirs],
            'device': self.iar_device(),
            'ewp': sep+self.project_name + ".ewp",
            'debugger': DeviceCMSIS(self.target).debug.replace('-','').upper()
        }
        ctx.update(flags)

        self.gen_file('iar/eww.tmpl', ctx, self.project_name+".eww")
        self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd")
        self.gen_file(self.get_ewp_template(), ctx, self.project_name + ".ewp")
Esempio n. 7
0
 def is_target_supported(cls, target_name):
     target = TARGET_MAP[target_name]
     if not (set(target.supported_toolchains).intersection(set(["ARMC6"]))):
         return False
     if not DeviceCMSIS.check_supported(target_name):
         return False
     if "Cortex-A" in target.core:
         return False
     if not hasattr(target, "post_binary_hook"):
         return True
     if target.post_binary_hook['function'] in cls.POST_BINARY_WHITELIST:
         return True
     else:
         return False
Esempio n. 8
0
 def is_target_supported(cls, target_name):
     target = TARGET_MAP[target_name]
     if not (set(target.supported_toolchains) and set(["ARM", "uARM"])):
         return False
     if not DeviceCMSIS.check_supported(target_name):
         return False
     if "Cortex-A" in target.core:
         return False
     if not hasattr(target, "post_binary_hook"):
         return True
     if target.post_binary_hook['function'] in cls.POST_BINARY_WHITELIST:
         return True
     else:
         return False
Esempio n. 9
0
class IAR(Exporter):
    NAME = 'iar'
    TOOLCHAIN = 'IAR'

    #iar_definitions.json location
    def_loc = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..',
                           '..', '..', 'tools', 'export', 'iar',
                           'iar_definitions.json')

    #create a dictionary of the definitions
    with open(def_loc, 'r') as f:
        IAR_DEFS = json.load(f)

    #supported targets have a device name and corresponding definition in
    #iar_definitions.json
    TARGETS = [
        target for target, obj in TARGET_MAP.iteritems()
        if hasattr(obj, 'device_name') and obj.device_name in IAR_DEFS.keys()
        and "IAR" in obj.supported_toolchains
        and DeviceCMSIS.check_supported(target)
    ]

    SPECIAL_TEMPLATES = {
        'rz_a1h': 'iar/iar_rz_a1h.ewp.tmpl',
        'nucleo_f746zg': 'iar/iar_nucleo_f746zg.ewp.tmpl'
    }

    def iar_groups(self, grouped_src):
        """Return a namedtuple of group info
        Positional Arguments:
        grouped_src: dictionary mapping a group(str) to sources
            within it (list of file names)
        Relevant part of IAR template
        {% for group in groups %}
	    <group>
	        <name>group.name</name>
	        {% for file in group.files %}
	        <file>
	        <name>$PROJ_DIR${{file}}</name>
	        </file>
	        {% endfor %}
	    </group>
	    {% endfor %}
        """
        IARgroup = namedtuple('IARgroup', ['name', 'files'])
        groups = []
        for name, files in grouped_src.items():
            groups.append(IARgroup(name, files))
        return groups

    def iar_device(self):
        """Retrieve info from iar_definitions.json"""
        device_name = TARGET_MAP[self.target].device_name
        device_info = self.IAR_DEFS[device_name]
        iar_defaults = {
            "OGChipSelectEditMenu": "",
            "CoreVariant": '',
            "GFPUCoreSlave": '',
            "GFPUCoreSlave2": 40,
            "GBECoreSlave": 35
        }

        iar_defaults.update(device_info)
        IARdevice = namedtuple('IARdevice', iar_defaults.keys())
        return IARdevice(**iar_defaults)

    def format_file(self, file):
        """Make IAR compatible path"""
        return join('$PROJ_DIR$', file)

    def format_src(self, srcs):
        """Group source files"""
        grouped = self.group_project_files(srcs)
        for group, files in grouped.items():
            grouped[group] = [self.format_file(src) for src in files]
        return grouped

    def get_ewp_template(self):
        return self.SPECIAL_TEMPLATES.get(self.target.lower(), 'iar/ewp.tmpl')

    def generate(self):
        """Generate the .eww, .ewd, and .ewp files"""
        srcs = self.resources.headers + self.resources.s_sources + \
               self.resources.c_sources + self.resources.cpp_sources + \
               self.resources.objects + self.resources.libraries
        flags = self.flags
        flags['c_flags'] = list(
            set(flags['common_flags'] + flags['c_flags'] + flags['cxx_flags']))
        if '--vla' in flags['c_flags']:
            flags['c_flags'].remove('--vla')
        if '--no_static_destruction' in flags['c_flags']:
            flags['c_flags'].remove('--no_static_destruction')
        #Optimizations
        if '-Oh' in flags['c_flags']:
            flags['c_flags'].remove('-Oh')
        ctx = {
            'name':
            self.project_name,
            'groups':
            self.iar_groups(self.format_src(srcs)),
            'linker_script':
            self.format_file(self.resources.linker_script),
            'include_paths':
            [self.format_file(src) for src in self.resources.inc_dirs],
            'device':
            self.iar_device(),
            'ewp':
            sep + self.project_name + ".ewp",
            'debugger':
            DeviceCMSIS(self.target).debug.replace('-', '').upper()
        }
        ctx.update(flags)

        self.gen_file('iar/eww.tmpl', ctx, self.project_name + ".eww")
        self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd")
        self.gen_file(self.get_ewp_template(), ctx, self.project_name + ".ewp")

    @staticmethod
    def build(project_name, log_name="build_log.txt", cleanup=True):
        """ Build IAR project """
        # > IarBuild [project_path] -build [project_name]
        proj_file = project_name + ".ewp"
        cmd = ["IarBuild", proj_file, '-build', project_name]

        # IAR does not support a '0' option to automatically use all
        # available CPUs, so we use Python's multiprocessing library
        # to detect the number of CPUs available
        cpus_available = cpu_count()
        jobs = cpus_available if cpus_available else None

        # Only add the parallel flag if we're using more than one CPU
        if jobs:
            cmd += ['-parallel', str(jobs)]

        # Build the project
        p = Popen(cmd, stdout=PIPE, stderr=PIPE)
        out, err = p.communicate()
        ret_code = p.returncode

        out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
        out_string += out
        out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n"
        out_string += err

        if ret_code == 0:
            out_string += "SUCCESS"
        else:
            out_string += "FAILURE"

        print out_string

        if log_name:
            # Write the output to the log file
            with open(log_name, 'w+') as f:
                f.write(out_string)

        # Cleanup the exported and built files
        if cleanup:
            os.remove(project_name + ".ewp")
            os.remove(project_name + ".ewd")
            os.remove(project_name + ".eww")
            # legacy output file location
            if exists('.build'):
                shutil.rmtree('.build')
            if exists('BUILD'):
                shutil.rmtree('BUILD')

        if ret_code != 0:
            # Seems like something went wrong.
            return -1
        else:
            return 0
Esempio n. 10
0
 def is_target_supported(cls, target_name):
     target = TARGET_MAP[target_name]
     return apply_supported_whitelist(
         cls.TOOLCHAIN, cls.POST_BINARY_WHITELIST, target) and\
         DeviceCMSIS.check_supported(target_name)
Esempio n. 11
0
class Uvision(Exporter):
    """Keil Uvision class

    This class encapsulates information to be contained in a Uvision
    project file (.uvprojx).
    The needed information can be viewed in uvision.tmpl
    """
    NAME = 'uvision5'
    TOOLCHAIN = 'ARM'

    POST_BINARY_WHITELIST = set([
        "MCU_NRF51Code.binary_hook",
        "TEENSY3_1Code.binary_hook",
        "LPCTargetCode.lpc_patch",
        "LPC4088Code.binary_hook",
        "MTSCode.combine_bins_mts_dot",
        "MTSCode.combine_bins_mts_dragonfly",
        "NCS36510TargetCode.ncs36510_addfib"
    ])
    TARGETS = [tgt for tgt in filter_supported("ARM", POST_BINARY_WHITELIST)
               if DeviceCMSIS.check_supported(tgt)]

    #File associations within .uvprojx file
    file_types = {'.cpp': 8, '.c': 1, '.s': 2,
                  '.obj': 3, '.o': 3, '.lib': 4,
                  '.ar': 4, '.h': 5, '.hpp': 5, '.sct': 4}

    def uv_files(self, files):
        """An generator containing Uvision specific information about project files
        Positional Arguments:
        files - the location of source files

        .uvprojx XML for project file:
        <File>
            <FileType>{{file.type}}</FileType>
            <FileName>{{file.name}}</FileName>
            <FilePath>{{file.loc}}</FilePath>
        </File>
        """
        for loc in files:
            #Encapsulates the information necessary for template entry above
            UVFile = namedtuple('UVFile', ['type','loc','name'])
            _, ext = os.path.splitext(loc)
            if ext.lower() in self.file_types:
                type = self.file_types[ext.lower()]
                name = ntpath.basename(normpath(loc))
                yield UVFile(type, loc, name)

    def format_flags(self):
        """Format toolchain flags for Uvision"""
        flags = copy.deepcopy(self.flags)
        # to be preprocessed with armcc
        asm_flag_string = '--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' + \
                          ",".join(flags['asm_flags'])
        flags['asm_flags'] = asm_flag_string
        # All non-asm flags are in one template field
        c_flags = list(set(flags['c_flags'] + flags['cxx_flags'] +flags['common_flags']))
        # These flags are in template to be set by user i n IDE
        template = ["--no_vla", "--cpp", "--c99"]
        # Flag is invalid if set in template
        # Optimizations are also set in the template
        invalid_flag = lambda x: x in template or re.match("-O(\d|time)", x) 
        flags['c_flags'] = [flag.replace('"','\\"') for flag in c_flags if not invalid_flag(flag)]
        flags['c_flags'] = " ".join(flags['c_flags'])
        return flags

    def format_src(self, srcs):
        """Make sources into the named tuple for use in the template"""
        grouped = self.group_project_files(srcs)
        for group, files in grouped.items():
            grouped[group] = sorted(list(self.uv_files(files)),
                                    key=lambda (_, __, name): name.lower())
        return grouped

    @staticmethod
    def format_fpu(core):
        """Generate a core's FPU string"""
        if core.endswith("FD"):
            return "FPU3(DFPU)"
        elif core.endswith("F"):
            return "FPU2"
        else:
            return ""

    def generate(self):
        """Generate the .uvproj file"""
        cache = Cache(True, False)
        if cache_d:
            cache.cache_descriptors()

        srcs = self.resources.headers + self.resources.s_sources + \
               self.resources.c_sources + self.resources.cpp_sources + \
               self.resources.objects + self.resources.libraries
        ctx = {
            'name': self.project_name,
            # project_files => dict of generators - file group to generator of
            # UVFile tuples defined above
            'project_files': sorted(list(self.format_src(srcs).iteritems()),
                                    key=lambda (group, _): group.lower()),
            'linker_script':self.resources.linker_script,
            'include_paths': '; '.join(self.resources.inc_dirs).encode('utf-8'),
            'device': DeviceUvision(self.target),
        }
        core = ctx['device'].core
        ctx['cputype'] = core.rstrip("FD")
        if core.endswith("FD"):
            ctx['fpu_setting'] = 3
        elif core.endswith("F"):
            ctx['fpu_setting'] = 2
        else:
            ctx['fpu_setting'] = 1
        ctx['fputype'] = self.format_fpu(core)
        ctx.update(self.format_flags())
        self.gen_file('uvision/uvision.tmpl', ctx, self.project_name+".uvprojx")
        self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx")

    @staticmethod
    def build(project_name, log_name='build_log.txt', cleanup=True):
        """ Build Uvision project """
        # > UV4 -r -j0 -o [log_name] [project_name].uvprojx
        proj_file = project_name + ".uvprojx"
        cmd = ['UV4', '-r', '-j0', '-o', log_name, proj_file]

        # Build the project
        p = Popen(cmd, stdout=PIPE, stderr=PIPE)
        out, err = p.communicate()
        ret_code = p.returncode

        # Print the log file to stdout
        with open(log_name, 'r') as f:
            print f.read()

        # Cleanup the exported and built files
        if cleanup:
            os.remove(log_name)
            os.remove(project_name+".uvprojx")
            os.remove(project_name+".uvoptx")
            # legacy .build directory cleaned if exists
            if exists('.build'):
                shutil.rmtree('.build')
            if exists('BUILD'):
                shutil.rmtree('BUILD')

        # Returns 0 upon success, 1 upon a warning, and neither upon an error
        if ret_code != 0 and ret_code != 1:
            # Seems like something went wrong.
            return -1
        else:
            return 0
Esempio n. 12
0
class Uvision(Exporter):
    """Keil Uvision class

    This class encapsulates information to be contained in a Uvision
    project file (.uvprojx).
    The needed information can be viewed in uvision.tmpl
    """
    NAME = 'uvision5'
    TOOLCHAIN = 'ARM'
    TARGETS = []
    for target, obj in TARGET_MAP.iteritems():
        if not ("ARM" in obj.supported_toolchains
                and hasattr(obj, "device_name")):
            continue
        if not DeviceCMSIS.check_supported(target):
            continue
        TARGETS.append(target)
    #File associations within .uvprojx file
    file_types = {
        '.cpp': 8,
        '.c': 1,
        '.s': 2,
        '.obj': 3,
        '.o': 3,
        '.lib': 4,
        '.ar': 4,
        '.h': 5,
        '.hpp': 5,
        '.sct': 4
    }

    def uv_file(self, loc):
        """Return a namedtuple of information about project file
        Positional Arguments:
        loc - the file's location

        .uvprojx XML for project file:
        <File>
            <FileType>{{file.type}}</FileType>
            <FileName>{{file.name}}</FileName>
            <FilePath>{{file.loc}}</FilePath>
        </File>
        """
        UVFile = namedtuple('UVFile', ['type', 'loc', 'name'])
        _, ext = os.path.splitext(loc)
        type = self.file_types[ext.lower()]
        name = ntpath.basename(normpath(loc))
        return UVFile(type, loc, name)

    def format_flags(self):
        """Format toolchain flags for Uvision"""
        flags = copy.deepcopy(self.flags)
        asm_flag_string = '--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' + \
                          ",".join(flags['asm_flags'])
        # asm flags only, common are not valid within uvision project,
        # they are armcc specific
        flags['asm_flags'] = asm_flag_string
        # cxx flags included, as uvision have them all in one tab
        flags['c_flags'] = list(
            set(['-D__ASSERT_MSG'] + flags['common_flags'] + flags['c_flags'] +
                flags['cxx_flags']))
        # not compatible with c99 flag set in the template
        try:
            flags['c_flags'].remove("--c99")
        except ValueError:
            pass
        # cpp is not required as it's implicit for cpp files
        try:
            flags['c_flags'].remove("--cpp")
        except ValueError:
            pass
        # we want no-vla for only cxx, but it's also applied for C in IDE,
        #  thus we remove it
        try:
            flags['c_flags'].remove("--no_vla")
        except ValueError:
            pass
        flags['c_flags'] = " ".join(flags['c_flags'])
        return flags

    def format_src(self, srcs):
        """Make sources into the named tuple for use in the template"""
        grouped = self.group_project_files(srcs)
        for group, files in grouped.items():
            grouped[group] = [self.uv_file(src) for src in files]
        return grouped

    def generate(self):
        """Generate the .uvproj file"""
        cache = Cache(True, False)
        if cache_d:
            cache.cache_descriptors()

        srcs = self.resources.headers + self.resources.s_sources + \
               self.resources.c_sources + self.resources.cpp_sources + \
               self.resources.objects + self.resources.libraries
        ctx = {
            'name': self.project_name,
            'project_files': self.format_src(srcs),
            'linker_script': self.resources.linker_script,
            'include_paths':
            '; '.join(self.resources.inc_dirs).encode('utf-8'),
            'device': DeviceUvision(self.target),
        }
        # Turn on FPU optimizations if the core has an FPU
        ctx['fpu_setting'] = 1 if 'f' not in ctx['device'].core.lower() \
                                  or 'd' in ctx['device'].core.lower() else 2
        ctx.update(self.format_flags())
        self.gen_file('uvision/uvision.tmpl', ctx,
                      self.project_name + ".uvprojx")
        self.gen_file('uvision/uvision_debug.tmpl', ctx,
                      self.project_name + ".uvoptx")

    @staticmethod
    def build(project_name, log_name='build_log.txt', cleanup=True):
        """ Build Uvision project """
        # > UV4 -r -j0 -o [log_name] [project_name].uvprojx
        proj_file = project_name + ".uvprojx"
        cmd = ['UV4', '-r', '-j0', '-o', log_name, proj_file]

        # Build the project
        p = Popen(cmd, stdout=PIPE, stderr=PIPE)
        out, err = p.communicate()
        ret_code = p.returncode

        # Print the log file to stdout
        with open(log_name, 'r') as f:
            print f.read()

        # Cleanup the exported and built files
        if cleanup:
            os.remove(log_name)
            os.remove(project_name + ".uvprojx")
            os.remove(project_name + ".uvoptx")
            # legacy .build directory cleaned if exists
            if exists('.build'):
                shutil.rmtree('.build')
            if exists('BUILD'):
                shutil.rmtree('BUILD')

        # Returns 0 upon success, 1 upon a warning, and neither upon an error
        if ret_code != 0 and ret_code != 1:
            # Seems like something went wrong.
            return -1
        else:
            return 0