STM32Cube系ライブラリ移植への道


いうわけでSTマイクロの苦情隔離場でbugという文字が乱舞するいわくつきのSTM32Cube
ライブラリへの移行を順次開始しました!
NUCLEO-F030板
NUCLEO-F401板
NUCLEO-F334板
おしまい。ぁー憑かれた…












すみません冗談です冗談!春先にも少し触れてすでにこれちょっと微妙だと判断を下した
STM32CubeF4をはじめとするCube系ライブラリは今までの"標準ペリフェラルライブラリ"
とは互換性が全くなく、バグも多数報告されていたのでねむいさんも移植に難色を示して
いました。が、最近発売されたNucleo系のボードに搭載された新しいMCUはもはや過去の
ライブラリには未対応となっており、事態を重く見たねむいさんもようやく重い腰を上げた
わけでございます。早く座らせてくれ
(※以下、縮めて"HALライブラリ"と呼称します)


実はここ数か月でHALライブラリへの移行準備自体は着々と進めていて、その第一歩と
して手持ちのNucleo板のプロジェクトのライブラリを一気に移行していました。
現在手持ちは写真のとおり(って見た目同じですが) F030,F401,そしてF334の3つです。
それらのプロジェクトはごくごく基本的な動作のみを網羅した小規模なプログラムに
とどめていたのでまだ難易度は低く、移植の感触をつかむのにはうってつけでした。
私の公開しているプロジェクトは全てこちらの手順に準拠しているので移行後も不自由
なく同じようにビルドできるものを目指しました。

移行にあたってねむいさん的ポリシーは以下の要素に。
1.プロジェクトのディレクトリ構造は従来の物から大きく崩さない
 まぁ鉄則ですね。ケアレスミス防止目的でもあります。
 互換性を重視しすぎて不便になるのも本末転倒なので変えるべきところは変えます。

2.HALライブラリに依存する箇所をなるべく作らない
 これも鉄則ですね〜。またライブラリ大変更されたら目にも当てられないですし。
 抽象化のためにサイズが激増する冗長なコードがやたらと多いので分解・簡略化して
 別途作ったほうがいいです。一方でHALライブラリ使った方が分かりやすい周辺機器
 の初期化の箇所は割り切って利用していきます。
 
 ぇ?それじゃHALライブラリ使ってる意味無いだろですって!?
 無いですよ。

3.STM32CubeMXで生成されたひな形は利用しない
 STM32CubeMXは各開発環境ごとにHCLK/PCLKの初期化コードを含むひな形を自動
 作成するJAVAで作成されたプログラムを指します。ねむいさんの環境はGCCのコマンド
 ラインビルドに属する極めて原始的なものなのでひな形をそのまま利用できません。

 CubeFxのアーカイブにサンプルコードが収録されてるのでCubeMX使わずともそれ見たら
 殆ど事が足ります。おまけに生成されたコードが現状バグだらけでまったく信用出来ない
 ので100000000000000000000歩譲ってHCLKやI2C/I2Sクロック周波数の初期設定に
 軽く参考にする程度です。

4.メモリリソースはなるべくていうか絶対に許さ浪費しない!
 HALライブラリでは抽象化を上げるためインスタンスという概念が追加されています。
 それに付随する構造体が馬鹿でかいサイズなのでF0系ではSRAM領域を圧迫されすごく
 苦しくなります…なるべくグローバル変数で確保はしないように心がけましょう。


上記の点を念頭に入れて再構成したプロジェクトと従来のプロジェクトでビルドした
バイナリファイルのサイズの比較してみました。比較対象基板はF030板のです。
*STM32 StdPeriphDriver(STM32F030R8T6_NUCLEO_20140326.7z)

Built Object Informations:
=== Total Binary Size ===
text data bss dec hex filename
0 7216 0 7216 1c30 main.hex
=== Verbose ELF Size ===
text data bss dec hex filename
7096 120 328 7544 1d78 main.elf


*STM32 HAL Driver(STM32F030R8T6_NUCLEO_20140702.7z)
Built Object Informations:
=== Total Binary Size ===
text data bss dec hex filename
0 7916 0 7916 1eec main.hex
=== Verbose ELF Size ===
text data bss dec hex filename
7796 120 412 8328 2088 main.elf

orz
フラッシュもSRAMも使用領域ががっつり増えてやがるorz

HAL Driverのスタートアップは"__libc_init_array"のリンクがあるのでC++の対応を
すててこれを取っ払ってみました
Built Object Informations:
=== Total Binary Size ===
text data bss dec hex filename
0 7828 0 7828 1e94 main.hex
=== Verbose ELF Size ===
text data bss dec hex filename
7708 120 412 8240 2030 main.elf

焼け石に水orz
SRAMを減らさなければ…

HALのSysTick関数"HAL_GetTick"は_weakで切られていてオミットできるのでやってみた
Built Object Informations:
=== Total Binary Size ===
text data bss dec hex filename
0 7820 0 7820 1e8c main.hex
=== Verbose ELF Size ===
text data bss dec hex filename
7700 120 408 8228 2024 main.elf

フラッシュメモリで8バイト、SRAMは4バイト減りましたが焼け石に(ry

bss領域がインスタンスの確保で100byteも増えやがるのはF0系でかなり痛いんですよね〜。
こいつを追い出してみました。
Built Object Informations:
=== Total Binary Size ===
text data bss dec hex filename
0 7776 0 7776 1e60 main.hex
=== Verbose ELF Size ===
text data bss dec hex filename
7656 120 300 8076 1f8c main.elf

雄々ッッ!!BSS領域が元より減りましたよ♥
もぅいいわこれで…もちろんスリムになってもちゃんと動作してます♥
※最初に取り除いた"__libc_init_array"はC++な人のためにリンクを復活させてリリースしてます。

今回の検証に当ってHALライブラリを使用したexampleの中で構造体の一部の要素が
未設定により起こる不具合がみつかりましたがまぁライブラリ自身の不具合じゃない
のでスルーで…(ねむいさんのプロジェクトでは明示的に初期化してます!)
そして話が冒頭の文章に戻るわけです。



ひとまずNUCLEO系板はすべて移行して最適化完了ですが残るDiscovery系の板のは
どうしようか考え中です。特にSTM32F4のいつものは多数のペリフェラルを使用して
いるので移植は本当に腰据えて一気に攻め上げないとバグを生んでしまいますからね…
しかしいずれは通らなければならない道だと思います。FATFSのSDIOとDMAの処理の
移植が峠になりそうです。

Go to top of page