Skip to content

[tools] Making memap output consistent across output formats #2834

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 30, 2016
Merged
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
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ script:
- PYTHONPATH=. python tools/test/config_test/config_test.py
- python tools/test/pylint.py
- py.test tools/test/toolchains/api.py
- python tools/test/memap/memap_test.py
- python tools/build_travis.py
before_install:
- sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded
Expand Down
137 changes: 67 additions & 70 deletions tools/memap.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,14 @@ def __init__(self):
# 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

Expand Down Expand Up @@ -399,68 +404,27 @@ def generate_output(self, export_format, file_output=None):
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=',',
Expand All @@ -474,36 +438,33 @@ def generate_csv(self, subtotal, misc_flash_mem, file_desc):
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
Expand All @@ -521,47 +482,80 @@ def generate_table(self, subtotal, misc_flash_mem, file_desc):
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])

table.add_row(row)

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"]

def compute_report(self):
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
})

def parse(self, mapfile, toolchain):
""" Parse and decode map file depending on the toolchain

Expand All @@ -584,6 +578,9 @@ def parse(self, mapfile, toolchain):
self.parse_map_file_iar(file_input)
else:
result = False

self.compute_report()

except IOError as error:
print "I/O error({0}): {1}".format(error.errno, error.strerror)
result = False
Expand Down
Loading