mirror of https://github.com/ARMmbed/mbed-os.git
Making memap output consistent across output formats
This commit fixes an issue where the output from memap.py was not consistent across all output formats. This issue stemmed from the fact that a few important calculations were being performed at output generation time. This has been moved to the 'parse' function and saved for future use by the 'generate' functions. Because this commit saves more data to the MemapParser instance, there were some name collisions. The public member 'mem_summary' has been renamed to 'mem_report'. 'mem_report' contains the data structure used by the json generator. This includes both the section data and the memory summary. The 'mem_summary' member now just contains the summary. The summary includes total allocated heap, total static RAM, etc.pull/2834/head
parent
b67e1f7564
commit
e8b06874a3
134
tools/memap.py
134
tools/memap.py
|
|
@ -51,9 +51,14 @@ class MemapParser(object):
|
|||
# list of all object files and mappting to module names
|
||||
self.object_to_module = dict()
|
||||
|
||||
# Memory usage summary structure
|
||||
# Memory report (sections + summary)
|
||||
self.mem_report = []
|
||||
|
||||
# Just the memory summary section
|
||||
self.mem_summary = dict()
|
||||
|
||||
self.subtotal = dict()
|
||||
|
||||
def module_add(self, module_name, size, section):
|
||||
""" Adds a module / section to the list
|
||||
|
||||
|
|
@ -399,68 +404,27 @@ class MemapParser(object):
|
|||
print "I/O error({0}): {1}".format(error.errno, error.strerror)
|
||||
return False
|
||||
|
||||
subtotal = dict()
|
||||
for k in self.sections:
|
||||
subtotal[k] = 0
|
||||
|
||||
# Calculate misc flash sections
|
||||
misc_flash_mem = 0
|
||||
for i in self.modules:
|
||||
for k in self.misc_flash_sections:
|
||||
if self.modules[i][k]:
|
||||
misc_flash_mem += self.modules[i][k]
|
||||
|
||||
json_obj = []
|
||||
for i in sorted(self.modules):
|
||||
|
||||
row = []
|
||||
|
||||
json_obj.append({
|
||||
"module":i,
|
||||
"size":{
|
||||
k:self.modules[i][k] for k in self.print_sections
|
||||
}
|
||||
})
|
||||
|
||||
summary = {
|
||||
'summary':{
|
||||
'static_ram': (subtotal['.data'] + subtotal['.bss']),
|
||||
'heap': (subtotal['.heap']),
|
||||
'stack': (subtotal['.stack']),
|
||||
'total_ram': (subtotal['.data'] + subtotal['.bss'] +
|
||||
subtotal['.heap']+subtotal['.stack']),
|
||||
'total_flash': (subtotal['.text'] + subtotal['.data'] +
|
||||
misc_flash_mem),
|
||||
}
|
||||
}
|
||||
|
||||
self.mem_summary = json_obj + [summary]
|
||||
|
||||
to_call = {'json': self.generate_json,
|
||||
'csv-ci': self.generate_csv,
|
||||
'table': self.generate_table}[export_format]
|
||||
to_call(subtotal, misc_flash_mem, file_desc)
|
||||
to_call(file_desc)
|
||||
|
||||
if file_desc is not sys.stdout:
|
||||
file_desc.close()
|
||||
|
||||
def generate_json(self, _, dummy, file_desc):
|
||||
def generate_json(self, file_desc):
|
||||
"""Generate a json file from a memory map
|
||||
|
||||
Positional arguments:
|
||||
subtotal - total sizes for each module
|
||||
misc_flash_mem - size of misc flash sections
|
||||
file_desc - the file to write out the final report to
|
||||
"""
|
||||
file_desc.write(json.dumps(self.mem_summary, indent=4))
|
||||
file_desc.write(json.dumps(self.mem_report, indent=4))
|
||||
file_desc.write('\n')
|
||||
|
||||
def generate_csv(self, subtotal, misc_flash_mem, file_desc):
|
||||
def generate_csv(self, file_desc):
|
||||
"""Generate a CSV file from a memoy map
|
||||
|
||||
Positional arguments:
|
||||
subtotal - total sizes for each module
|
||||
misc_flash_mem - size of misc flash sections
|
||||
file_desc - the file to write out the final report to
|
||||
"""
|
||||
csv_writer = csv.writer(file_desc, delimiter=',',
|
||||
|
|
@ -474,36 +438,33 @@ class MemapParser(object):
|
|||
csv_sizes += [self.modules[i][k]]
|
||||
|
||||
csv_module_section += ['static_ram']
|
||||
csv_sizes += [subtotal['.data']+subtotal['.bss']]
|
||||
csv_sizes += [self.mem_summary['static_ram']]
|
||||
|
||||
csv_module_section += ['heap']
|
||||
if subtotal['.heap'] == 0:
|
||||
if self.mem_summary['heap'] == 0:
|
||||
csv_sizes += ['unknown']
|
||||
else:
|
||||
csv_sizes += [subtotal['.heap']]
|
||||
csv_sizes += [self.mem_summary['heap']]
|
||||
|
||||
csv_module_section += ['stack']
|
||||
if subtotal['.stack'] == 0:
|
||||
if self.mem_summary['stack'] == 0:
|
||||
csv_sizes += ['unknown']
|
||||
else:
|
||||
csv_sizes += [subtotal['.stack']]
|
||||
csv_sizes += [self.mem_summary['stack']]
|
||||
|
||||
csv_module_section += ['total_ram']
|
||||
csv_sizes += [subtotal['.data'] + subtotal['.bss'] +
|
||||
subtotal['.heap'] + subtotal['.stack']]
|
||||
csv_sizes += [self.mem_summary['total_ram']]
|
||||
|
||||
csv_module_section += ['total_flash']
|
||||
csv_sizes += [subtotal['.text']+subtotal['.data']+misc_flash_mem]
|
||||
csv_sizes += [self.mem_summary['total_flash']]
|
||||
|
||||
csv_writer.writerow(csv_module_section)
|
||||
csv_writer.writerow(csv_sizes)
|
||||
|
||||
def generate_table(self, subtotal, misc_flash_mem, file_desc):
|
||||
def generate_table(self, file_desc):
|
||||
"""Generate a table from a memoy map
|
||||
|
||||
Positional arguments:
|
||||
subtotal - total sizes for each module
|
||||
misc_flash_mem - size of misc flash sections
|
||||
file_desc - the file to write out the final report to
|
||||
"""
|
||||
# Create table
|
||||
|
|
@ -521,9 +482,6 @@ class MemapParser(object):
|
|||
for i in sorted(self.modules):
|
||||
row = [i]
|
||||
|
||||
for k in self.sections:
|
||||
subtotal[k] += self.modules[i][k]
|
||||
|
||||
for k in self.print_sections:
|
||||
row.append(self.modules[i][k])
|
||||
|
||||
|
|
@ -531,34 +489,32 @@ class MemapParser(object):
|
|||
|
||||
subtotal_row = ['Subtotals']
|
||||
for k in self.print_sections:
|
||||
subtotal_row.append(subtotal[k])
|
||||
subtotal_row.append(self.subtotal[k])
|
||||
|
||||
table.add_row(subtotal_row)
|
||||
|
||||
file_desc.write(table.get_string())
|
||||
file_desc.write('\n')
|
||||
|
||||
if subtotal['.heap'] == 0:
|
||||
if self.mem_summary['heap'] == 0:
|
||||
file_desc.write("Allocated Heap: unknown\n")
|
||||
else:
|
||||
file_desc.write("Allocated Heap: %s bytes\n" %
|
||||
str(subtotal['.heap']))
|
||||
str(self.mem_summary['heap']))
|
||||
|
||||
if subtotal['.stack'] == 0:
|
||||
if self.mem_summary['stack'] == 0:
|
||||
file_desc.write("Allocated Stack: unknown\n")
|
||||
else:
|
||||
file_desc.write("Allocated Stack: %s bytes\n" %
|
||||
str(subtotal['.stack']))
|
||||
str(self.mem_summary['stack']))
|
||||
|
||||
file_desc.write("Total Static RAM memory (data + bss): %s bytes\n" %
|
||||
(str(subtotal['.data'] + subtotal['.bss'])))
|
||||
(str(self.mem_summary['static_ram'])))
|
||||
file_desc.write(
|
||||
"Total RAM memory (data + bss + heap + stack): %s bytes\n"
|
||||
% (str(subtotal['.data'] + subtotal['.bss'] + subtotal['.heap'] +
|
||||
subtotal['.stack'])))
|
||||
% (str(self.mem_summary['total_ram'])))
|
||||
file_desc.write("Total Flash memory (text + data + misc): %s bytes\n" %
|
||||
(str(subtotal['.text'] + subtotal['.data'] +
|
||||
misc_flash_mem)))
|
||||
(str(self.mem_summary['total_flash'])))
|
||||
|
||||
toolchains = ["ARM", "ARM_STD", "ARM_MICRO", "GCC_ARM", "IAR"]
|
||||
|
||||
|
|
@ -584,6 +540,44 @@ class MemapParser(object):
|
|||
self.parse_map_file_iar(file_input)
|
||||
else:
|
||||
result = False
|
||||
|
||||
for k in self.sections:
|
||||
self.subtotal[k] = 0
|
||||
|
||||
for i in sorted(self.modules):
|
||||
for k in self.sections:
|
||||
self.subtotal[k] += self.modules[i][k]
|
||||
|
||||
# Calculate misc flash sections
|
||||
self.misc_flash_mem = 0
|
||||
for i in self.modules:
|
||||
for k in self.misc_flash_sections:
|
||||
if self.modules[i][k]:
|
||||
self.misc_flash_mem += self.modules[i][k]
|
||||
|
||||
self.mem_summary = {
|
||||
'static_ram': (self.subtotal['.data'] + self.subtotal['.bss']),
|
||||
'heap': (self.subtotal['.heap']),
|
||||
'stack': (self.subtotal['.stack']),
|
||||
'total_ram': (self.subtotal['.data'] + self.subtotal['.bss'] +
|
||||
self.subtotal['.heap']+self.subtotal['.stack']),
|
||||
'total_flash': (self.subtotal['.text'] + self.subtotal['.data'] +
|
||||
self.misc_flash_mem),
|
||||
}
|
||||
|
||||
self.mem_report = []
|
||||
for i in sorted(self.modules):
|
||||
self.mem_report.append({
|
||||
"module":i,
|
||||
"size":{
|
||||
k:self.modules[i][k] for k in self.print_sections
|
||||
}
|
||||
})
|
||||
|
||||
self.mem_report.append({
|
||||
'summary': self.mem_summary
|
||||
})
|
||||
|
||||
except IOError as error:
|
||||
print "I/O error({0}): {1}".format(error.errno, error.strerror)
|
||||
result = False
|
||||
|
|
|
|||
|
|
@ -1047,7 +1047,7 @@ class mbedToolchain:
|
|||
# Here we return memory statistics structure (constructed after
|
||||
# call to generate_output) which contains raw data in bytes
|
||||
# about sections + summary
|
||||
return memap.mem_summary
|
||||
return memap.mem_report
|
||||
|
||||
# Set the configuration data
|
||||
def set_config_data(self, config_data):
|
||||
|
|
|
|||
Loading…
Reference in New Issue