From edde28594fbbf44a25f0fb4229353137bca35a3e Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 13 Mar 2020 11:48:43 +0100 Subject: prettify linkmem --- controller/fw/Makefile | 42 +++++++++++++++++++++++------------------- controller/fw/src/adc.c | 13 ++++++++++--- controller/fw/tools/linkmem.py | 29 ++++++++++++++++++++++++----- 3 files changed, 57 insertions(+), 27 deletions(-) diff --git a/controller/fw/Makefile b/controller/fw/Makefile index 27fd9ba..db10868 100644 --- a/controller/fw/Makefile +++ b/controller/fw/Makefile @@ -156,11 +156,21 @@ CXXFLAGS += -Wall -Wextra -Wshadow -Wundef -Wredundant-decls CXXFLAGS += -I. LDFLAGS += $(ARCH_FLAGS) $(SYSTEM_FLAGS) -LDFLAGS += -Wl,--cre -LDFLAGS += --trace LIBS += -lgcc -LDFLAGS += -Wl,--gc-sections -Wl,--trace-symbol=twiddleCoef_4096 -Wl,--trace-symbol=arm_cfft_sR_f32_len4096 +LDFLAGS += -Wl,--gc-sections + +OBJS := $(addprefix $(BUILDDIR)/,$(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)) + +ALL_OBJS := $(OBJS) +ALL_OBJS += $(BUILDDIR)/src/startup_stm32f407xx.o +ALL_OBJS += $(BUILDDIR)/src/system_stm32f4xx.o +ALL_OBJS += $(BUILDDIR)/libsodium/src/libsodium/.libs/libsodium.a +ALL_OBJS += $(BUILDDIR)/tinyaes/aes.o +ALL_OBJS += $(BUILDDIR)/levmarq/levmarq.o +ALL_OBJS += $(BUILDDIR)/generated/gold_code_$(DSSS_GOLD_CODE_NBITS).o +ALL_OBJS += $(BUILDDIR)/generated/fmeas_fft_window.o +ALL_OBJS += $(BUILDDIR)/generated/dsss_cwt_wavelet.o ######################################################################################################################## # Rules @@ -170,11 +180,10 @@ all: binsize .PHONY: binsize binsize: $(BUILDDIR)/$(BINARY) + $(LD) -T$(LDSCRIPT) $(LDFLAGS) -Wl,--print-memory-usage -o /dev/null $(ALL_OBJS) $(LIBS) + @echo @echo "▐▬▬▬▌ SyMbOL sIzE HiGhScORe LiSt ▐▬▬▬▌" $(NM) --print-size --size-sort --radix=d $< | tail -n 20 - @echo - @echo "===== Binary size =====" - $(SIZE) $< src/dsss_demod.c: $(BUILDDIR)/generated/dsss_gold_code.h $(BUILDDIR)/generated/dsss_butter_filter.h @@ -208,21 +217,16 @@ $(PRESIG_KEYFILE): $(BUILDDIR)/generated: ; mkdir -p $@ -OBJS := $(addprefix $(BUILDDIR)/,$(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)) +.PRECIOUS: $(BUILDDIR)/$(BINARY) +$(BUILDDIR)/$(BINARY) $(BUILDDIR)/$(BINARY:.elf=.map) &: $(ALL_OBJS) + $(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ -Wl,-Map=$(BUILDDIR)/$(BINARY:.elf=.map) $^ $(LIBS) -ALL_OBJS := $(OBJS) -ALL_OBJS += $(BUILDDIR)/src/startup_stm32f407xx.o -ALL_OBJS += $(BUILDDIR)/src/system_stm32f4xx.o -ALL_OBJS += $(BUILDDIR)/libsodium/src/libsodium/.libs/libsodium.a -ALL_OBJS += $(BUILDDIR)/tinyaes/aes.o -ALL_OBJS += $(BUILDDIR)/levmarq/levmarq.o -ALL_OBJS += $(BUILDDIR)/generated/gold_code_$(DSSS_GOLD_CODE_NBITS).o -ALL_OBJS += $(BUILDDIR)/generated/fmeas_fft_window.o -ALL_OBJS += $(BUILDDIR)/generated/dsss_cwt_wavelet.o +.PHONY: linktrace +linktrace: $(ALL_OBJS) + $(PYTHON3) tools/linktracer.py $(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ $^ $(LIBS) -.PRECIOUS: $(BUILDDIR)/$(BINARY) -$(BUILDDIR)/$(BINARY): $(ALL_OBJS) - $(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ -Wl,-Map=$(BUILDDIR)/src/$*.map $^ $(LIBS) +%.dot: %.elf + r2 -a arm -qc 'aa;agRd' $< 2>/dev/null >$@ tools: $(BUILDDIR)/tools/freq_meas_test $(BUILDDIR)/tools/freq_meas_test: tools/freq_meas_test.c src/freq_meas.c levmarq/levmarq.c $(BUILDDIR)/generated/fmeas_fft_window.c $(CMSIS_SOURCES) diff --git a/controller/fw/src/adc.c b/controller/fw/src/adc.c index 5f6b995..4801525 100644 --- a/controller/fw/src/adc.c +++ b/controller/fw/src/adc.c @@ -12,6 +12,7 @@ static DMA_TypeDef *const adc_dma = DMA2; static DMA_Stream_TypeDef *const mem_stream = DMA2_Stream1; static DMA_Stream_TypeDef *const adc_stream = DMA2_Stream0; static const int dma_adc_channel = 0; +static const int adc_channel = 10; /* Configure ADC1 to sample channel 0. Trigger from TIM1 CC0 every 1ms. Transfer readings into alternating buffers * throug DMA. Enable DMA interrupts. @@ -24,9 +25,13 @@ static const int dma_adc_channel = 0; * This means we can immediately start running an FFT on ADC DMA transfer complete interrupt. */ void adc_init() { - RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; + RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN | RCC_AHB1ENR_GPIOCEN; RCC->APB2ENR |= RCC_APB2ENR_ADC1EN | RCC_APB2ENR_TIM1EN; + /* PC0 -> ADC1.ch10 */ + GPIOC->MODER &= ~GPIO_MODER_MODER0_Msk; + GPIOC->MODER |= (3<LIFCR |= 0x3f; adc_stream->CR = 0; /* disable */ while (adc_stream->CR & DMA_SxCR_EN) @@ -45,13 +50,15 @@ void adc_init() { ADC1->CR1 = (0<CR2 = ADC_CR2_EXTEN | (0<SQR3 = (adc_channel<SQR1 = (0<CR2 = (2<CR1 = TIM_CR1_CEN; TIM1->CCMR1 = (6<CCER = TIM_CCER_CC1E; - TIM1->PSC = 84; /* 1us ticks @ f_APB2=84MHz */ - TIM1->ARR = 1000; /* 1ms period */ + TIM1->PSC = 84-1; /* 1us ticks @ f_APB2=84MHz */ + TIM1->ARR = 1000-1; /* 1ms period */ TIM1->CCR1 = 1; TIM1->EGR = TIM_EGR_UG; } diff --git a/controller/fw/tools/linkmem.py b/controller/fw/tools/linkmem.py index a04f31e..494217a 100644 --- a/controller/fw/tools/linkmem.py +++ b/controller/fw/tools/linkmem.py @@ -7,12 +7,13 @@ import re import subprocess from contextlib import contextmanager from collections import defaultdict +import colorsys import cxxfilt - from elftools.elf.elffile import ELFFile from elftools.elf.descriptions import describe_symbol_type import libarchive +import matplotlib.cm @contextmanager def chdir(newdir): @@ -117,10 +118,19 @@ def wrap(leader='', print=print, left='{', right='}'): def mangle(name): return re.sub('[^a-zA-Z0-9_]', '_', name) +hexcolor = lambda r, g, b: f'#{int(r*255):02x}{int(g*255):02x}{int(b*255):02x}' +def vhex(val): + r,g,b,_a = matplotlib.cm.viridis(1.0-val) + fc = hexcolor(r, g, b) + h,s,v = colorsys.rgb_to_hsv(r,g,b) + cc = '#000000' if v > 0.8 else '#ffffff' + return fc, cc + if __name__ == '__main__': import argparse parser = argparse.ArgumentParser() parser.add_argument('--trace-sections', type=str, action='append', default=[]) + parser.add_argument('--trim-stubs', type=str, action='append', default=[]) parser.add_argument('linker_binary') parser.add_argument('linker_args', nargs=argparse.REMAINDER) args = parser.parse_args() @@ -129,6 +139,10 @@ if __name__ == '__main__': trace_sections_mangled = { sec.replace('.', '_') for sec in trace_sections } syms, refs, syms_out = trace_source_files(args.linker_binary, args.linker_args, trace_sections) + for name, (obj, size) in syms.items(): + if path.basename(obj) in args.trim_stubs and size <= 8 and not refs.get(name): + syms_out.discard(name) + clusters = defaultdict(lambda: []) for sym, (obj, size) in syms.items(): clusters[obj].append((sym, size)) @@ -137,6 +151,9 @@ if __name__ == '__main__': for name, (obj, size) in syms.items(): if size is not None: obj_size[obj] += size + max_size = max([ size for _obj, size in syms.values() if size is not None ]) + + max_osize = max(obj_size.values()) with wrap('digraph G', print) as lvl1print: print('rankdir=LR;') @@ -144,18 +161,20 @@ if __name__ == '__main__': for i, (obj, syms) in enumerate(clusters.items()): with wrap(f'subgraph cluster_{i}', lvl1print) as lvl2print: - lvl2print(f'label = "{obj} <{obj_size[obj]}>";') + fc, cc = vhex(obj_size[obj]/max_osize) + lvl2print(f'label = <
{path.basename(obj)} ({obj_size[obj]}B)
>;') lvl2print() for sym, size in syms: if sym in syms_out: - lvl2print(f'{mangle(sym)}[label = "{sym} <{size}>"];') + fc, cc = vhex(size/max_size) + lvl2print(f'{mangle(sym)}[label = "{sym} ({size}B)", style="rounded,filled", shape="box", fillcolor="{fc}", fontname="carlito", fontcolor="{cc}" color=None];') lvl1print() for start, ends in refs.items(): for end in ends: if end and (start in syms_out or start in trace_sections_mangled) and end in syms_out: - lvl1print(f'{mangle(start)} -> {mangle(end)};') + lvl1print(f'{mangle(start)} -> {mangle(end)} [style="bold", color="#333333"];') for sec in trace_sections: - lvl1print(f'{sec.replace(".", "_")} [label = "section {sec}"];') + lvl1print(f'{sec.replace(".", "_")} [label = "section {sec}", shape="box", style="filled,bold"];') -- cgit