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
Brian Daniels 2016-09-27 16:51:16 -05:00
parent b67e1f7564
commit e8b06874a3
2 changed files with 65 additions and 71 deletions

View File

@ -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

View File

@ -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):