mirror of
https://github.com/opentx/opentx.git
synced 2025-07-13 03:19:53 +03:00
184 lines
6.2 KiB
Bash
Executable file
184 lines
6.2 KiB
Bash
Executable file
#!/bin/bash
|
|
#
|
|
# This is a wrapper for the elf-size-report.awk script which prints a detailed report
|
|
# of memory segment allocations and usage in a given ELF file, based on gcc 'size' output.
|
|
# This script sets up memory segment information needed by the awk script.
|
|
# If more than one .elf file is given, then a comparison (delta memory use) report is
|
|
# also performed using elf-size-compare.awk.
|
|
# Currently supports some STMicro & Atmel ARM MCUs. May not work with all placement strategies.
|
|
#
|
|
# Usage:
|
|
# [VAR=value] ./elf-memory-report.sh [options] [file.elf] [file2.elf] [...]
|
|
#
|
|
# Where VAR is any of the CAPITALIZED variables below. More than one can be specified,
|
|
# and any VAR can also be set in the environment.
|
|
# SIZE : gcc binutils 'size' command to use, default is "arm-none-eabi-size".
|
|
# MCU :
|
|
# Specifies MCU model on which to base default segment location/size parameters. Also see "--mcu=" option.
|
|
# MEM_START_<segment> & MEM_SIZE_<segment> : (read code below for defaults)
|
|
# Allows specifying additional/custom segment information, eg. MEM_SIZE_FLASH=768
|
|
#
|
|
# Options can be one or more of the following:
|
|
# --mcu=<MCU>
|
|
# Set MCU type. Same as setting the MCU env. variable, and overrides it.
|
|
# --skip-data
|
|
# Some linker scripts duplicate .data in the output (eg: .data and .data_run).
|
|
# Set this option to skip .data from being counted in RAM a 2nd time
|
|
# (it is always shown as being in Flash).
|
|
# --compare-only
|
|
# When specifying multiple elf files, only show the final comparison report.
|
|
# --no-compare
|
|
# Opposite and exclusive of previous option, that is, do NOT show comparison report (only size reports).
|
|
#
|
|
# If an elf file is not specified on the command line, this script will prompt for one.
|
|
#
|
|
# Examples:
|
|
# MCU="STM32F439xI" MEM_SIZE_SDRAM2=8192 ./elf-memory-report.sh path/to/firmware.elf
|
|
# ./elf-memory-report.sh --mcu ATSAM3S4C --compare-only firmware_new.elf firmware_old.elf
|
|
# set -k && ./elf-memory-report.sh MCU=STM32F427VG --skip-data firmware.elf
|
|
# (the -k switch allows variable assignment anywhere on the command line)
|
|
# c:\cygwin\bin\bash -kc './elf-memory-report.sh --mcu ATSAM3S8C "c:\windows\path\with spaces\firmware.elf"'
|
|
#
|
|
# License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
|
# Copyright (c)2016 Maxim Paperno
|
|
# Copyright (c)2017 OpenTX
|
|
#
|
|
|
|
# -- gcc binutils 'size' command to use
|
|
: ${SIZE:="arm-none-eabi-size"}
|
|
|
|
# -- MCU type, if defined will set certain memory defaults
|
|
# e.g. STM32F205xE or ATSAM3S4C
|
|
: ${MCU:="unknown"}
|
|
|
|
# -- process options
|
|
compare=2
|
|
skip_data=0
|
|
for i in "$@" ; do
|
|
case $i in
|
|
--mcu=*) MCU="${i#*=}"; shift;;
|
|
--skip-data) skip_data=1; shift;;
|
|
--compare-only) compare=1; shift;;
|
|
--no-compare) compare=0; shift;;
|
|
esac
|
|
done
|
|
|
|
# -- make sure gawk is installed
|
|
: ${AWKCMD:=""}
|
|
if gawk --version >/dev/null 2>&1; then
|
|
[[ "$OSTYPE" == "darwin"* ]] && AWKCMD="gawk -nf"
|
|
else
|
|
echo "GAWK is required, exiting."
|
|
exit 1
|
|
fi
|
|
|
|
# -- defaults which may change based on MCU
|
|
default_flash_addr=0x08000000
|
|
default_flash_sz=1024 # KB
|
|
default_ccm_sz=0
|
|
default_ram1_sz=128
|
|
default_ram2_sz=0
|
|
default_ram3_sz=0
|
|
# -- Set defaults based on MCU type
|
|
if [[ $MCU != "unknown" ]] ; then
|
|
mcu_brand=${MCU:0:2} # ST or AT
|
|
if [[ $mcu_brand == "ST" && ${#MCU} -ge 7 ]] ; then
|
|
# e.g.: STM32F427VG
|
|
stm_series=${MCU:6:1} # 4
|
|
stm_ser_ex=${MCU:7:1} # 2
|
|
stm_flash=${MCU:10:1} # G
|
|
default_ram1_sz=112
|
|
default_ram2_sz=16
|
|
case $stm_flash in
|
|
"I") default_flash_sz=2048;;
|
|
"G") default_flash_sz=1024;;
|
|
"E") default_flash_sz=512;;
|
|
"C") default_flash_sz=256;;
|
|
esac
|
|
if (( $stm_series == 4 )) ; then
|
|
default_ccm_sz=64
|
|
if (( $stm_ser_ex >= 2 )) ; then
|
|
default_ram3_sz=64
|
|
fi
|
|
fi
|
|
elif [[ $mcu_brand == "AT" && ${#MCU} -ge 9 ]] ; then
|
|
# e.g.: ATSAM3S4C
|
|
atm_series=${MCU:5:4} # 3S4C
|
|
default_flash_addr=0x00400000
|
|
case $atm_series in
|
|
"3S8C") default_flash_sz=512; default_ram1_sz=64;;
|
|
"3S4C") default_flash_sz=256; default_ram1_sz=48;;
|
|
"3S2C") default_flash_sz=128; default_ram1_sz=32;;
|
|
esac
|
|
else
|
|
echo "MCU type unrecognized, exiting."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# -- target memory locations in hex
|
|
: ${MEM_START_FLASH:=$default_flash_addr}
|
|
: ${MEM_START_CCRAM:=0x10000000}
|
|
: ${MEM_START_SRAM1:=0x20000000}
|
|
: ${MEM_START_SRAM2:=0x2001c000}
|
|
: ${MEM_START_SRAM3:=0x20020000}
|
|
: ${MEM_START_PSRAM1:=0x60000000}
|
|
: ${MEM_START_SDRAM1:=0xC0000000}
|
|
: ${MEM_START_SDRAM2:=0xD0000000}
|
|
|
|
# -- target memory sizes in KB
|
|
: ${MEM_SIZE_FLASH:=$default_flash_sz}
|
|
: ${MEM_SIZE_CCRAM:=$default_ccm_sz}
|
|
: ${MEM_SIZE_SRAM1:=$default_ram1_sz}
|
|
: ${MEM_SIZE_SRAM2:=$default_ram2_sz}
|
|
: ${MEM_SIZE_SRAM3:=$default_ram3_sz}
|
|
: ${MEM_SIZE_PSRAM1:=0}
|
|
: ${MEM_SIZE_SDRAM1:=0}
|
|
: ${MEM_SIZE_SDRAM2:=0}
|
|
|
|
# -- prompt for elf file if not on command line
|
|
if [[ -z "$@" ]] ; then
|
|
read -p "Elf file(s): " ELF_FILES
|
|
else
|
|
ELF_FILES=$@
|
|
fi
|
|
|
|
# -- Set arrays for awk script. The segments should be in increasing address order.
|
|
names=("Flash" "CCRAM" "SRAM1" "SRAM2" "SRAM3" "PSRAM1" "SDRAM1" "SDRAM2")
|
|
addrs=(${MEM_START_FLASH} ${MEM_START_CCRAM} ${MEM_START_SRAM1} ${MEM_START_SRAM2} ${MEM_START_SRAM3} \
|
|
${MEM_START_PSRAM1} ${MEM_START_SDRAM1} ${MEM_START_SDRAM2})
|
|
sizes=(${MEM_SIZE_FLASH} ${MEM_SIZE_CCRAM} ${MEM_SIZE_SRAM1} ${MEM_SIZE_SRAM2} ${MEM_SIZE_SRAM3} \
|
|
${MEM_SIZE_PSRAM1} ${MEM_SIZE_SDRAM1} ${MEM_SIZE_SDRAM2})
|
|
|
|
base_dir="$(dirname "$BASH_SOURCE")"
|
|
base_dir="${base_dir%%[[:space:]]}" # sometimes we get trailing \n
|
|
|
|
# -- run the ARM size command for each elf file and send output to awk script
|
|
all_output=""
|
|
file_cnt=0
|
|
for elf in "$@"; do
|
|
if [[ ! -f "$elf" ]] ; then
|
|
echo "ELF file \"$elf\" not found."
|
|
continue
|
|
fi
|
|
#${SIZE} -A -x ${elf}
|
|
escelf="${elf//\\//}"
|
|
output=`${SIZE} -A -x ${elf} | ${AWKCMD} "${base_dir}/elf-size-report.awk" \
|
|
-v mcu="${MCU}" \
|
|
-v elf="${escelf}" \
|
|
-v skip_data=${skip_data} \
|
|
-v names="${names[*]}" \
|
|
-v addrs="${addrs[*]}" \
|
|
-v sizes="${sizes[*]}"`
|
|
if (( compare != 1 )) ; then
|
|
echo "$output"
|
|
echo
|
|
fi
|
|
file_cnt+=1
|
|
all_output+="${output}\n"
|
|
done
|
|
# -- if more than one elf file was given, also run a comparison report
|
|
if (( file_cnt > 1 && compare )) ; then
|
|
echo "$all_output" | ${AWKCMD} "${base_dir}/elf-size-compare.awk"
|
|
fi
|
|
|