Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/board/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ if GetDepend(['BSP_USE_MULTICORE']):
LINKFLAGS += ' --predefine="-D__use_shmem__=1"'
LINKFLAGS += ' --predefine="-D__multicore__=1"'
if rtconfig.PLATFORM in ['iccarm']:
LINKFLAGS += ' __use_shmem__=1'
LINKFLAGS += ' __multicore__=1'
LINKFLAGS += ' --config_def __use_shmem__=1'
LINKFLAGS += ' --config_def __multicore__=1'

if GetDepend(['BSP_USING_ETH']):
CPPDEFINES += ['SDK_NETC_USED=1', 'FSL_ETH_ENABLE_CACHE_CONTROL=1']
Expand Down
30 changes: 25 additions & 5 deletions bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/rtconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
'FLEXSPI_NOR_HYPERRAM': 'MIMXRT1189xxxxx_cm33_flexspi_nor_hyperram',
}[_LINKER_SCRIPT_TYPE]


if PLATFORM == 'gcc':
PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc'
Expand Down Expand Up @@ -229,25 +228,31 @@
EXEC_PATH = EXEC_PATH + '/arm/bin/'
POST_ACTION = 'ielftool --bin $TARGET rtthread.bin'

# Map from linker script type to the matching Keil target name.
_LINKER_SCRIPT_TO_KEIL_TARGET = {
# Map from linker script type to the matching Keil target / IAR configuration name.
# Keil targets and IAR configurations share the same names, so one table serves both.
_LINKER_SCRIPT_TO_PROJECT_TARGET = {
'RAM': 'rtthread_ram',
'FLEXSPI_NOR': 'rtthread_flexspi_nor',
'FLEXSPI_NOR_HYPERRAM': 'rtthread_flexspi_nor_hyperram',
}

def _get_active_project_target():
"""Return the Keil target / IAR config name matching the selected linker script."""
return _LINKER_SCRIPT_TO_PROJECT_TARGET.get(_LINKER_SCRIPT_TYPE, 'rtthread_ram')

def update_keil_active_target(uvoptx_path='project.uvoptx'):
"""Set <IsCurrentTarget> in project.uvoptx to match the selected linker script."""
import xml.etree.ElementTree as etree

active = _LINKER_SCRIPT_TO_KEIL_TARGET.get(_LINKER_SCRIPT_TYPE, 'rtthread_ram')
active = _get_active_project_target()

if not os.path.exists(uvoptx_path):
return
return active

tree = etree.parse(uvoptx_path)
root = tree.getroot()


for tgt in tree.findall('Target'):
tname = tgt.find('TargetName')
is_current = tgt.find('TargetOption/OPTFL/IsCurrentTarget')
Expand All @@ -261,7 +266,22 @@ def update_keil_active_target(uvoptx_path='project.uvoptx'):

print('Keil active target set to: ' + active)

# Return the active target name so the caller (tools/targets/keil.py) can
# build the matching target with UV4.exe instead of the template's first one.
return active

def iar_get_active_config():

"""Return the IAR configuration name matching the selected linker script.

This hook is called by tools/targets/iar.py when generating the IAR
project so that the active configuration follows the Kconfig linker
script selection. It is board-specific and only defined here.
"""
return _get_active_project_target()

def dist_handle(BSP_ROOT, dist_dir):

import sys
cwd_path = os.getcwd()
# sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools'))
Expand Down
4 changes: 2 additions & 2 deletions bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/board/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ if GetDepend(['BSP_USE_MULTICORE']):
LINKFLAGS += ' --predefine="-D__use_shmem__=1"'
LINKFLAGS += ' --predefine="-D__multicore__=1"'
if rtconfig.PLATFORM in ['iccarm']:
LINKFLAGS += ' __use_shmem__=1'
LINKFLAGS += ' __multicore__=1'
LINKFLAGS += ' --config_def __use_shmem__=1'
LINKFLAGS += ' --config_def __multicore__=1'

if GetDepend(['BSP_USING_ETH']):
CPPDEFINES += ['SDK_NETC_USED=1', 'FSL_ETH_ENABLE_CACHE_CONTROL=1']
Expand Down
27 changes: 23 additions & 4 deletions bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/rtconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,22 +242,27 @@
EXEC_PATH = EXEC_PATH + '/arm/bin/'
POST_ACTION = 'ielftool --bin $TARGET rtthread.bin'

# Map from linker script type to the matching Keil target name.
_LINKER_SCRIPT_TO_KEIL_TARGET = {
# Map from linker script type to the matching Keil target / IAR configuration name.
# Keil targets and IAR configurations share the same names, so one table serves both.
_LINKER_SCRIPT_TO_PROJECT_TARGET = {
'RAM': 'rtthread_ram',
'HYPERRAM': 'rtthread_hyperram',
'FLEXSPI_NOR': 'rtthread_flexspi_nor',
'FLEXSPI_NOR_HYPERRAM': 'rtthread_flexspi_nor_hyperram',
}

def _get_active_project_target():
"""Return the Keil target / IAR config name matching the selected linker script."""
return _LINKER_SCRIPT_TO_PROJECT_TARGET.get(_LINKER_SCRIPT_TYPE, 'rtthread_ram')

def update_keil_active_target(uvoptx_path='project.uvoptx'):
"""Set <IsCurrentTarget> in project.uvoptx to match the selected linker script."""
import xml.etree.ElementTree as etree

active = _LINKER_SCRIPT_TO_KEIL_TARGET.get(_LINKER_SCRIPT_TYPE, 'rtthread_ram')
active = _get_active_project_target()

if not os.path.exists(uvoptx_path):
return
return active

tree = etree.parse(uvoptx_path)
root = tree.getroot()
Expand All @@ -275,6 +280,20 @@ def update_keil_active_target(uvoptx_path='project.uvoptx'):

print('Keil active target set to: ' + active)

# Return the active target name so the caller (tools/targets/keil.py) can
# build the matching target with UV4.exe instead of the template's first one.
return active


def iar_get_active_config():
"""Return the IAR configuration name matching the selected linker script.

This hook is called by tools/targets/iar.py when generating the IAR
project so that the active configuration follows the Kconfig linker
script selection. It is board-specific and only defined here.
"""
return _get_active_project_target()

def dist_handle(BSP_ROOT, dist_dir):
import sys
cwd_path = os.getcwd()
Expand Down
149 changes: 137 additions & 12 deletions tools/targets/iar.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#

import os
import re
import sys
import string
import utils
Expand All @@ -40,14 +41,15 @@

<workspace>
<project>
<path>$WS_DIR$\%s</path>
</project>
<path>$WS_DIR$\%(project)s</path>
</project>%(active_config)s
<batchBuild/>
</workspace>


'''


def IARAddGroup(parent, name, files, project_path):
group = SubElement(parent, 'group')
group_name = SubElement(group, 'name')
Expand All @@ -69,11 +71,69 @@ def IARAddGroup(parent, name, files, project_path):
else:
file_name.text = '$PROJ_DIR$\\' + path # ('$PROJ_DIR$\\' + path).decode(fs_encoding)

def IARWorkspace(target):
# make an workspace
def _update_iar_wsdt(wsdt_path, project_name, active_config):
"""Update <CurrentConfigs><Project> in the IAR session file to set the active configuration."""
config_str = '%s/%s' % (project_name, active_config)

if not os.path.exists(wsdt_path):
os.makedirs(os.path.dirname(wsdt_path), exist_ok=True)
tree = etree.ElementTree(etree.Element('Workspace'))
else:
tree = etree.parse(wsdt_path)

root = tree.getroot()
cfg_dict = root.find('ConfigDictionary')
if cfg_dict is None:
cfg_dict = SubElement(root, 'ConfigDictionary')
cur_cfgs = cfg_dict.find('CurrentConfigs')
if cur_cfgs is None:
cur_cfgs = SubElement(cfg_dict, 'CurrentConfigs')
proj_elem = cur_cfgs.find('Project')
if proj_elem is None:
proj_elem = SubElement(cur_cfgs, 'Project')
proj_elem.text = config_str
tree.write(wsdt_path, encoding='utf-8', xml_declaration=True)

def _split_iar_linkflags(linkflags):
tokens = re.findall(r'(?:[^\s"]+|"[^"]*")+', linkflags)
if re.sub(r'\s+', '', ''.join(tokens)) != re.sub(r'\s+', '', linkflags):
raise ValueError('Invalid quoting in IAR linker flags: %s' % linkflags)

defines = []
extra = []
index = 0
while index < len(tokens):
token = tokens[index]
if token == '--config_def':
index += 1
if index == len(tokens):
raise ValueError('Missing value for --config_def')
define = tokens[index]
elif token.startswith('--config_def='):
define = token[len('--config_def='):]
else:
extra.append(token)
index += 1
continue

if define.startswith('"') and define.endswith('"'):
define = define[1:-1]
if not re.fullmatch(r'[A-Za-z_][A-Za-z0-9_]*=.+', define):
raise ValueError('Invalid IAR configuration definition: %s' % define)
defines.append(define)
index += 1

return defines, ' '.join(extra)

def IARWorkspace(target, active_config=None):
# make an workspace, optionally setting the active configuration
workspace = target.replace('.ewp', '.eww')
project_name = os.path.splitext(os.path.basename(target))[0]
active_elem = ''
if active_config:
active_elem = '\n <activeConfig>\n <name>%s/%s</name>\n </activeConfig>' % (project_name, active_config)
out = open(workspace, 'w')
xml = iar_workspace % target
xml = iar_workspace % {'project': target, 'active_config': active_elem}
out.write(xml)
out.close()

Expand All @@ -83,10 +143,9 @@ def IARProject(env, target, script):
tree = etree.parse('template.ewp')
root = tree.getroot()

out = open(target, 'w')

CPPPATH = []
CPPDEFINES = env.get('CPPDEFINES', [])

LOCAL_CPPDEFINES = []
LINKFLAGS = ''
CFLAGS = ''
Expand Down Expand Up @@ -118,7 +177,7 @@ def searchLib(group):

# get each group's link flags
if 'LINKFLAGS' in group and group['LINKFLAGS']:
LINKFLAGS += group['LINKFLAGS']
LINKFLAGS += ' ' + group['LINKFLAGS']

if 'LIBS' in group and group['LIBS']:
for item in group['LIBS']:
Expand All @@ -137,6 +196,16 @@ def searchLib(group):
paths[inc] = None # 使用 dict 去重并保持插入顺序
paths = list(paths.keys())

config_defines, extra_linkflags = _split_iar_linkflags(LINKFLAGS)

if config_defines or extra_linkflags:
for config in tree.findall('configuration'):
names = [option.findtext('name') for option in config.findall('settings/data/option')]
if config_defines and 'IlinkConfigDefines' not in names:
raise ValueError('IAR configuration has no IlinkConfigDefines option')
if extra_linkflags and ('IlinkUseExtraOptions' not in names or 'IlinkExtraOptions' not in names):
raise ValueError('IAR configuration has no linker extra options')

# setting options
options = tree.findall('configuration/settings/data/option')
for option in options:
Expand All @@ -160,6 +229,23 @@ def searchLib(group):
state = SubElement(option, 'state')
state.text = define

if name.text == 'IlinkConfigDefines':
for define in config_defines:
state = SubElement(option, 'state')
state.text = define

if name.text == 'IlinkUseExtraOptions' and extra_linkflags:
state = option.find('state')
if state is None:
state = SubElement(option, 'state')
state.text = '1'

if name.text == 'IlinkExtraOptions' and extra_linkflags:
state = option.find('state')
if state is None:
state = SubElement(option, 'state')
state.text = ' '.join(filter(None, [state.text, extra_linkflags]))

if name.text == 'IlinkAdditionalLibs':
for path in Libs:
state = SubElement(option, 'state')
Expand All @@ -170,10 +256,49 @@ def searchLib(group):
state.text = path

xml_indent(root)
out.write(etree.tostring(root, encoding='utf-8').decode())
out.close()

IARWorkspace(target)
with open(target, 'w') as out:
out.write(etree.tostring(root, encoding='utf-8').decode())

# Determine the active configuration from the BSP via an optional board-specific hook.
active_config = None
try:
import rtconfig
if hasattr(rtconfig, 'iar_get_active_config'):
active_config = rtconfig.iar_get_active_config()
except Exception as e:
print('Warning: could not get IAR active config: %s' % e)

IARWorkspace(target, active_config)

# update settings/project.wsdt to set the active configuration
if active_config:
wsdt_path = os.path.join('settings', os.path.splitext(os.path.basename(target))[0] + '.wsdt')

project_name = os.path.splitext(os.path.basename(target))[0]
_update_iar_wsdt(wsdt_path, project_name, active_config)

# The IAR IDE keeps the workspace/session state in memory and writes it
# back on close, which can overwrite the active configuration we just
# generated. Remind the user to close the workspace before regenerating.
print('IAR active configuration set to: %s' % active_config)
print('Note: if the IAR workspace (.eww) is currently open, close it '
'before regenerating the project, otherwise the active target '
'will not be updated.')

# copy template.ewd (debugger settings) and template.ewt (build settings) to project files.
# The template sources are always template.ewd / template.ewt in the project directory;
# do not derive them from the output project name, otherwise a custom --project-name
# would make source and destination identical and trigger shutil.SameFileError.
import shutil
ewd_template = os.path.join(project_path, 'template.ewd')
ewd_target = target.replace('.ewp', '.ewd')
if os.path.exists(ewd_template) and os.path.abspath(ewd_template) != os.path.abspath(ewd_target):
shutil.copy2(ewd_template, ewd_target)

ewt_template = os.path.join(project_path, 'template.ewt')
ewt_target = target.replace('.ewp', '.ewt')
if os.path.exists(ewt_template) and os.path.abspath(ewt_template) != os.path.abspath(ewt_target):
shutil.copy2(ewt_template, ewt_target)

def IARPath():
import rtconfig
Expand Down
Loading
Loading