Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: memap.py
- Revision:
- 22:9e85236d8716
- Parent:
- 13:ab47a20b66f0
- Child:
- 24:25bff2709c20
diff -r 4fdf0dd04f6f -r 9e85236d8716 memap.py
--- a/memap.py Fri Jul 15 22:58:15 2016 +0100
+++ b/memap.py Sat Jul 16 00:34:03 2016 +0100
@@ -10,6 +10,7 @@
import csv
import json
import argparse
+from utils import argparse_uppercase_type, argparse_lowercase_hyphen_type, argparse_filestring_type
from prettytable import PrettyTable
debug = False
@@ -26,9 +27,9 @@
self.misc_flash_sections = ('.interrupts', '.flash_config')
- self.other_sections = ('.interrupts_ram', '.init', '.ARM.extab', \
- '.ARM.exidx', '.ARM.attributes', '.eh_frame', \
- '.init_array', '.fini_array', '.jcr', '.stab', \
+ self.other_sections = ('.interrupts_ram', '.init', '.ARM.extab',
+ '.ARM.exidx', '.ARM.attributes', '.eh_frame',
+ '.init_array', '.fini_array', '.jcr', '.stab',
'.stabstr', '.ARM.exidx', '.ARM')
# sections to print info (generic for all toolchains)
@@ -43,6 +44,9 @@
# list of all object files and mappting to module names
self.object_to_module = dict()
+ # Memory usage summary structure
+ self.mem_summary = dict()
+
def module_add(self, module_name, size, section):
"""
Adds a module / section to the list
@@ -67,7 +71,7 @@
return i # should name of the section (assuming it's a known one)
if line.startswith('.'):
- return 'unknown' # all others are clasified are unknown
+ return 'unknown' # all others are classified are unknown
else:
return False # everything else, means no change in section
@@ -336,6 +340,8 @@
else:
self.object_to_module.update({object_name:module_name})
+ export_formats = ["json", "csv-ci", "table"]
+
def generate_output(self, export_format, file_output=None):
"""
Generates summary of memory map data
@@ -363,11 +369,12 @@
# Create table
columns = ['Module']
- for i in list(self.print_sections):
- columns.append(i)
+ columns.extend(self.print_sections)
table = PrettyTable(columns)
table.align["Module"] = "l"
+ for col in self.print_sections:
+ table.align[col] = 'r'
for i in list(self.print_sections):
table.align[i] = 'r'
@@ -388,8 +395,12 @@
for k in self.print_sections:
row.append(self.modules[i][k])
- json_obj.append({"module":i, "size":{\
- k:self.modules[i][k] for k in self.print_sections}})
+ json_obj.append({
+ "module":i,
+ "size":{
+ k:self.modules[i][k] for k in self.print_sections
+ }
+ })
table.add_row(row)
@@ -399,16 +410,19 @@
table.add_row(subtotal_row)
+ 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),
+ }
+ }
+
if export_format == 'json':
- json_obj.append({\
- 'summary':{\
- 'total_static_ram':(subtotal['.data']+subtotal['.bss']),\
- 'allocated_heap':(subtotal['.heap']),\
- 'allocated_stack':(subtotal['.stack']),\
- 'total_ram':(subtotal['.data']+subtotal['.bss']+subtotal['.heap']+subtotal['.stack']),\
- 'total_flash':(subtotal['.text']+subtotal['.data']+misc_flash_mem),}})
-
- file_desc.write(json.dumps(json_obj, indent=4))
+ json_to_file = json_obj + [summary]
+ file_desc.write(json.dumps(json_to_file, indent=4))
file_desc.write('\n')
elif export_format == 'csv-ci': # CSV format for the CI system
@@ -467,33 +481,40 @@
if file_desc is not sys.stdout:
file_desc.close()
+ self.mem_summary = json_obj + [summary]
+
return True
+ def get_memory_summary(self):
+ """! Object is available only after self.generate_output('json') is called
+ @return Return memory summary object
+ """
+ return self.mem_summary
+
+ toolchains = ["ARM", "ARM_STD", "ARM_MICRO", "GCC_ARM", "IAR"]
+
def parse(self, mapfile, toolchain):
"""
Parse and decode map file depending on the toolchain
"""
+ result = True
try:
- file_input = open(mapfile, 'rt')
+ with open(mapfile, 'rt') as file_input:
+ if toolchain == "ARM" or toolchain == "ARM_STD" or toolchain == "ARM_MICRO":
+ self.search_objects(os.path.abspath(mapfile), "ARM")
+ self.parse_map_file_armcc(file_input)
+ elif toolchain == "GCC_ARM":
+ self.parse_map_file_gcc(file_input)
+ elif toolchain == "IAR":
+ self.search_objects(os.path.abspath(mapfile), toolchain)
+ self.parse_map_file_iar(file_input)
+ else:
+ result = False
except IOError as error:
print "I/O error({0}): {1}".format(error.errno, error.strerror)
- return False
-
- if toolchain == "ARM" or toolchain == "ARM_STD" or toolchain == "ARM_MICRO":
- self.search_objects(os.path.abspath(mapfile), "ARM")
- self.parse_map_file_armcc(file_input)
- elif toolchain == "GCC_ARM":
- self.parse_map_file_gcc(file_input)
- elif toolchain == "IAR":
- self.search_objects(os.path.abspath(mapfile), toolchain)
- self.parse_map_file_iar(file_input)
- else:
- return False
-
- file_input.close()
-
- return True
+ result = False
+ return result
def main():
@@ -502,15 +523,15 @@
# Parser handling
parser = argparse.ArgumentParser(description="Memory Map File Analyser for ARM mbed\nversion %s" % version)
- parser.add_argument('file', help='memory map file')
+ parser.add_argument('file', type=argparse_filestring_type, help='memory map file')
- parser.add_argument('-t', '--toolchain', dest='toolchain', help='select a toolchain used to build the memory map file (ARM, GCC_ARM, IAR)',\
- required=True)
+ parser.add_argument('-t', '--toolchain', dest='toolchain', help='select a toolchain used to build the memory map file (%s)' % ", ".join(MemapParser.toolchains),\
+ required=True, type=argparse_uppercase_type(MemapParser.toolchains, "toolchain"))
parser.add_argument('-o', '--output', help='output file name', required=False)
- parser.add_argument('-e', '--export', dest='export', required=False,\
- help="export format (examples: 'json', 'csv-ci', 'table': default)")
+ parser.add_argument('-e', '--export', dest='export', required=False, default='table', type=argparse_lowercase_hyphen_type(MemapParser.export_formats,'export format'),\
+ help="export format (examples: %s: default)" % ", ".join(MemapParser.export_formats))
parser.add_argument('-v', '--version', action='version', version=version)
@@ -528,13 +549,8 @@
# Parse and decode a map file
if args.file and args.toolchain:
if memap.parse(args.file, args.toolchain) is False:
- print "Unknown toolchain for memory statistics %s" % args.toolchain
sys.exit(0)
- # default export format is table
- if not args.export:
- args.export = 'table'
-
# Write output in file
if args.output != None:
memap.generate_output(args.export, args.output)
