Anders Blomdell / mbed-sdk-tools
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers __init__.py Source File

__init__.py

00001 """
00002 mbed SDK
00003 Copyright (c) 2011-2017 ARM Limited
00004 
00005 Licensed under the Apache License, Version 2.0 (the "License");
00006 you may not use this file except in compliance with the License.
00007 You may obtain a copy of the License at
00008 
00009 http://www.apache.org/licenses/LICENSE-2.0
00010 
00011 Unless required by applicable law or agreed to in writing, software
00012 distributed under the License is distributed on an "AS IS" BASIS,
00013 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014 See the License for the specific language governing permissions and
00015 limitations under the License.
00016 """
00017 from __future__ import print_function, absolute_import
00018 from builtins import str
00019 
00020 from os.path import splitext, basename, relpath, join
00021 import shutil
00022 from tools.utils import mkdir
00023 from tools.export.gnuarmeclipse import GNUARMEclipse
00024 from tools.export.gnuarmeclipse import UID
00025 from tools.build_api import prepare_toolchain
00026 from tools.targets import TARGET_MAP
00027 from sys import flags, platform
00028 
00029 # Global random number generator instance.
00030 u = UID()
00031 
00032 
00033 class Sw4STM32 (GNUARMEclipse):
00034     """
00035     Sw4STM32 class
00036     """
00037     NAME = 'Sw4STM32'
00038     TOOLCHAIN = 'GCC_ARM'
00039 
00040     BOARDS = {
00041         'B96B_F446VE':
00042         {
00043             'name': 'B96B-F446VE',
00044             'mcuId': 'STM32F446VETx'
00045         },
00046         'DISCO_F051R8':
00047         {
00048             'name': 'STM32F0DISCOVERY',
00049             'mcuId': 'STM32F051R8Tx'
00050         },
00051         'DISCO_F303VC':
00052         {
00053             'name': 'STM32F3DISCOVERY',
00054             'mcuId': 'STM32F303VCTx'
00055         },
00056         'DISCO_F334C8':
00057         {
00058             'name': 'STM32F3348DISCOVERY',
00059             'mcuId': 'STM32F334C8Tx'
00060         },
00061         'DISCO_F401VC':
00062         {
00063             'name': 'STM32F401C-DISCO',
00064             'mcuId': 'STM32F401VCTx'
00065         },
00066         'DISCO_F407VG':
00067         {
00068             'name': 'STM32F4DISCOVERY',
00069             'mcuId': 'STM32F407VGTx'
00070         },
00071         'DISCO_F413ZH':
00072         {
00073             'name': 'DISCO_F413',
00074             'mcuId': 'STM32F413ZHTx'
00075         },
00076         'DISCO_F429ZI':
00077         {
00078             'name': 'STM32F429I-DISCO',
00079             'mcuId': 'STM32F429ZITx'
00080         },
00081         'DISCO_F469NI':
00082         {
00083             'name': 'DISCO-F469NI',
00084             'mcuId': 'STM32F469NIHx'
00085         },
00086         'DISCO_F746NG':
00087         {
00088             'name': 'STM32F746G-DISCO',
00089             'mcuId': 'STM32F746NGHx'
00090         },
00091         'DISCO_F769NI':
00092         {
00093             'name': 'DISCO-F769NI',
00094             'mcuId': 'STM32F769NIHx'
00095         },
00096         'DISCO_L053C8':
00097         {
00098             'name': 'STM32L0538DISCOVERY',
00099             'mcuId': 'STM32L053C8Tx'
00100         },
00101         'DISCO_L072CZ_LRWAN1':
00102         {
00103             'name': 'DISCO-L072CZ-LRWAN1',
00104             'mcuId': 'STM32L072CZTx'
00105         },
00106         'MTB_MURATA_ABZ':
00107         {
00108             'name': 'MTB-MURATA-ABZ',
00109             'mcuId': 'STM32L0x2xZ'
00110         },
00111         'DISCO_L475VG_IOT01A':
00112         {
00113             'name': 'STM32L475G-DISCO',
00114             'mcuId': 'STM32L475VGTx'
00115         },
00116         'DISCO_L476VG':
00117         {
00118             'name': 'STM32L476G-DISCO',
00119             'mcuId': 'STM32L476VGTx'
00120         },
00121         'NUCLEO_F030R8':
00122         {
00123             'name': 'NUCLEO-F030R8',
00124             'mcuId': 'STM32F030R8Tx'
00125         },
00126         'NUCLEO_F031K6':
00127         {
00128             'name': 'NUCLEO-F031K6',
00129             'mcuId': 'STM32F031K6Tx'
00130         },
00131         'NUCLEO_F042K6':
00132         {
00133             'name': 'NUCLEO-F042K6',
00134             'mcuId': 'STM32F042K6Tx'
00135         },
00136         'NUCLEO_F070RB':
00137         {
00138             'name': 'NUCLEO-F070RB',
00139             'mcuId': 'STM32F070RBTx'
00140         },
00141         'NUCLEO_F072RB':
00142         {
00143             'name': 'NUCLEO-F072RB',
00144             'mcuId': 'STM32F072RBTx'
00145         },
00146         'NUCLEO_F091RC':
00147         {
00148             'name': 'NUCLEO-F091RC',
00149             'mcuId': 'STM32F091RCTx'
00150         },
00151         'NUCLEO_F103RB':
00152         {
00153             'name': 'NUCLEO-F103RB',
00154             'mcuId': 'STM32F103RBTx'
00155         },
00156         'NUCLEO_F207ZG':
00157         {
00158             'name': 'NUCLEO-F207ZG',
00159             'mcuId': 'STM32F207ZGTx'
00160         },
00161         'NUCLEO_F302R8':
00162         {
00163             'name': 'NUCLEO-F302R8',
00164             'mcuId': 'STM32F302R8Tx'
00165         },
00166         'NUCLEO_F303K8':
00167         {
00168             'name': 'NUCLEO-F303K8',
00169             'mcuId': 'STM32F303K8Tx'
00170         },
00171         'NUCLEO_F303RE':
00172         {
00173             'name': 'NUCLEO-F303RE',
00174             'mcuId': 'STM32F303RETx'
00175         },
00176         'NUCLEO_F303ZE':
00177         {
00178             'name': 'NUCLEO-F303ZE',
00179             'mcuId': 'STM32F303ZETx'
00180         },
00181         'NUCLEO_F334R8':
00182         {
00183             'name': 'NUCLEO-F334R8',
00184             'mcuId': 'STM32F334R8Tx'
00185         },
00186         'NUCLEO_F401RE':
00187         {
00188             'name': 'NUCLEO-F401RE',
00189             'mcuId': 'STM32F401RETx'
00190         },
00191         'NUCLEO_F410RB':
00192         {
00193             'name': 'NUCLEO-F410RB',
00194             'mcuId': 'STM32F410RBTx'
00195         },
00196         'NUCLEO_F411RE':
00197         {
00198             'name': 'NUCLEO-F411RE',
00199             'mcuId': 'STM32F411RETx'
00200         },
00201         'NUCLEO_F413ZH':
00202         {
00203             'name': 'NUCLEO-F413ZH',
00204             'mcuId': 'STM32F413ZHTx'
00205         },
00206         'NUCLEO_F429ZI':
00207         {
00208             'name': 'NUCLEO-F429ZI',
00209             'mcuId': 'STM32F429ZITx'
00210         },
00211         'NUCLEO_F446RE':
00212         {
00213             'name': 'NUCLEO-F446RE',
00214             'mcuId': 'STM32F446RETx'
00215         },
00216         'NUCLEO_F446ZE':
00217         {
00218             'name': 'NUCLEO-F446ZE',
00219             'mcuId': 'STM32F446ZETx'
00220         },
00221         'NUCLEO_F746ZG':
00222         {
00223             'name': 'NUCLEO-F746ZG',
00224             'mcuId': 'STM32F746ZGTx'
00225         },
00226         'NUCLEO_F767ZI':
00227         {
00228             'name': 'NUCLEO-F767ZI',
00229             'mcuId': 'STM32F767ZITx'
00230         },
00231         'NUCLEO_L011K4':
00232         {
00233             'name': 'NUCLEO-L011K4',
00234             'mcuId': 'STM32L011K4Tx'
00235         },
00236         'NUCLEO_L031K6':
00237         {
00238             'name': 'NUCLEO-L031K6',
00239             'mcuId': 'STM32L031K6Tx'
00240         },
00241         'NUCLEO_L053R8':
00242         {
00243             'name': 'NUCLEO-L053R8',
00244             'mcuId': 'STM32L053R8Tx'
00245         },
00246         'NUCLEO_L073RZ':
00247         {
00248             'name': 'NUCLEO-L073RZ',
00249             'mcuId': 'STM32L073RZTx'
00250         },
00251         'MTB_RAK811':
00252         {
00253             'name': 'MTB-RAK-811',
00254             'mcuId': 'STM32L151CBUxA'
00255         },
00256         'NUCLEO_L152RE':
00257         {
00258             'name': 'NUCLEO-L152RE',
00259             'mcuId': 'STM32L152RETx'
00260         },
00261         'NUCLEO_L432KC':
00262         {
00263             'name': 'NUCLEO-L432KC',
00264             'mcuId': 'STM32L432KCUx'
00265         },
00266         'MTB_ADV_WISE_1510':
00267         {
00268             'name': 'MTB-ADV-WISE-1510',
00269             'mcuId': 'STM32L443xC'
00270         },
00271         'NUCLEO_L476RG':
00272         {
00273             'name': 'NUCLEO-L476RG',
00274             'mcuId': 'STM32L476RGTx'
00275         },
00276         'NUCLEO_L486RG':
00277         {
00278             'name': 'NUCLEO-L486RG',
00279             'mcuId': 'STM32L486RGTx'
00280         },
00281         'NUCLEO_L496ZG':
00282         {
00283             'name': 'NUCLEO-L496ZG',
00284             'mcuId': 'STM32L496ZGTx'
00285         },
00286         'NUCLEO_L496ZG_P':
00287         {
00288             'name': 'NUCLEO-L496ZG',
00289             'mcuId': 'STM32L496ZGTx'
00290         },
00291     }
00292 
00293     @classmethod
00294     def is_target_supported(cls, target_name):
00295         target = TARGET_MAP[target_name]
00296         target_supported = bool(set(target.resolution_order_names)
00297                                 .intersection(set(cls.BOARDS.keys())))
00298         toolchain_supported = cls.TOOLCHAIN in target.supported_toolchains
00299         return target_supported and toolchain_supported
00300 
00301     def __gen_dir(self, dir_name):
00302         """
00303         Method that creates directory
00304         """
00305         settings = join(self.export_dir, dir_name)
00306         mkdir(settings)
00307 
00308     def get_fpu_hardware (self, fpu_unit):
00309         """
00310         Convert fpu unit name into hardware name.
00311         """
00312         hw = ''
00313         fpus = {
00314             'fpv4spd16': 'fpv4-sp-d16',
00315             'fpv5d16': 'fpv5-d16',
00316             'fpv5spd16': 'fpv5-sp-d16'
00317         }
00318         if fpu_unit in fpus:
00319             hw = fpus[fpu_unit]
00320         return hw
00321 
00322     def process_sw_options (self, opts, flags_in):
00323         """
00324         Process System Workbench specific options.
00325 
00326         System Workbench for STM32 has some compile options, which are not recognized by the GNUARMEclipse exporter.
00327         Those are handled in this method.
00328         """
00329         opts['c']['preprocess'] = False
00330         if '-E' in flags_in['c_flags']:
00331             opts['c']['preprocess'] = True
00332         opts['cpp']['preprocess'] = False
00333         if '-E' in flags_in['cxx_flags']:
00334             opts['cpp']['preprocess'] = True
00335         opts['c']['slowflashdata'] = False
00336         if '-mslow-flash-data' in flags_in['c_flags']:
00337             opts['c']['slowflashdata'] = True
00338         opts['cpp']['slowflashdata'] = False
00339         if '-mslow-flash-data' in flags_in['cxx_flags']:
00340             opts['cpp']['slowflashdata'] = True
00341         if opts['common']['optimization.messagelength']:
00342             opts['common']['optimization.other'] += ' -fmessage-length=0'
00343         if opts['common']['optimization.signedchar']:
00344             opts['common']['optimization.other'] += ' -fsigned-char'
00345         if opts['common']['optimization.nocommon']:
00346             opts['common']['optimization.other'] += ' -fno-common'
00347         if opts['common']['optimization.noinlinefunctions']:
00348             opts['common']['optimization.other'] += ' -fno-inline-functions'
00349         if opts['common']['optimization.freestanding']:
00350             opts['common']['optimization.other'] += ' -ffreestanding'
00351         if opts['common']['optimization.nobuiltin']:
00352             opts['common']['optimization.other'] += ' -fno-builtin'
00353         if opts['common']['optimization.spconstant']:
00354             opts['common']['optimization.other'] += ' -fsingle-precision-constant'
00355         if opts['common']['optimization.nomoveloopinvariants']:
00356             opts['common']['optimization.other'] += ' -fno-move-loop-invariants'
00357         if opts['common']['warnings.unused']:
00358             opts['common']['warnings.other'] += ' -Wunused'
00359         if opts['common']['warnings.uninitialized']:
00360             opts['common']['warnings.other'] += ' -Wuninitialized'
00361         if opts['common']['warnings.missingdeclaration']:
00362             opts['common']['warnings.other'] += ' -Wmissing-declarations'
00363         if opts['common']['warnings.pointerarith']:
00364             opts['common']['warnings.other'] += ' -Wpointer-arith'
00365         if opts['common']['warnings.padded']:
00366             opts['common']['warnings.other'] += ' -Wpadded'
00367         if opts['common']['warnings.shadow']:
00368             opts['common']['warnings.other'] += ' -Wshadow'
00369         if opts['common']['warnings.logicalop']:
00370             opts['common']['warnings.other'] += ' -Wlogical-op'
00371         if opts['common']['warnings.agreggatereturn']:
00372             opts['common']['warnings.other'] += ' -Waggregate-return'
00373         if opts['common']['warnings.floatequal']:
00374             opts['common']['warnings.other'] += ' -Wfloat-equal'
00375         opts['ld']['strip'] = False
00376         if '-s' in flags_in['ld_flags']:
00377             opts['ld']['strip'] = True
00378         opts['ld']['shared'] = False
00379         if '-shared' in flags_in['ld_flags']:
00380             opts['ld']['shared'] = True
00381         opts['ld']['soname'] = ''
00382         opts['ld']['implname'] = ''
00383         opts['ld']['defname'] = ''
00384         for item in flags_in['ld_flags']:
00385             if item.startswith('-Wl,-soname='):
00386                 opts['ld']['soname'] = item[len('-Wl,-soname='):]
00387             if item.startswith('-Wl,--out-implib='):
00388                 opts['ld']['implname'] = item[len('-Wl,--out-implib='):]
00389             if item.startswith('-Wl,--output-def='):
00390                 opts['ld']['defname'] = item[len('-Wl,--output-def='):]
00391         opts['common']['arm.target.fpu.hardware'] = self.get_fpu_hardware (
00392             opts['common']['arm.target.fpu.unit'])
00393         opts['common']['debugging.codecov'] = False
00394         if '-fprofile-arcs' in flags_in['common_flags'] and '-ftest-coverage' in flags_in['common_flags']:
00395             opts['common']['debugging.codecov'] = True
00396         # Passing linker options to linker with '-Wl,'-prefix.
00397         for index in range(len(opts['ld']['flags'])):
00398             item = opts['ld']['flags'][index]
00399             if not item.startswith('-Wl,'):
00400                 opts['ld']['flags'][index] = '-Wl,' + item
00401         # Strange System Workbench feature: If first parameter in Other flags is a
00402         # define (-D...), Other flags will be replaced by defines and other flags
00403         # are completely ignored. Moving -D parameters to defines.
00404         for compiler in ['c', 'cpp', 'as']:
00405             tmpList = opts[compiler]['other'].split(' ')
00406             otherList = []
00407             for item in tmpList:
00408                 if item.startswith('-D'):
00409                     opts[compiler]['defines'].append(str(item[2:]))
00410                 else:
00411                     otherList.append(item)
00412             opts[compiler]['other'] = ' '.join(otherList)
00413         # Assembler options
00414         for as_def in opts['as']['defines']:
00415             if '=' in as_def:
00416                 opts['as']['other'] += ' --defsym ' + as_def
00417             else:
00418                 opts['as']['other'] += ' --defsym ' + as_def + '=1'
00419 
00420     def generate (self):
00421         """
00422         Generate the .project and .cproject files.
00423         """
00424         options = {}
00425 
00426         if not self.resources.linker_script:
00427             raise NotSupportedException("No linker script found.")
00428 
00429         print('\nCreate a System Workbench for STM32 managed project')
00430         print('Project name: {0}'.format(self.project_name))
00431         print('Target:       {0}'.format(self.toolchain.target.name))
00432         print('Toolchain:    {0}'.format(self.TOOLCHAIN ) + '\n')
00433 
00434         self.resources.win_to_unix()
00435 
00436         libraries = []
00437         for lib in self.libraries:
00438             library, _ = splitext(basename(lib))
00439             libraries.append(library[3:])
00440 
00441         self.system_libraries  = [
00442             'stdc++', 'supc++', 'm', 'c', 'gcc', 'nosys'
00443         ]
00444 
00445         profiles = self.get_all_profiles()
00446         self.as_defines  = [s.replace('"', '"')
00447                            for s in self.toolchain.get_symbols(True)]
00448         self.c_defines  = [s.replace('"', '"')
00449                           for s in self.toolchain.get_symbols()]
00450         self.cpp_defines  = self.c_defines 
00451 
00452         self.include_path  = []
00453         for s in self.resources.inc_dirs:
00454             self.include_path .append("../" + self.filter_dot(s))
00455         print('Include folders: {0}'.format(len(self.include_path )))
00456 
00457         self.compute_exclusions()
00458 
00459         print('Exclude folders: {0}'.format(len(self.excluded_folders)))
00460 
00461         ld_script = self.filter_dot(self.resources.linker_script)
00462         print('Linker script:   {0}'.format(ld_script))
00463 
00464         lib_dirs = [self.filter_dot(s) for s in self.resources.lib_dirs]
00465 
00466         preproc_cmd = basename(self.toolchain.preproc[0]) + " " + " ".join(self.toolchain.preproc[1:])
00467 
00468         for id in ['debug', 'release']:
00469             opts = {}
00470             opts['common'] = {}
00471             opts['as'] = {}
00472             opts['c'] = {}
00473             opts['cpp'] = {}
00474             opts['ld'] = {}
00475 
00476             opts['id'] = id
00477             opts['name'] = opts['id'].capitalize()
00478 
00479             profile = profiles[id]
00480 
00481             # A small hack, do not bother with src_path again,
00482             # pass an empty string to avoid crashing.
00483             src_paths = ['']
00484             toolchain = prepare_toolchain(
00485                 src_paths, "", self.toolchain.target.name, self.TOOLCHAIN , build_profile=[profile])
00486 
00487             # Hack to fill in build_dir
00488             toolchain.build_dir = self.toolchain.build_dir
00489 
00490             flags = self.toolchain_flags(toolchain)
00491 
00492             # Most GNU ARM Eclipse options have a parent,
00493             # either debug or release.
00494             if '-O0' in flags['common_flags'] or '-Og' in flags['common_flags']:
00495                 opts['parent_id'] = 'debug'
00496             else:
00497                 opts['parent_id'] = 'release'
00498 
00499             self.process_options(opts, flags)
00500 
00501             opts['c']['defines'] = self.c_defines 
00502             opts['cpp']['defines'] = self.cpp_defines 
00503             opts['as']['defines'] = self.as_defines 
00504 
00505             self.process_sw_options (opts, flags)
00506 
00507             opts['ld']['library_paths'] = [
00508                 self.filter_dot(s) for s in self.resources.lib_dirs]
00509 
00510             opts['ld']['user_libraries'] = libraries
00511             opts['ld']['system_libraries'] = self.system_libraries 
00512             opts['ld']['script'] = "linker-script-" + id + ".ld"
00513 
00514             # Unique IDs used in multiple places.
00515             uid = {}
00516             uid['config'] = u.id
00517             uid['tool_c_compiler'] = u.id
00518             uid['tool_c_compiler_input'] = u.id
00519             uid['tool_cpp_compiler'] = u.id
00520             uid['tool_cpp_compiler_input'] = u.id
00521 
00522             opts['uid'] = uid
00523 
00524             options[id] = opts
00525 
00526         ctx = {
00527             'name': self.project_name,
00528             'platform': platform,
00529             'include_paths': self.include_path ,
00530             'config_header': self.config_header_ref.name,
00531             'exclude_paths': '|'.join(self.excluded_folders),
00532             'ld_script': ld_script,
00533             'library_paths': lib_dirs,
00534             'object_files': self.resources.objects,
00535             'libraries': libraries,
00536             'board_name': self.BOARDS [self.target.upper()]['name'],
00537             'mcu_name': self.BOARDS [self.target.upper()]['mcuId'],
00538             'cpp_cmd': preproc_cmd,
00539             'options': options,
00540             # id property of 'u' will generate new random identifier every time
00541             # when called.
00542             'u': u
00543         }
00544 
00545         self.__gen_dir ('.settings')
00546         self.gen_file('sw4stm32/language_settings_commom.tmpl',
00547                       ctx, '.settings/language.settings.xml')
00548         self.gen_file('sw4stm32/project_common.tmpl', ctx, '.project')
00549         self.gen_file('sw4stm32/cproject_common.tmpl', ctx, '.cproject')
00550         self.gen_file('sw4stm32/makefile.targets.tmpl', ctx,
00551                       'makefile.targets', trim_blocks=True, lstrip_blocks=True)
00552         self.gen_file('sw4stm32/launch.tmpl', ctx, self.project_name +
00553                       ' ' + options['debug']['name'] + '.launch')
00554 
00555     @staticmethod
00556     def clean(_):
00557         shutil.rmtree(".settings")