mbed-os
Dependents: cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more
Diff: tools/export/sw4stm32/__init__.py
- Revision:
- 0:b74591d5ab33
diff -r 000000000000 -r b74591d5ab33 tools/export/sw4stm32/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/export/sw4stm32/__init__.py Mon Dec 11 17:54:04 2017 +0000 @@ -0,0 +1,536 @@ +""" +mbed SDK +Copyright (c) 2011-2017 ARM Limited + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +from os.path import splitext, basename, join +from tools.utils import mkdir +from tools.export.gnuarmeclipse import GNUARMEclipse +from tools.export.gnuarmeclipse import UID +from tools.build_api import prepare_toolchain +from sys import flags, platform + +# Global random number generator instance. +u = UID() + + +class Sw4STM32(GNUARMEclipse): + """ + Sw4STM32 class + """ + NAME = 'Sw4STM32' + TOOLCHAIN = 'GCC_ARM' + + BOARDS = { + 'B96B_F446VE': + { + 'name': 'B96B-F446VE', + 'mcuId': 'STM32F446VETx' + }, + 'DISCO_F051R8': + { + 'name': 'STM32F0DISCOVERY', + 'mcuId': 'STM32F051R8Tx' + }, + 'DISCO_F303VC': + { + 'name': 'STM32F3DISCOVERY', + 'mcuId': 'STM32F303VCTx' + }, + 'DISCO_F334C8': + { + 'name': 'STM32F3348DISCOVERY', + 'mcuId': 'STM32F334C8Tx' + }, + 'DISCO_F401VC': + { + 'name': 'STM32F401C-DISCO', + 'mcuId': 'STM32F401VCTx' + }, + 'DISCO_F407VG': + { + 'name': 'STM32F4DISCOVERY', + 'mcuId': 'STM32F407VGTx' + }, + 'DISCO_F413ZH': + { + 'name': 'DISCO_F413', + 'mcuId': 'STM32F413ZHTx' + }, + 'DISCO_F429ZI': + { + 'name': 'STM32F429I-DISCO', + 'mcuId': 'STM32F429ZITx' + }, + 'DISCO_F469NI': + { + 'name': 'DISCO-F469NI', + 'mcuId': 'STM32F469NIHx' + }, + 'DISCO_F746NG': + { + 'name': 'STM32F746G-DISCO', + 'mcuId': 'STM32F746NGHx' + }, + 'DISCO_F769NI': + { + 'name': 'DISCO-F769NI', + 'mcuId': 'STM32F769NIHx' + }, + 'DISCO_L053C8': + { + 'name': 'STM32L0538DISCOVERY', + 'mcuId': 'STM32L053C8Tx' + }, + 'DISCO_L072CZ_LRWAN1': + { + 'name': 'DISCO-L072CZ-LRWAN1', + 'mcuId': 'STM32L072CZTx' + }, + 'DISCO_L475VG_IOT01A': + { + 'name': 'STM32L475G-DISCO', + 'mcuId': 'STM32L475VGTx' + }, + 'DISCO_L476VG': + { + 'name': 'STM32L476G-DISCO', + 'mcuId': 'STM32L476VGTx' + }, + 'NUCLEO_F030R8': + { + 'name': 'NUCLEO-F030R8', + 'mcuId': 'STM32F030R8Tx' + }, + 'NUCLEO_F031K6': + { + 'name': 'NUCLEO-F031K6', + 'mcuId': 'STM32F031K6Tx' + }, + 'NUCLEO_F042K6': + { + 'name': 'NUCLEO-F042K6', + 'mcuId': 'STM32F042K6Tx' + }, + 'NUCLEO_F070RB': + { + 'name': 'NUCLEO-F070RB', + 'mcuId': 'STM32F070RBTx' + }, + 'NUCLEO_F072RB': + { + 'name': 'NUCLEO-F072RB', + 'mcuId': 'STM32F072RBTx' + }, + 'NUCLEO_F091RC': + { + 'name': 'NUCLEO-F091RC', + 'mcuId': 'STM32F091RCTx' + }, + 'NUCLEO_F103RB': + { + 'name': 'NUCLEO-F103RB', + 'mcuId': 'STM32F103RBTx' + }, + 'NUCLEO_F207ZG': + { + 'name': 'NUCLEO-F207ZG', + 'mcuId': 'STM32F207ZGTx' + }, + 'NUCLEO_F302R8': + { + 'name': 'NUCLEO-F302R8', + 'mcuId': 'STM32F302R8Tx' + }, + 'NUCLEO_F303K8': + { + 'name': 'NUCLEO-F303K8', + 'mcuId': 'STM32F303K8Tx' + }, + 'NUCLEO_F303RE': + { + 'name': 'NUCLEO-F303RE', + 'mcuId': 'STM32F303RETx' + }, + 'NUCLEO_F303ZE': + { + 'name': 'NUCLEO-F303ZE', + 'mcuId': 'STM32F303ZETx' + }, + 'NUCLEO_F334R8': + { + 'name': 'NUCLEO-F334R8', + 'mcuId': 'STM32F334R8Tx' + }, + 'NUCLEO_F401RE': + { + 'name': 'NUCLEO-F401RE', + 'mcuId': 'STM32F401RETx' + }, + 'NUCLEO_F410RB': + { + 'name': 'NUCLEO-F410RB', + 'mcuId': 'STM32F410RBTx' + }, + 'NUCLEO_F411RE': + { + 'name': 'NUCLEO-F411RE', + 'mcuId': 'STM32F411RETx' + }, + 'NUCLEO_F429ZI': + { + 'name': 'NUCLEO-F429ZI', + 'mcuId': 'STM32F429ZITx' + }, + 'NUCLEO_F446RE': + { + 'name': 'NUCLEO-F446RE', + 'mcuId': 'STM32F446RETx' + }, + 'NUCLEO_F446ZE': + { + 'name': 'NUCLEO-F446ZE', + 'mcuId': 'STM32F446ZETx' + }, + 'NUCLEO_F746ZG': + { + 'name': 'NUCLEO-F746ZG', + 'mcuId': 'STM32F746ZGTx' + }, + 'NUCLEO_F767ZI': + { + 'name': 'NUCLEO-F767ZI', + 'mcuId': 'STM32F767ZITx' + }, + 'NUCLEO_L011K4': + { + 'name': 'NUCLEO-L011K4', + 'mcuId': 'STM32L011K4Tx' + }, + 'NUCLEO_L031K6': + { + 'name': 'NUCLEO-L031K6', + 'mcuId': 'STM32L031K6Tx' + }, + 'NUCLEO_L053R8': + { + 'name': 'NUCLEO-L053R8', + 'mcuId': 'STM32L053R8Tx' + }, + 'NUCLEO_L073RZ': + { + 'name': 'NUCLEO-L073RZ', + 'mcuId': 'STM32L073RZTx' + }, + 'NUCLEO_L152RE': + { + 'name': 'NUCLEO-L152RE', + 'mcuId': 'STM32L152RETx' + }, + 'NUCLEO_L432KC': + { + 'name': 'NUCLEO-L432KC', + 'mcuId': 'STM32L432KCUx' + }, + 'NUCLEO_L476RG': + { + 'name': 'NUCLEO-L476RG', + 'mcuId': 'STM32L476RGTx' + }, + 'NUCLEO_L486RG': + { + 'name': 'NUCLEO-L486RG', + 'mcuId': 'STM32L486RGTx' + }, + 'NUCLEO_L496ZG': + { + 'name': 'NUCLEO-L496ZG', + 'mcuId': 'STM32L496ZGTx' + }, + 'NUCLEO_L496ZG_P': + { + 'name': 'NUCLEO-L496ZG', + 'mcuId': 'STM32L496ZGTx' + }, + } + + TARGETS = BOARDS.keys() + + def __gen_dir(self, dir_name): + """ + Method that creates directory + """ + settings = join(self.export_dir, dir_name) + mkdir(settings) + + def get_fpu_hardware(self, fpu_unit): + """ + Convert fpu unit name into hardware name. + """ + hw = '' + fpus = { + 'fpv4spd16': 'fpv4-sp-d16', + 'fpv5d16': 'fpv5-d16', + 'fpv5spd16': 'fpv5-sp-d16' + } + if fpu_unit in fpus: + hw = fpus[fpu_unit] + return hw + + def process_sw_options(self, opts, flags_in): + """ + Process System Workbench specific options. + + System Workbench for STM32 has some compile options, which are not recognized by the GNUARMEclipse exporter. + Those are handled in this method. + """ + opts['c']['preprocess'] = False + if '-E' in flags_in['c_flags']: + opts['c']['preprocess'] = True + opts['cpp']['preprocess'] = False + if '-E' in flags_in['cxx_flags']: + opts['cpp']['preprocess'] = True + opts['c']['slowflashdata'] = False + if '-mslow-flash-data' in flags_in['c_flags']: + opts['c']['slowflashdata'] = True + opts['cpp']['slowflashdata'] = False + if '-mslow-flash-data' in flags_in['cxx_flags']: + opts['cpp']['slowflashdata'] = True + if opts['common']['optimization.messagelength']: + opts['common']['optimization.other'] += ' -fmessage-length=0' + if opts['common']['optimization.signedchar']: + opts['common']['optimization.other'] += ' -fsigned-char' + if opts['common']['optimization.nocommon']: + opts['common']['optimization.other'] += ' -fno-common' + if opts['common']['optimization.noinlinefunctions']: + opts['common']['optimization.other'] += ' -fno-inline-functions' + if opts['common']['optimization.freestanding']: + opts['common']['optimization.other'] += ' -ffreestanding' + if opts['common']['optimization.nobuiltin']: + opts['common']['optimization.other'] += ' -fno-builtin' + if opts['common']['optimization.spconstant']: + opts['common']['optimization.other'] += ' -fsingle-precision-constant' + if opts['common']['optimization.nomoveloopinvariants']: + opts['common']['optimization.other'] += ' -fno-move-loop-invariants' + if opts['common']['warnings.unused']: + opts['common']['warnings.other'] += ' -Wunused' + if opts['common']['warnings.uninitialized']: + opts['common']['warnings.other'] += ' -Wuninitialized' + if opts['common']['warnings.missingdeclaration']: + opts['common']['warnings.other'] += ' -Wmissing-declarations' + if opts['common']['warnings.pointerarith']: + opts['common']['warnings.other'] += ' -Wpointer-arith' + if opts['common']['warnings.padded']: + opts['common']['warnings.other'] += ' -Wpadded' + if opts['common']['warnings.shadow']: + opts['common']['warnings.other'] += ' -Wshadow' + if opts['common']['warnings.logicalop']: + opts['common']['warnings.other'] += ' -Wlogical-op' + if opts['common']['warnings.agreggatereturn']: + opts['common']['warnings.other'] += ' -Waggregate-return' + if opts['common']['warnings.floatequal']: + opts['common']['warnings.other'] += ' -Wfloat-equal' + opts['ld']['strip'] = False + if '-s' in flags_in['ld_flags']: + opts['ld']['strip'] = True + opts['ld']['shared'] = False + if '-shared' in flags_in['ld_flags']: + opts['ld']['shared'] = True + opts['ld']['soname'] = '' + opts['ld']['implname'] = '' + opts['ld']['defname'] = '' + for item in flags_in['ld_flags']: + if item.startswith('-Wl,-soname='): + opts['ld']['soname'] = item[len('-Wl,-soname='):] + if item.startswith('-Wl,--out-implib='): + opts['ld']['implname'] = item[len('-Wl,--out-implib='):] + if item.startswith('-Wl,--output-def='): + opts['ld']['defname'] = item[len('-Wl,--output-def='):] + opts['common']['arm.target.fpu.hardware'] = self.get_fpu_hardware( + opts['common']['arm.target.fpu.unit']) + opts['common']['debugging.codecov'] = False + if '-fprofile-arcs' in flags_in['common_flags'] and '-ftest-coverage' in flags_in['common_flags']: + opts['common']['debugging.codecov'] = True + # Passing linker options to linker with '-Wl,'-prefix. + for index in range(len(opts['ld']['flags'])): + item = opts['ld']['flags'][index] + if not item.startswith('-Wl,'): + opts['ld']['flags'][index] = '-Wl,' + item + # Strange System Workbench feature: If first parameter in Other flags is a + # define (-D...), Other flags will be replaced by defines and other flags + # are completely ignored. Moving -D parameters to defines. + for compiler in ['c', 'cpp', 'as']: + tmpList = opts[compiler]['other'].split(' ') + otherList = [] + for item in tmpList: + if item.startswith('-D'): + opts[compiler]['defines'].append(str(item[2:])) + else: + otherList.append(item) + opts[compiler]['other'] = ' '.join(otherList) + # Assembler options + for as_def in opts['as']['defines']: + if '=' in as_def: + opts['as']['other'] += ' --defsym ' + as_def + else: + opts['as']['other'] += ' --defsym ' + as_def + '=1' + + def generate(self): + """ + Generate the .project and .cproject files. + """ + options = {} + + if not self.resources.linker_script: + raise NotSupportedException("No linker script found.") + + print ('\nCreate a System Workbench for STM32 managed project') + print ('Project name: {0}'.format(self.project_name)) + print ('Target: {0}'.format(self.toolchain.target.name)) + print ('Toolchain: {0}'.format(self.TOOLCHAIN) + '\n') + + self.resources.win_to_unix() + + config_header = self.filter_dot(self.toolchain.get_config_header()) + + libraries = [] + for lib in self.resources.libraries: + library, _ = splitext(basename(lib)) + libraries.append(library[3:]) + + self.system_libraries = [ + 'stdc++', 'supc++', 'm', 'c', 'gcc', 'nosys' + ] + + profiles = self.get_all_profiles() + self.as_defines = [s.replace('"', '"') + for s in self.toolchain.get_symbols(True)] + self.c_defines = [s.replace('"', '"') + for s in self.toolchain.get_symbols()] + self.cpp_defines = self.c_defines + print 'Symbols: {0}'.format(len(self.c_defines)) + + self.include_path = [] + for s in self.resources.inc_dirs: + self.include_path.append("../" + self.filter_dot(s)) + print ('Include folders: {0}'.format(len(self.include_path))) + + self.compute_exclusions() + + print ('Exclude folders: {0}'.format(len(self.excluded_folders))) + + ld_script = self.filter_dot(self.resources.linker_script) + print ('Linker script: {0}'.format(ld_script)) + + lib_dirs = [self.filter_dot(s) for s in self.resources.lib_dirs] + + preproc_cmd = basename(self.toolchain.preproc[0]) + " " + " ".join(self.toolchain.preproc[1:]) + + for id in ['debug', 'release']: + opts = {} + opts['common'] = {} + opts['as'] = {} + opts['c'] = {} + opts['cpp'] = {} + opts['ld'] = {} + + opts['id'] = id + opts['name'] = opts['id'].capitalize() + + # TODO: Add prints to log or console in verbose mode. + #print ('\nBuild configuration: {0}'.format(opts['name'])) + + profile = profiles[id] + + # A small hack, do not bother with src_path again, + # pass an empty string to avoid crashing. + src_paths = [''] + toolchain = prepare_toolchain( + src_paths, "", self.toolchain.target.name, self.TOOLCHAIN, build_profile=[profile]) + + # Hack to fill in build_dir + toolchain.build_dir = self.toolchain.build_dir + + flags = self.toolchain_flags(toolchain) + + # TODO: Add prints to log or console in verbose mode. + # print 'Common flags:', ' '.join(flags['common_flags']) + # print 'C++ flags:', ' '.join(flags['cxx_flags']) + # print 'C flags:', ' '.join(flags['c_flags']) + # print 'ASM flags:', ' '.join(flags['asm_flags']) + # print 'Linker flags:', ' '.join(flags['ld_flags']) + + # Most GNU ARM Eclipse options have a parent, + # either debug or release. + if '-O0' in flags['common_flags'] or '-Og' in flags['common_flags']: + opts['parent_id'] = 'debug' + else: + opts['parent_id'] = 'release' + + self.process_options(opts, flags) + + opts['c']['defines'] = self.c_defines + opts['cpp']['defines'] = self.cpp_defines + opts['as']['defines'] = self.as_defines + + self.process_sw_options(opts, flags) + + opts['ld']['library_paths'] = [ + self.filter_dot(s) for s in self.resources.lib_dirs] + + opts['ld']['user_libraries'] = libraries + opts['ld']['system_libraries'] = self.system_libraries + opts['ld']['script'] = "linker-script-" + id + ".ld" + + # Unique IDs used in multiple places. + uid = {} + uid['config'] = u.id + uid['tool_c_compiler'] = u.id + uid['tool_c_compiler_input'] = u.id + uid['tool_cpp_compiler'] = u.id + uid['tool_cpp_compiler_input'] = u.id + + opts['uid'] = uid + + options[id] = opts + + ctx = { + 'name': self.project_name, + 'platform': platform, + 'include_paths': self.include_path, + 'config_header': config_header, + 'exclude_paths': '|'.join(self.excluded_folders), + 'ld_script': ld_script, + 'library_paths': lib_dirs, + 'object_files': self.resources.objects, + 'libraries': libraries, + 'board_name': self.BOARDS[self.target.upper()]['name'], + 'mcu_name': self.BOARDS[self.target.upper()]['mcuId'], + 'cpp_cmd': preproc_cmd, + 'options': options, + # id property of 'u' will generate new random identifier every time + # when called. + 'u': u + } + + self.__gen_dir('.settings') + self.gen_file('sw4stm32/language_settings_commom.tmpl', + ctx, '.settings/language.settings.xml') + self.gen_file('sw4stm32/project_common.tmpl', ctx, '.project') + self.gen_file('sw4stm32/cproject_common.tmpl', ctx, '.cproject') + self.gen_file('sw4stm32/makefile.targets.tmpl', ctx, + 'makefile.targets', trim_blocks=True, lstrip_blocks=True) + self.gen_file('sw4stm32/launch.tmpl', ctx, self.project_name + + ' ' + options['debug']['name'] + '.launch')