Blackfin - ライブラリとメモリ超過

投稿 2015/04/12 | Blackfin | hotall


私が学生だった頃、マイコンのメモリはKbyte単位でした。
この時代では、常にプログラムサイズを意識しながらのプログラミングです。

使用言語は高級言語もありましたが、アセンブラがメインですから、ソースコードの行数で大体のサイズがわかるので、そろそろ危ないのではないかと、ヒヤヒヤしながらコードを追加していました。

あれから、月日が経ち、汎用パソコンのプログラミンばかりを手がけていると、メモリサイズがMbyte、Gbyteとなるにつれ、プログラムサイズへの関心は薄れていきました。

実際、過去には作成したプログラムのリファクタリングで、プログラムサイズを削減するのに多くの時間を費やしていました。しかし、現在ではパフォーマンスのチューニングはあっても、プログラムサイズそのものの調整はほどんどありません。

私がBlackfinの調査の一環として雛形プログラムを作成を進めていた時、それはやってきました。

VisualDSP++にはメーカが提供するライブラリがあります。
各機能を抽象化し、内部レジスタを意識することなくプログラミングできることは、作業効率を高めるだけでなく、ハードウェアが持つ振る舞いの癖などに悩まされず済みます。この分野には「おまじない」というコードが存在するのも実装の困難さを象徴しています。
ですから、メーカーが提供するライブラリを極力使うのは自然な流れです。

今回も、この方針で雛形プログラムを作成していました。
割込み管理、遅延コールバック、電源管理、DMA管理、タイマー管理・・・と機能を増やしながら逐次コンパイル・テストを行い、順調に作業は進んでいましたが、ある時、コンパイラが文法エラー以外のエラーを吐きました。
[Error li1040]:Out of memory in output section 'L1_code' in processor 'p0'
Total of 0x1924 word(s) were not mapped.
メモリ超過です。

ツールのメモリマップウィンドウでLDFファイルをダブルクリックすると詳細が表示されます。
L1_code区画が赤く表示されています。これを更にダブルクリックすると、包含モジュールの一覧が表示されます。
すると使用領域がはみ出しているのが分かります。一番大きなモジュールがlibc532y.dlbで、L1_code領域をほとんど埋めています。
左のInput Sections画面からこのライブラリモジュールを展開表示すると、かなり多くの関数群が含まれているのがわかります。
試しに電源管理の使用をやめると、エラーはなくなりました。

更に詳細を調べるため、メモリマップリストを作成します。
[プロジェクトオプション]-[Link]-[General]-[AdditionalOutput]-[Generate symbol map]をチェックするとmap.xmlファイルが出力されます。
出力された<プロジェクト名>.map.xmlファイルの<MEMORY>要素にファイルのメモリ使用量が記述されています。
<OUTPUT_SECTION name='L1_code' id='033CC810' memory_id='02A89B00' type='SHT_PROGBITS' 
start_address='0xffa00000' word_size='0x7274' word_size_unmapped='0x1924'
word_size_reserved='0x0' >
<MEMORY id='02B99ED0' name='MEM_L1_CODE' start_address='0xffa00000'
end_address='0xffa07fff' type='' qualifier='RAM' width='0x8' words_used='0x7274'
words_unused='0xd8c' >
使用が0x7274で未使用が0xd8cということは残り10%です。
このライブラリを使用すると、ユーザーが使用できる領域はほんの僅かということです。
ADSP-BF59Xのメモリマップ上、プログラムコードが使用できるのは0xFFA00000-0xFFA07FFFまでの32KBYTEしかありません。

サービス別のオブジェクトサイズは次の通りです。
サービスのコードサイズ(%=x/32768)
遅延コールバック:libssl592-ay.dlb[adi_dcb.doj:2202(6.7%)
DMA管理:libssl592-ay.dlb[adi_dma.doj:8628(26.3%)
フラグ入出力:libssl592-ay.dlb[adi_flag.doj:2464(7.5%)
割込み管理:libssl592-ay.dlb[adi_int.doj:2028(6.2%)
割込み管理:libssl592-ay.dlb[adi_int_asm.doj:1824(5.6%)
ポート入出力:libssl592-ay.dlb[adi_ports.doj:698(2.1%)
電源管理:libssl592-ay.dlb[adi_pwr.doj:6132(18.7%)
電源管理:libssl592-ay.dlb[adi_pwr_asm.doj:192(0.6%)
タイマー管理:libssl592-ay.dlb[adi_tmr.doj:3482(10.6%)

試しに今度はReleaseモードでコンパイルしてみました
<MSG id='034042C0' mid='li3201' type='Informational' suppressed=''>
<TEXT><![CDATA[Successfully eliminated 16036 bytes in processor 'p0']]></TEXT>
16Kbyteに縮小されました。
しかし、Debugモードが使えない開発は開発効率上、現実的ではありません。

ここで疑問が湧きます。サンプルプログラムにはすべての機能を網羅したPower_On_Self_Testがあります。これは一体どうなっているのでしょう。
因みにこのプログラムをコンパイルして、サイズを調べてみます。
debugモード:0x6542(25922byte)
残り=32768-25922=6846(21%)

メモリは残り2割を残して、収まっています。
それでも残り2割とは。ここにアプリケーションを収めるには厳しいと感じざるを得ません。
しかも、中を調べてみると、ライブラリはほとんど使っておらず、ほぼスクラッチでコーディングされています。

ここで、私はようやく気づきました。このメモリサイズではライブラリは使えないと。
Blackfinは外部メモリを拡張できますが、今回はオンチップメモリ上で動作さなければならない制約があります。
ここに多くの機能を実装する今回の仕様では、ライブラリの使用を断念せざるを得なくなりました。

« Prev • Next »

コメント

コメントはありません。

コメントする