169 lines
4.6 KiB
Python
169 lines
4.6 KiB
Python
from string import Template
|
|
import re
|
|
|
|
required_sections = ['ROMEM', 'RWMEM', 'STACK']
|
|
|
|
|
|
def fix_startup_file(config, filename):
|
|
|
|
# Get the stack size from the config file. Note that the startup file
|
|
# measures in words, not bytes.
|
|
stack_size = config['STACK']['size'] // 4
|
|
|
|
# Read in every line of the given file
|
|
input_lines = None
|
|
with open(filename) as f:
|
|
input_lines = [line for line in f]
|
|
|
|
# Perform a search-and-replace with the new stack size.
|
|
def fix_line(line):
|
|
return re.sub(r'(pui32Stack\[)([x0-9a-fA-F]*)',
|
|
r'\g<1>' + str(stack_size),
|
|
line)
|
|
|
|
output_lines = map(fix_line, input_lines)
|
|
output_text = ''.join(output_lines)
|
|
|
|
# Write the new file back to the input
|
|
with open(filename, 'w') as f:
|
|
f.write(output_text)
|
|
|
|
|
|
def generate_link_script(config):
|
|
robase = config['ROMEM']['start']
|
|
roend = robase + config['ROMEM']['size']
|
|
rwbase = config['RWMEM']['start']
|
|
rwend = rwbase + config['RWMEM']['size']
|
|
tcmbase = config['TCM']['start']
|
|
tcmend = tcmbase + config['TCM']['size']
|
|
stackbase = config['STACK']['start']
|
|
stackend = stackbase + config['STACK']['size']
|
|
|
|
D = dict()
|
|
D['robase'] = format_hex(robase)
|
|
D['roend'] = format_hex(roend)
|
|
D['rwbase'] = format_hex(rwbase)
|
|
D['rwend'] = format_hex(rwend)
|
|
D['tcmbase'] = format_hex(tcmbase)
|
|
D['tcmend'] = format_hex(tcmend)
|
|
|
|
D['stackbase'] = format_hex(stackbase)
|
|
D['stackend'] = format_hex(stackend)
|
|
|
|
D['stack_size'] = config['STACK']['size']
|
|
|
|
#D['section_defs'] = format_sections(section_definition, config)
|
|
#D['section_blocks'] = format_sections(section_block, config)
|
|
#D['section_placements'] = format_sections(section_placement, config)
|
|
|
|
return link_script_template.substitute(**D)
|
|
|
|
|
|
def format_sections(template, config):
|
|
|
|
def fill_section_template(section):
|
|
mapping = {
|
|
'section_name': section,
|
|
'block_name': section + '_BLOCK',
|
|
'mem_name': section + '_MEM',
|
|
'align': 4,
|
|
'start': format_hex(config[section]['start']),
|
|
'size': format_hex(config[section]['size']),
|
|
'end': format_hex(config[section]['start'] +
|
|
config[section]['size']),
|
|
|
|
'permissions': convert_permissions(config[section]['perm']),
|
|
}
|
|
|
|
return template.substitute(**mapping)
|
|
|
|
def is_extra_section(section):
|
|
return section not in required_sections
|
|
|
|
sections = filter(is_extra_section, config)
|
|
|
|
return ''.join(map(fill_section_template, sections))
|
|
|
|
|
|
def convert_permissions(perm_string):
|
|
if 'r' in perm_string and 'w' in perm_string and 'x' in perm_string:
|
|
return 'readwrite'
|
|
else:
|
|
return 'readonly'
|
|
|
|
|
|
def format_hex(n):
|
|
return '0x{:08X}'.format(n)
|
|
|
|
|
|
link_script_template = Template('''\
|
|
//*****************************************************************************
|
|
//
|
|
// linker_script.icf
|
|
//
|
|
// IAR linker Configuration File
|
|
//
|
|
//*****************************************************************************
|
|
|
|
//
|
|
// Define a memory section that covers the entire 4 GB addressable space of the
|
|
// processor. (32-bit can address up to 4GB)
|
|
//
|
|
define memory mem with size = 4G;
|
|
|
|
//
|
|
// Define regions for the various types of internal memory.
|
|
//
|
|
define region ROMEM = mem:[from ${robase} to ${roend}];
|
|
define region RWMEM = mem:[from ${rwbase} to ${rwend}];
|
|
define region TCM = mem:[from ${tcmbase} to ${tcmend}];
|
|
define region STACKMEM = mem:[from ${stackbase} to ${stackend}];
|
|
|
|
//
|
|
// Define blocks for logical groups of data.
|
|
//
|
|
define block HEAP with alignment = 0x8, size = 0x00000000 { };
|
|
define block CSTACK with alignment = 0x8, size = ${stack_size}
|
|
{
|
|
section .stack
|
|
};
|
|
|
|
define block ROSTART with fixed order
|
|
{
|
|
readonly section .intvec,
|
|
readonly section .patch
|
|
};
|
|
|
|
//
|
|
// Set section properties.
|
|
//
|
|
initialize by copy { readwrite };
|
|
initialize by copy { section RWMEM };
|
|
do not initialize { section .noinit };
|
|
do not initialize { section .stack };
|
|
|
|
//
|
|
// Place code sections in memory regions.
|
|
//
|
|
place at start of ROMEM { block ROSTART };
|
|
place in ROMEM { readonly };
|
|
place at start of STACKMEM { block CSTACK};
|
|
place in RWMEM { block HEAP, readwrite, section .noinit };
|
|
place in TCM { section .tcm };
|
|
''')
|
|
|
|
section_definition = Template('''\
|
|
define region ${mem_name} = mem:[from ${start} to ${end}];
|
|
''')
|
|
|
|
section_block = Template('''\
|
|
define block ${block_name} with alignment = ${align}, size = ${size}
|
|
{
|
|
${permissions} section ${section_name}
|
|
};
|
|
''')
|
|
|
|
section_placement = Template('''\
|
|
place in ${mem_name} { block ${block_name} };
|
|
''')
|