prettify linkmem

This commit is contained in:
jaseg 2020-03-13 11:48:43 +01:00
parent bf7e8701c7
commit edde28594f
3 changed files with 58 additions and 28 deletions

View file

@ -156,11 +156,21 @@ CXXFLAGS += -Wall -Wextra -Wshadow -Wundef -Wredundant-decls
CXXFLAGS += -I. CXXFLAGS += -I.
LDFLAGS += $(ARCH_FLAGS) $(SYSTEM_FLAGS) LDFLAGS += $(ARCH_FLAGS) $(SYSTEM_FLAGS)
LDFLAGS += -Wl,--cre
LDFLAGS += --trace
LIBS += -lgcc 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 # Rules
@ -170,11 +180,10 @@ all: binsize
.PHONY: binsize .PHONY: binsize
binsize: $(BUILDDIR)/$(BINARY) binsize: $(BUILDDIR)/$(BINARY)
$(LD) -T$(LDSCRIPT) $(LDFLAGS) -Wl,--print-memory-usage -o /dev/null $(ALL_OBJS) $(LIBS)
@echo
@echo "▐▬▬▬▌ SyMbOL sIzE HiGhScORe LiSt ▐▬▬▬▌" @echo "▐▬▬▬▌ SyMbOL sIzE HiGhScORe LiSt ▐▬▬▬▌"
$(NM) --print-size --size-sort --radix=d $< | tail -n 20 $(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 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 $@ $(BUILDDIR)/generated: ; mkdir -p $@
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
.PRECIOUS: $(BUILDDIR)/$(BINARY) .PRECIOUS: $(BUILDDIR)/$(BINARY)
$(BUILDDIR)/$(BINARY): $(ALL_OBJS) $(BUILDDIR)/$(BINARY) $(BUILDDIR)/$(BINARY:.elf=.map) &: $(ALL_OBJS)
$(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ -Wl,-Map=$(BUILDDIR)/src/$*.map $^ $(LIBS) $(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ -Wl,-Map=$(BUILDDIR)/$(BINARY:.elf=.map) $^ $(LIBS)
.PHONY: linktrace
linktrace: $(ALL_OBJS)
$(PYTHON3) tools/linktracer.py $(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ $^ $(LIBS)
%.dot: %.elf
r2 -a arm -qc 'aa;agRd' $< 2>/dev/null >$@
tools: $(BUILDDIR)/tools/freq_meas_test 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) $(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)

View file

@ -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 mem_stream = DMA2_Stream1;
static DMA_Stream_TypeDef *const adc_stream = DMA2_Stream0; static DMA_Stream_TypeDef *const adc_stream = DMA2_Stream0;
static const int dma_adc_channel = 0; 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 /* Configure ADC1 to sample channel 0. Trigger from TIM1 CC0 every 1ms. Transfer readings into alternating buffers
* throug DMA. Enable DMA interrupts. * 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. * This means we can immediately start running an FFT on ADC DMA transfer complete interrupt.
*/ */
void adc_init() { void adc_init() {
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN | RCC_AHB1ENR_GPIOCEN;
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN | RCC_APB2ENR_TIM1EN; RCC->APB2ENR |= RCC_APB2ENR_ADC1EN | RCC_APB2ENR_TIM1EN;
/* PC0 -> ADC1.ch10 */
GPIOC->MODER &= ~GPIO_MODER_MODER0_Msk;
GPIOC->MODER |= (3<<GPIO_MODER_MODER0_Pos);
adc_dma->LIFCR |= 0x3f; adc_dma->LIFCR |= 0x3f;
adc_stream->CR = 0; /* disable */ adc_stream->CR = 0; /* disable */
while (adc_stream->CR & DMA_SxCR_EN) while (adc_stream->CR & DMA_SxCR_EN)
@ -45,13 +50,15 @@ void adc_init() {
ADC1->CR1 = (0<<ADC_CR1_RES_Pos) | (0<<ADC_CR1_DISCNUM_Pos) | ADC_CR1_DISCEN | (0<<ADC_CR1_AWDCH_Pos); ADC1->CR1 = (0<<ADC_CR1_RES_Pos) | (0<<ADC_CR1_DISCNUM_Pos) | ADC_CR1_DISCEN | (0<<ADC_CR1_AWDCH_Pos);
ADC1->CR2 = ADC_CR2_EXTEN | (0<<ADC_CR2_EXTSEL_Pos) | ADC_CR2_DMA | ADC_CR2_ADON | ADC_CR2_DDS; ADC1->CR2 = ADC_CR2_EXTEN | (0<<ADC_CR2_EXTSEL_Pos) | ADC_CR2_DMA | ADC_CR2_ADON | ADC_CR2_DDS;
ADC1->SQR3 = (adc_channel<<ADC_SQR3_SQ3_Pos);
ADC1->SQR1 = (0<<ADC_SQR1_L_Pos);
TIM1->CR2 = (2<<TIM_CR2_MMS_Pos); /* Enable update event on TRGO to provide a 1ms reference to rest of system */ TIM1->CR2 = (2<<TIM_CR2_MMS_Pos); /* Enable update event on TRGO to provide a 1ms reference to rest of system */
TIM1->CR1 = TIM_CR1_CEN; TIM1->CR1 = TIM_CR1_CEN;
TIM1->CCMR1 = (6<<TIM_CCMR1_OC1M_Pos) | (0<<TIM_CCMR1_CC1S_Pos); TIM1->CCMR1 = (6<<TIM_CCMR1_OC1M_Pos) | (0<<TIM_CCMR1_CC1S_Pos);
TIM1->CCER = TIM_CCER_CC1E; TIM1->CCER = TIM_CCER_CC1E;
TIM1->PSC = 84; /* 1us ticks @ f_APB2=84MHz */ TIM1->PSC = 84-1; /* 1us ticks @ f_APB2=84MHz */
TIM1->ARR = 1000; /* 1ms period */ TIM1->ARR = 1000-1; /* 1ms period */
TIM1->CCR1 = 1; TIM1->CCR1 = 1;
TIM1->EGR = TIM_EGR_UG; TIM1->EGR = TIM_EGR_UG;
} }

View file

@ -7,12 +7,13 @@ import re
import subprocess import subprocess
from contextlib import contextmanager from contextlib import contextmanager
from collections import defaultdict from collections import defaultdict
import colorsys
import cxxfilt import cxxfilt
from elftools.elf.elffile import ELFFile from elftools.elf.elffile import ELFFile
from elftools.elf.descriptions import describe_symbol_type from elftools.elf.descriptions import describe_symbol_type
import libarchive import libarchive
import matplotlib.cm
@contextmanager @contextmanager
def chdir(newdir): def chdir(newdir):
@ -117,10 +118,19 @@ def wrap(leader='', print=print, left='{', right='}'):
def mangle(name): def mangle(name):
return re.sub('[^a-zA-Z0-9_]', '_', 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__': if __name__ == '__main__':
import argparse import argparse
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--trace-sections', type=str, action='append', default=[]) 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_binary')
parser.add_argument('linker_args', nargs=argparse.REMAINDER) parser.add_argument('linker_args', nargs=argparse.REMAINDER)
args = parser.parse_args() args = parser.parse_args()
@ -129,6 +139,10 @@ if __name__ == '__main__':
trace_sections_mangled = { sec.replace('.', '_') for sec in trace_sections } 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) 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: []) clusters = defaultdict(lambda: [])
for sym, (obj, size) in syms.items(): for sym, (obj, size) in syms.items():
clusters[obj].append((sym, size)) clusters[obj].append((sym, size))
@ -137,6 +151,9 @@ if __name__ == '__main__':
for name, (obj, size) in syms.items(): for name, (obj, size) in syms.items():
if size is not None: if size is not None:
obj_size[obj] += size 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: with wrap('digraph G', print) as lvl1print:
print('rankdir=LR;') print('rankdir=LR;')
@ -144,18 +161,20 @@ if __name__ == '__main__':
for i, (obj, syms) in enumerate(clusters.items()): for i, (obj, syms) in enumerate(clusters.items()):
with wrap(f'subgraph cluster_{i}', lvl1print) as lvl2print: 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 = <<table border="0"><tr><td border="0" cellpadding="5" bgcolor="{fc}"><font face="carlito" color="{cc}"><b>{path.basename(obj)} ({obj_size[obj]}B)</b></font></td></tr></table>>;')
lvl2print() lvl2print()
for sym, size in syms: for sym, size in syms:
if sym in syms_out: 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() lvl1print()
for start, ends in refs.items(): for start, ends in refs.items():
for end in ends: for end in ends:
if end and (start in syms_out or start in trace_sections_mangled) and end in syms_out: 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: for sec in trace_sections:
lvl1print(f'{sec.replace(".", "_")} [label = "section {sec}"];') lvl1print(f'{sec.replace(".", "_")} [label = "section {sec}", shape="box", style="filled,bold"];')