#!/usr/bin/env ruby

require 'pp'

D = Struct.new(:sec, :size, :name)

target = ARGV.shift

sram = `arm-none-eabi-objdump -t '#{target}'`.chomp.split(/\n/).
	select {|l| /\.bss|\.data/ =~ l }.
	map {|l|
		sec, size0 = *l.split(/\t/)
		size, name = *size0.split(/\s+/) if size0
		D.new(sec, size.to_i(16), name)
	}

total = sram.map {|i| i.size }.reduce {|r,i| r + i}

sram.sort_by {|i|
	i.size
}.each { |i|
	puts "% 3d%% % 10d %s" % [i.size.to_f / total * 100, i.size, i.name]
}

puts "total: %d bytes" % total

こういうのを書いて

$ foo  build/ch.elf

と実行すると

...
  0%        124 SD1
  0%        132 USBD1
  1%        192 dump_buffer
  1%        208 ch_idle_thread_wa
  2%        384 SDU1
  2%        384 rx_buffer
  4%        640 waThread2
  6%        960 waThread1
  7%       1064 impure_data
 10%       1616 measured
 10%       1616 trace_index
 13%       2048 spi_buffer
 30%       4552 current_props
total: 15081 bytes

こういう感じである程度わかる。

  1. トップ
  2. tech
  3. SRAM 使用量のカウント

avstack.pl である程度できる。

avstack.pl の $objdump を適当にアーキテクチャをあわせて変えておく。

my $objdump = "arm-none-eabi-objdump";

このうえで、GCC のコンパイルフラグに -fstack-usage をつける。そうすると .o の同じ名前で .su というファイルができる。

asm から変換されたファイルとかでは .su は作られないので、.su がない .o を除外して、avstack.pl の引数にすべて与える。

$ ./avstack.pl build/obj/Font5x7.o build/obj/adc.o ...
  Func                               Cost    Frame   Height
------------------------------------------------------------------------
> Thread1                             792       20       16
  sweep                               772       84       15
  ui_process                          688       12       14
  ui_process_touch                    676       12       13
  touch_pickup_marker                 664       52       12
  drag_marker                         612       44       11
  ui_process_lever                    608       12       12
  ui_process_normal                   596       28       11
> menu_marker_sel_cb                  580       12       11
...

すると、使用率順に表示してくれる。> マークはどこからもそれが呼ばれていない関数、つまり呼び出し元と思われるもの。

Cost は最大スタック利用量。Frame は該当関数のスタック利用量 (コールコストを含む)。Height は最大コールスタック数。

Height * コールコストが意外とでかい。

  1. トップ
  2. tech
  3. スタック使用量の静的解析