mirror of https://github.com/ARMmbed/mbed-os.git
Added pretty bar printing for compile output
Looks like this: Building project mbed-os-prettyoutput (ARCH_PRO, GCC_ARM) Scan: . Scan: env Scan: mbed Scan: FEATURE_LWIP Text 70.5KB Data 2.72KB BSS 7.43KB ROM 73.2KB RAM 10.1KB ROM [||||||| ] 73.2KB/512KB RAM [|||||||||||||||| ] 10.1KB/32KB Image: BUILD/ARCH_PRO/GCC_ARM/mbed-os-prettyoutput.bin If you build a target without a cmsis-pack it looks like this: Building project mbed-os-prettyoutput (ARM_BEETLE_SOC, GCC_ARM) Scan: . Scan: env Scan: mbed Scan: FEATURE_BLE Text 99KB Data 2.84KB BSS 13KB ROM 102KB RAM 15.8KB Image: BUILD/ARM_BEETLE_SOC/GCC_ARM/mbed-os-prettyoutput.bin And the old behaviour of displaying the memap table can be brought back by passing the --stats-depth parameterpull/5929/head
parent
4c07c1c830
commit
471d99c68f
|
@ -27,6 +27,7 @@ from os import linesep, remove, makedirs
|
||||||
from time import time
|
from time import time
|
||||||
from intelhex import IntelHex
|
from intelhex import IntelHex
|
||||||
from json import load, dump
|
from json import load, dump
|
||||||
|
from tools.arm_pack_manager import Cache
|
||||||
|
|
||||||
from tools.utils import mkdir, run_cmd, run_cmd_ext, NotSupportedException,\
|
from tools.utils import mkdir, run_cmd, run_cmd_ext, NotSupportedException,\
|
||||||
ToolException, InvalidReleaseTargetException, intelhex_offset
|
ToolException, InvalidReleaseTargetException, intelhex_offset
|
||||||
|
@ -547,19 +548,24 @@ def build_project(src_paths, build_path, target, toolchain_name,
|
||||||
memap_instance = getattr(toolchain, 'memap_instance', None)
|
memap_instance = getattr(toolchain, 'memap_instance', None)
|
||||||
memap_table = ''
|
memap_table = ''
|
||||||
if memap_instance:
|
if memap_instance:
|
||||||
# Write output to stdout in text (pretty table) format
|
real_stats_depth = stats_depth if stats_depth is None else 2
|
||||||
memap_table = memap_instance.generate_output('table', stats_depth)
|
memap_table = memap_instance.generate_output('table', real_stats_depth)
|
||||||
|
|
||||||
if not silent:
|
if not silent:
|
||||||
|
if not stats_depth:
|
||||||
|
memap_bars = memap_instance.generate_output('bars',
|
||||||
|
real_stats_depth, None,
|
||||||
|
getattr(toolchain.target, 'device_name', None))
|
||||||
|
print memap_bars
|
||||||
|
else:
|
||||||
print memap_table
|
print memap_table
|
||||||
|
|
||||||
# Write output to file in JSON format
|
# Write output to file in JSON format
|
||||||
map_out = join(build_path, name + "_map.json")
|
map_out = join(build_path, name + "_map.json")
|
||||||
memap_instance.generate_output('json', stats_depth, map_out)
|
memap_instance.generate_output('json', real_stats_depth, map_out)
|
||||||
|
|
||||||
# Write output to file in CSV format for the CI
|
# Write output to file in CSV format for the CI
|
||||||
map_csv = join(build_path, name + "_map.csv")
|
map_csv = join(build_path, name + "_map.csv")
|
||||||
memap_instance.generate_output('csv-ci', stats_depth, map_csv)
|
memap_instance.generate_output('csv-ci', real_stats_depth, map_csv)
|
||||||
|
|
||||||
resources.detect_duplicates(toolchain)
|
resources.detect_duplicates(toolchain)
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ if __name__ == '__main__':
|
||||||
"--stats-depth",
|
"--stats-depth",
|
||||||
type=int,
|
type=int,
|
||||||
dest="stats_depth",
|
dest="stats_depth",
|
||||||
default=2,
|
default=None,
|
||||||
help="Depth level for static memory report")
|
help="Depth level for static memory report")
|
||||||
|
|
||||||
# Local run
|
# Local run
|
||||||
|
|
|
@ -9,9 +9,11 @@ from os.path import basename, dirname, join, relpath, commonprefix
|
||||||
import re
|
import re
|
||||||
import csv
|
import csv
|
||||||
import json
|
import json
|
||||||
|
import math
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from prettytable import PrettyTable
|
from prettytable import PrettyTable
|
||||||
|
from tools.arm_pack_manager import Cache
|
||||||
|
|
||||||
from utils import argparse_filestring_type, \
|
from utils import argparse_filestring_type, \
|
||||||
argparse_lowercase_hyphen_type, argparse_uppercase_type
|
argparse_lowercase_hyphen_type, argparse_uppercase_type
|
||||||
|
@ -506,7 +508,7 @@ class MemapParser(object):
|
||||||
|
|
||||||
export_formats = ["json", "csv-ci", "table"]
|
export_formats = ["json", "csv-ci", "table"]
|
||||||
|
|
||||||
def generate_output(self, export_format, depth, file_output=None):
|
def generate_output(self, export_format, depth, file_output=None, *args):
|
||||||
""" Generates summary of memory map data
|
""" Generates summary of memory map data
|
||||||
|
|
||||||
Positional arguments:
|
Positional arguments:
|
||||||
|
@ -531,8 +533,9 @@ class MemapParser(object):
|
||||||
|
|
||||||
to_call = {'json': self.generate_json,
|
to_call = {'json': self.generate_json,
|
||||||
'csv-ci': self.generate_csv,
|
'csv-ci': self.generate_csv,
|
||||||
'table': self.generate_table}[export_format]
|
'table': self.generate_table,
|
||||||
output = to_call(file_desc)
|
'bars': self.generate_bars}[export_format]
|
||||||
|
output = to_call(file_desc, *args)
|
||||||
|
|
||||||
if file_desc is not stdout:
|
if file_desc is not stdout:
|
||||||
file_desc.close()
|
file_desc.close()
|
||||||
|
@ -616,6 +619,71 @@ class MemapParser(object):
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
def generate_bars(self, file_desc, device_name=None):
|
||||||
|
""" Generates nice looking bars that represent the memory consumption
|
||||||
|
|
||||||
|
Returns: string containing nice looking bars
|
||||||
|
"""
|
||||||
|
|
||||||
|
# TODO add tty detection, and width detection probably
|
||||||
|
WIDTH = 72
|
||||||
|
try:
|
||||||
|
# NOTE this only works on linux
|
||||||
|
import sys, fcntl, termios, struct
|
||||||
|
height, width, _, _ = struct.unpack('HHHH',
|
||||||
|
fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ,
|
||||||
|
struct.pack('HHHH', 0, 0, 0, 0)))
|
||||||
|
WIDTH = min(width, WIDTH)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
text = self.subtotal['.text']
|
||||||
|
data = self.subtotal['.data']
|
||||||
|
bss = self.subtotal['.bss']
|
||||||
|
rom_used = self.mem_summary['total_flash']
|
||||||
|
ram_used = self.mem_summary['static_ram']
|
||||||
|
|
||||||
|
# No device_name = no cmsis-pack = we don't know the memory layout
|
||||||
|
if device_name is not None:
|
||||||
|
try:
|
||||||
|
cache = Cache(False, False)
|
||||||
|
cmsis_part = cache.index[device_name]
|
||||||
|
rom_avail = int(cmsis_part['memory']['IROM1']['size'], 0)
|
||||||
|
ram_avail = int(cmsis_part['memory']['IRAM1']['size'], 0)
|
||||||
|
except KeyError:
|
||||||
|
# If we don't have the expected regions, fall back to no device_name
|
||||||
|
device_name = None
|
||||||
|
|
||||||
|
PREFIXES = ['', 'K', 'M', 'G', 'T', 'P', 'E']
|
||||||
|
def unit(n, u='B', p=3):
|
||||||
|
if n == 0:
|
||||||
|
return '0' + u
|
||||||
|
|
||||||
|
scale = math.floor(math.log(n, 1024))
|
||||||
|
return '{1:.{0}g}{2}{3}'.format(p, n/(1024**scale), PREFIXES[int(scale)], u)
|
||||||
|
|
||||||
|
usage = "Text {} Data {} BSS {}".format(unit(text), unit(data), unit(bss))
|
||||||
|
avail = "ROM {} RAM {}".format(unit(rom_used), unit(ram_used))
|
||||||
|
output = ["{0} {1:>{2}}".format(usage, avail,
|
||||||
|
abs(WIDTH-len(usage)-1) if device_name is not None else 0)]
|
||||||
|
|
||||||
|
if device_name is not None:
|
||||||
|
for region, avail, uses in [
|
||||||
|
('ROM', rom_avail, [('|', text), ('|', data)]),
|
||||||
|
('RAM', ram_avail, [('|', bss), ('|', data)])]:
|
||||||
|
barwidth = WIDTH-17 - len(region)
|
||||||
|
|
||||||
|
used = sum(use for c, use in uses)
|
||||||
|
bars = [(c, (barwidth*use) // avail) for c, use in uses]
|
||||||
|
bars.append((' ', barwidth - sum(width for c, width in bars)))
|
||||||
|
bars = ''.join(c*width for c, width in bars)
|
||||||
|
|
||||||
|
output.append("{0} [{2:<{1}}] {3:>13}".format(
|
||||||
|
region, barwidth, bars,
|
||||||
|
"{}/{}".format(unit(used), unit(avail))))
|
||||||
|
|
||||||
|
return '\n'.join(output)
|
||||||
|
|
||||||
toolchains = ["ARM", "ARM_STD", "ARM_MICRO", "GCC_ARM", "GCC_CR", "IAR"]
|
toolchains = ["ARM", "ARM_STD", "ARM_MICRO", "GCC_ARM", "GCC_CR", "IAR"]
|
||||||
|
|
||||||
def compute_report(self):
|
def compute_report(self):
|
||||||
|
|
Loading…
Reference in New Issue