Skip to content

Commit 9f33ba8

Browse files
authored
Merge pull request #2047 from PrzemekWirkus/devel_mmap_proj
[Tools] Add summary for test building
2 parents 458b46c + 12a01f6 commit 9f33ba8

File tree

5 files changed

+186
-109
lines changed

5 files changed

+186
-109
lines changed

tools/build_api.py

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ def build_project(src_path, build_path, target, toolchain_name,
176176

177177
if report != None:
178178
start = time()
179-
179+
180180
# If project_id is specified, use that over the default name
181181
id_name = project_id.upper() if project_id else name.upper()
182182
description = project_description if project_description else name
@@ -232,6 +232,7 @@ def build_project(src_path, build_path, target, toolchain_name,
232232
cur_result["elapsed_time"] = end - start
233233
cur_result["output"] = toolchain.get_output()
234234
cur_result["result"] = "OK"
235+
cur_result["memory_usage"] = toolchain.map_outputs
235236

236237
add_result_to_report(report, cur_result)
237238

@@ -294,7 +295,7 @@ def build_library(src_paths, build_path, target, toolchain_name,
294295

295296
if report != None:
296297
start = time()
297-
298+
298299
# If project_id is specified, use that over the default name
299300
id_name = project_id.upper() if project_id else name.upper()
300301
description = name
@@ -377,7 +378,7 @@ def build_library(src_paths, build_path, target, toolchain_name,
377378
toolchain.copy_files(resources.libraries, build_path, resources=resources)
378379
if resources.linker_script:
379380
toolchain.copy_files(resources.linker_script, build_path, resources=resources)
380-
381+
381382
if resource.hex_files:
382383
toolchain.copy_files(resources.hex_files, build_path, resources=resources)
383384

@@ -399,12 +400,12 @@ def build_library(src_paths, build_path, target, toolchain_name,
399400
except Exception, e:
400401
if report != None:
401402
end = time()
402-
403+
403404
if isinstance(e, ToolException):
404405
cur_result["result"] = "FAIL"
405406
elif isinstance(e, NotSupportedException):
406407
cur_result["result"] = "NOT_SUPPORTED"
407-
408+
408409
cur_result["elapsed_time"] = end - start
409410

410411
toolchain_output = toolchain.get_output()
@@ -428,7 +429,7 @@ def build_lib(lib_id, target, toolchain_name, options=None, verbose=False, clean
428429
if not lib.is_supported(target, toolchain_name):
429430
print 'Library "%s" is not yet supported on target %s with toolchain %s' % (lib_id, target.name, toolchain)
430431
return False
431-
432+
432433
# We need to combine macros from parameter list with macros from library definition
433434
MACROS = lib.macros if lib.macros else []
434435
if macros:
@@ -441,7 +442,7 @@ def build_lib(lib_id, target, toolchain_name, options=None, verbose=False, clean
441442
dependencies_paths = lib.dependencies
442443
inc_dirs = lib.inc_dirs
443444
inc_dirs_ext = lib.inc_dirs_ext
444-
445+
445446
""" src_path: the path of the source directory
446447
build_path: the path of the build directory
447448
target: ['LPC1768', 'LPC11U24', 'LPC2368']
@@ -522,7 +523,7 @@ def build_lib(lib_id, target, toolchain_name, options=None, verbose=False, clean
522523
# Copy Headers
523524
for resource in resources:
524525
toolchain.copy_files(resource.headers, build_path, resources=resource)
525-
526+
526527
dependencies_include_dir.extend(toolchain.scan_resources(build_path).inc_dirs)
527528

528529
# Compile Sources
@@ -716,7 +717,7 @@ def mcu_toolchain_matrix(verbose_html=False, platform_filter=None):
716717
perm_counter += 1
717718
else:
718719
text = "-"
719-
720+
720721
row.append(text)
721722
pt.add_row(row)
722723

@@ -942,6 +943,49 @@ def print_build_results(result_list, build_name):
942943
result += "\n"
943944
return result
944945

946+
def print_build_memory_usage_results(report):
947+
""" Generate result table with memory usage values for build results
948+
Agregates (puts together) reports obtained from self.get_memory_summary()
949+
@param report Report generated during build procedure. See
950+
"""
951+
from prettytable import PrettyTable
952+
columns_text = ['name', 'target', 'toolchain']
953+
columns_int = ['static_ram', 'stack', 'heap', 'total_ram', 'total_flash']
954+
table = PrettyTable(columns_text + columns_int)
955+
956+
for col in columns_text:
957+
table.align[col] = 'l'
958+
959+
for col in columns_int:
960+
table.align[col] = 'r'
961+
962+
for target in report:
963+
for toolchain in report[target]:
964+
for name in report[target][toolchain]:
965+
for dlist in report[target][toolchain][name]:
966+
for dlistelem in dlist:
967+
# Get 'memory_usage' record and build table with statistics
968+
record = dlist[dlistelem]
969+
if 'memory_usage' in record and record['memory_usage']:
970+
# Note that summary should be in the last record of
971+
# 'memory_usage' section. This is why we are grabbing
972+
# last "[-1]" record.
973+
row = [
974+
record['description'],
975+
record['target_name'],
976+
record['toolchain_name'],
977+
record['memory_usage'][-1]['summary']['static_ram'],
978+
record['memory_usage'][-1]['summary']['stack'],
979+
record['memory_usage'][-1]['summary']['heap'],
980+
record['memory_usage'][-1]['summary']['total_ram'],
981+
record['memory_usage'][-1]['summary']['total_flash'],
982+
]
983+
table.add_row(row)
984+
985+
result = "Memory map breakdown for built projects (values in Bytes):\n"
986+
result += table.get_string(sortby='name')
987+
return result
988+
945989
def write_build_report(build_report, template_filename, filename):
946990
build_report_failing = []
947991
build_report_passing = []
@@ -963,14 +1007,14 @@ def write_build_report(build_report, template_filename, filename):
9631007
def scan_for_source_paths(path, exclude_paths=None):
9641008
ignorepatterns = []
9651009
paths = []
966-
1010+
9671011
def is_ignored(file_path):
9681012
for pattern in ignorepatterns:
9691013
if fnmatch.fnmatch(file_path, pattern):
9701014
return True
9711015
return False
972-
973-
1016+
1017+
9741018
""" os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])
9751019
When topdown is True, the caller can modify the dirnames list in-place
9761020
(perhaps using del or slice assignment), and walk() will only recurse into

tools/memap.py

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ def __init__(self):
2626

2727
self.misc_flash_sections = ('.interrupts', '.flash_config')
2828

29-
self.other_sections = ('.interrupts_ram', '.init', '.ARM.extab', \
30-
'.ARM.exidx', '.ARM.attributes', '.eh_frame', \
31-
'.init_array', '.fini_array', '.jcr', '.stab', \
29+
self.other_sections = ('.interrupts_ram', '.init', '.ARM.extab',
30+
'.ARM.exidx', '.ARM.attributes', '.eh_frame',
31+
'.init_array', '.fini_array', '.jcr', '.stab',
3232
'.stabstr', '.ARM.exidx', '.ARM')
3333

3434
# sections to print info (generic for all toolchains)
@@ -43,6 +43,9 @@ def __init__(self):
4343
# list of all object files and mappting to module names
4444
self.object_to_module = dict()
4545

46+
# Memory usage summary structure
47+
self.mem_summary = dict()
48+
4649
def module_add(self, module_name, size, section):
4750
"""
4851
Adds a module / section to the list
@@ -67,7 +70,7 @@ def check_new_section_gcc(self, line):
6770
return i # should name of the section (assuming it's a known one)
6871

6972
if line.startswith('.'):
70-
return 'unknown' # all others are clasified are unknown
73+
return 'unknown' # all others are classified are unknown
7174
else:
7275
return False # everything else, means no change in section
7376

@@ -363,11 +366,12 @@ def generate_output(self, export_format, file_output=None):
363366

364367
# Create table
365368
columns = ['Module']
366-
for i in list(self.print_sections):
367-
columns.append(i)
369+
columns.extend(self.print_sections)
368370

369371
table = PrettyTable(columns)
370372
table.align["Module"] = "l"
373+
for col in self.print_sections:
374+
table.align[col] = 'r'
371375

372376
for i in list(self.print_sections):
373377
table.align[i] = 'r'
@@ -388,8 +392,12 @@ def generate_output(self, export_format, file_output=None):
388392
for k in self.print_sections:
389393
row.append(self.modules[i][k])
390394

391-
json_obj.append({"module":i, "size":{\
392-
k:self.modules[i][k] for k in self.print_sections}})
395+
json_obj.append({
396+
"module":i,
397+
"size":{
398+
k:self.modules[i][k] for k in self.print_sections
399+
}
400+
})
393401

394402
table.add_row(row)
395403

@@ -399,16 +407,19 @@ def generate_output(self, export_format, file_output=None):
399407

400408
table.add_row(subtotal_row)
401409

410+
summary = {
411+
'summary':{
412+
'static_ram':(subtotal['.data']+subtotal['.bss']),
413+
'heap':(subtotal['.heap']),
414+
'stack':(subtotal['.stack']),
415+
'total_ram':(subtotal['.data']+subtotal['.bss']+subtotal['.heap']+subtotal['.stack']),
416+
'total_flash':(subtotal['.text']+subtotal['.data']+misc_flash_mem),
417+
}
418+
}
419+
402420
if export_format == 'json':
403-
json_obj.append({\
404-
'summary':{\
405-
'total_static_ram':(subtotal['.data']+subtotal['.bss']),\
406-
'allocated_heap':(subtotal['.heap']),\
407-
'allocated_stack':(subtotal['.stack']),\
408-
'total_ram':(subtotal['.data']+subtotal['.bss']+subtotal['.heap']+subtotal['.stack']),\
409-
'total_flash':(subtotal['.text']+subtotal['.data']+misc_flash_mem),}})
410-
411-
file_desc.write(json.dumps(json_obj, indent=4))
421+
json_to_file = json_obj + [summary]
422+
file_desc.write(json.dumps(json_to_file, indent=4))
412423
file_desc.write('\n')
413424

414425
elif export_format == 'csv-ci': # CSV format for the CI system
@@ -467,33 +478,38 @@ def generate_output(self, export_format, file_output=None):
467478
if file_desc is not sys.stdout:
468479
file_desc.close()
469480

481+
self.mem_summary = json_obj + [summary]
482+
470483
return True
471484

485+
def get_memory_summary(self):
486+
"""! Object is available only after self.generate_output('json') is called
487+
@return Return memory summary object
488+
"""
489+
return self.mem_summary
490+
472491
def parse(self, mapfile, toolchain):
473492
"""
474493
Parse and decode map file depending on the toolchain
475494
"""
476495

496+
result = True
477497
try:
478-
file_input = open(mapfile, 'rt')
498+
with open(mapfile, 'rt') as file_input:
499+
if toolchain == "ARM" or toolchain == "ARM_STD" or toolchain == "ARM_MICRO":
500+
self.search_objects(os.path.abspath(mapfile), "ARM")
501+
self.parse_map_file_armcc(file_input)
502+
elif toolchain == "GCC_ARM":
503+
self.parse_map_file_gcc(file_input)
504+
elif toolchain == "IAR":
505+
self.search_objects(os.path.abspath(mapfile), toolchain)
506+
self.parse_map_file_iar(file_input)
507+
else:
508+
result = False
479509
except IOError as error:
480510
print "I/O error({0}): {1}".format(error.errno, error.strerror)
481-
return False
482-
483-
if toolchain == "ARM" or toolchain == "ARM_STD" or toolchain == "ARM_MICRO":
484-
self.search_objects(os.path.abspath(mapfile), "ARM")
485-
self.parse_map_file_armcc(file_input)
486-
elif toolchain == "GCC_ARM":
487-
self.parse_map_file_gcc(file_input)
488-
elif toolchain == "IAR":
489-
self.search_objects(os.path.abspath(mapfile), toolchain)
490-
self.parse_map_file_iar(file_input)
491-
else:
492-
return False
493-
494-
file_input.close()
495-
496-
return True
511+
result = False
512+
return result
497513

498514
def main():
499515

0 commit comments

Comments
 (0)