diff --git a/apps/calculation/test.py b/apps/calculation/test.py new file mode 100644 index 000000000..84fb10c01 --- /dev/null +++ b/apps/calculation/test.py @@ -0,0 +1,11 @@ +import sys, tty +def command_line(): + tty.setraw(sys.stdin) + while True: + char = sys.stdin.read(1) + if ord(char) == 3: # CTRL-C + break; + print(ord(char)) + sys.stdout.write(u"\u001b[1000D") # Move all the way left + +command_line(); diff --git a/build/device/ram_map.py b/build/device/ram_map.py index d97ab9e04..08c611274 100644 --- a/build/device/ram_map.py +++ b/build/device/ram_map.py @@ -4,61 +4,86 @@ import re import subprocess import sys import matplotlib.pyplot as plt +import random from matplotlib.ticker import FormatStrFormatter -readelf_line_regex = re.compile("[0-9]+:\s+([0-9a-f]+)\s+([0-9]+)\s+[A-Z]+") -def parse_line(line): - hex_start, dec_size = re.findall(readelf_line_regex, line)[0] - return (int(hex_start, 16), int(dec_size)) +def filter_set(data, pred): + result = {} + for k,v in data.items(): + if (pred(v)): + result[k] = v + return result -readelf_output = subprocess.check_output([ - "arm-none-eabi-readelf", - "-W", # Don't limit line lenght - "-s", # Sizes - sys.argv[1] -]).decode('utf-8') +def pred_ram(symbol): + return (symbol[0] >= 0x20000000) and (symbol[0] <= 0x20040000) -for line in readelf_output.splitlines(): - words = line.split() - if not words: - continue - symbol = words[-1] - if symbol == "_ZN3Ion17staticStorageAreaE": - storage = parse_line(line) - if symbol == "_ZZN13AppsContainer19sharedAppsContainerEvE20appsContainerStorage": - container = parse_line(line) - if symbol == "_stack_start": - stack_start, _ = parse_line(line) - if symbol == "_stack_end": - stack_end, _ = parse_line(line) - if symbol == "_heap_start": - heap_start, _ = parse_line(line) - if symbol == "_heap_end": - heap_end, _ = parse_line(line) +def pred_size(symbol): + return (symbol[1] >= 64) -stack_size = stack_start - stack_end # Stack grows downwards -stack = (stack_end, stack_size) -heap_size = heap_end - heap_start -heap = (heap_start, heap_size) +def load_symbols(filename): + nm_output = subprocess.check_output([ + "arm-none-eabi-nm", + "--print-size", + filename + ]).decode('utf-8').splitlines() + nm_symbol_regex = re.compile("^([0-9A-Fa-f]+) ([0-9A-Fa-f]+) (.) (.+)$") + nm_sizeless_regex = re.compile("^([0-9a-z]+) (.) (.+)$") + symbol_results = [ re.match(nm_symbol_regex, line).groups() for line in nm_output if re.match(nm_symbol_regex, line) ] + sizeless_results = [ re.match(nm_sizeless_regex, line).groups() for line in nm_output if re.match(nm_sizeless_regex, line) ] + results = {} + for result in symbol_results: + results[result[3]] = ((int(result[0],16),int(result[1],16),result[2],result[3])) + for result in sizeless_results: + results[result[2]] = ((int(result[0],16),0,result[1],result[2])) + # Fixup stack and heap + for i in (("_stack_start", "_stack_end", "_stack"), ("_heap_start", "_heap_end", "_heap")): + if i[0] in results and i[1] in results: + start = results[i[0]] + end = results[i[1]] + results[i[2]] = (min(start[0], end[0]), abs(end[0]-start[0]), start[2], i[2]) + del results[i[0]] + del results[i[1]] + return results + +def demangle_symbols(symbols): + symbol_names = [] + for name in symbols.keys(): + symbol_names.append(name) + symbols_encoded = "\n".join(symbol_names).encode('utf-8') + demangled_output = subprocess.check_output(["c++filt"], input=symbols_encoded).decode('utf-8').splitlines() + demangled_symbols = {} + cpt=0 + for symbol in symbols.values(): + demangled_symbols[demangled_output[cpt]] = (symbol[0], symbol[1], symbol[2], demangled_output[cpt]) + cpt += 1 + return demangled_symbols def format_kb(i): - return ("%d KB" % (i/1024)) + return ("%.3f KiB" % (i/1024)) -fig,ax = plt.subplots() +def plot_symbols(symbols, range_start, range_end): + fig,ax = plt.subplots() + cpt = 0 + for symbol in symbols.values(): + symbol_name = symbol[3].lstrip("_") + symbol_color=(random.uniform(0,1),random.uniform(0,1),random.uniform(0,1)) + ax.broken_barh([(symbol[0], symbol[1])], (0, 1), color=symbol_color, label=symbol_name + " - " + format_kb(symbol[1])) + cpt += 1 + ax.set_yticks([]) + ax.set_xticks(list(range(range_start, range_end+1, int((range_end-range_start)/16)))) + xlabels = map(lambda t: '0x%08X' % int(t), ax.get_xticks()) + ax.set_xticklabels(xlabels); + ax.legend() + fig.set_size_inches(20, 2) + return fig -def plot(value, name, c): - ax.broken_barh([value], (0, 1), color=c, label=name + " - " + format_kb(value[1])) +data=load_symbols(sys.argv[1]) +data=demangle_symbols(data) +data = filter_set(data, pred_ram) +data = filter_set(data, pred_size) -plot(container, "Container", "blue") -plot(storage, "Storage", "red") -plot(heap, "Heap", "pink") -plot(stack, "Stack", "green") +fig=plot_symbols(data,0x20000000,0x20040000) -ax.set_yticks([]) -ax.set_xticks(list(range(0x20000000,0x20040001,0x10000))) -xlabels = map(lambda t: '0x%08X' % int(t), ax.get_xticks()) -ax.set_xticklabels(xlabels); -ax.legend() -fig.set_size_inches(20, 2) -fig.savefig(sys.argv[2]) +fig.show() +input() diff --git a/build/targets.device.mak b/build/targets.device.mak index bc0840c77..9fedbc053 100644 --- a/build/targets.device.mak +++ b/build/targets.device.mak @@ -20,11 +20,8 @@ $(eval $(call rule_for, \ with_local_version \ )) -$(eval $(call rule_for, \ - RAMSIZE, %_ram_map.png, %.$$(EXE), \ - $$(PYTHON) build/device/ram_map.py $$< $$@, \ - with_local_version \ -)) +%_ram_map: %.$(EXE) + $(PYTHON) build/device/ram_map.py $(BUILD_DIR)/$< .PHONY: %_size %_size: $(BUILD_DIR)/%.$(EXE) @@ -83,4 +80,4 @@ binpack: $(BUILD_DIR)/flasher.light.bin $(BUILD_DIR)/epsilon.onboarding.two_bina cp $(BUILD_DIR)/flasher.light.bin $(BUILD_DIR)/binpack cp $(BUILD_DIR)/epsilon.onboarding.internal.bin $(BUILD_DIR)/epsilon.onboarding.external.bin $(BUILD_DIR)/binpack cd $(BUILD_DIR) && for binary in flasher.light.bin epsilon.onboarding.internal.bin epsilon.onboarding.external.bin; do shasum -a 256 -b binpack/$${binary} > binpack/$${binary}.sha256;done - cd $(BUILD_DIR) && tar cvfz binpack-$(MODEL)-`git rev-parse HEAD | head -c 7`.tgz binpack/* \ No newline at end of file + cd $(BUILD_DIR) && tar cvfz binpack-$(MODEL)-`git rev-parse HEAD | head -c 7`.tgz binpack/*