mirror of https://github.com/ARMmbed/mbed-os.git
562 lines
18 KiB
Python
562 lines
18 KiB
Python
"""
|
|
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 __future__ import print_function, absolute_import
|
|
from builtins import str
|
|
|
|
from os.path import splitext, basename, relpath, join
|
|
import shutil
|
|
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 tools.targets import TARGET_MAP
|
|
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'
|
|
},
|
|
'MTB_MURATA_ABZ':
|
|
{
|
|
'name': 'MTB-MURATA-ABZ',
|
|
'mcuId': 'STM32L0x2xZ'
|
|
},
|
|
'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_F413ZH':
|
|
{
|
|
'name': 'NUCLEO-F413ZH',
|
|
'mcuId': 'STM32F413ZHTx'
|
|
},
|
|
'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'
|
|
},
|
|
'MTB_RAK811':
|
|
{
|
|
'name': 'MTB-RAK-811',
|
|
'mcuId': 'STM32L151CBUxA'
|
|
},
|
|
'NUCLEO_L152RE':
|
|
{
|
|
'name': 'NUCLEO-L152RE',
|
|
'mcuId': 'STM32L152RETx'
|
|
},
|
|
'NUCLEO_L432KC':
|
|
{
|
|
'name': 'NUCLEO-L432KC',
|
|
'mcuId': 'STM32L432KCUx'
|
|
},
|
|
'MTB_ADV_WISE_1510':
|
|
{
|
|
'name': 'MTB-ADV-WISE-1510',
|
|
'mcuId': 'STM32L443xC'
|
|
},
|
|
'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'
|
|
},
|
|
}
|
|
|
|
@classmethod
|
|
def is_target_supported(cls, target_name):
|
|
target = TARGET_MAP[target_name]
|
|
target_supported = bool(set(target.resolution_order_names)
|
|
.intersection(set(cls.BOARDS.keys())))
|
|
toolchain_supported = cls.TOOLCHAIN in target.supported_toolchains
|
|
return target_supported and toolchain_supported
|
|
|
|
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.toolchain.get_config_header()
|
|
if config_header:
|
|
config_header = relpath(config_header, self.resources.file_basepath[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
|
|
|
|
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()
|
|
|
|
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)
|
|
|
|
# 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')
|
|
|
|
@staticmethod
|
|
def clean(_):
|
|
shutil.rmtree(".settings")
|