STM32CubeIDEでスタートアップの挙動を確認する

  • 2020.03.28
  • IDE
STM32CubeIDEでスタートアップの挙動を確認する

今回はIDEでスタートアップの処理を追いながらメモリーにアクセスする方法等を見てみます。

投稿時の開発環境を記しておきます。

PC:Windows10 OS
IDE: STM32CubeIDE Version1.3.0
Board: STM32Nucleo-F401RE

IDEで何かプロジェクトを立ち上げておいて、スタートアップの処理を見てみます。
ここでは以前つくったF401mbedBaseのプロジェクトを使ってみます。

データシートを見ると、このマイコンのメモリマップは以下のようになっています。

Flash: 0x8000000 – 0x807FFFF
SRAM: 0x20000000 – 0x20017FFF

これを頭の片隅に入れておいてください。

Project Explorer で F401mbedBase/Core/Startup/startup_stm32f401retx.s をダブルクリックして開きます。
これはアセンブラのソースファイルです。

77行目に Reset_Handler:
78行目に ldr sp, = estack

と書かれていますので、78行目にブレークポイントを貼って、Debugを開始します。
Run – Resume すると 81行目で止まりました。
78行目では止まってくれないようです。78行目にブレークポイントを貼ると78行目の命令を実行し終えたところで止まりました。
78行目はスタックポインタというレジスタ sp にスタックの値を代入しています。

ここで Window – Show View – Registers を選択します。
> General Registers の > をクリックして展開します。

ここで sp の値(Value)を見ると 0x20018000 となっています。
最初に sp には RAMの最後 + 1 番地の値をセットするのでメモリーマップと一致していることがわかります。
もし10進数で表示されていたら value のあたりを右クリックして Number Format – Hex とすれば16進数で表示することができます。
また pc の値を見ると 0x8005084 となっています。

pcはプログラムカウンタというレジスタでプログラムを実行するアドレスが入っています。

ここで Window – Show View – Disassembly を選択します。
これで逆アセンブルされたコードを見ることができます。

今の場合は、元々アセンブラのコードが書かれている場所だったので movs r1,#0 の部分はそのまま表示されています。

ただし、その左側にアドレスも表示されるようになります。

08005084: movs r1,#0

となっていて、pcの値とアドレスが一致していることがわかります。
ここでプログラムが停止しているからですね。

その少し上に

Reset_Handler:
08005080:
と書かれています。

ここで Window – Show View – Memory Browser を選択し コンボボックスに 0x8000000 を入力します。
Memory Browser は指定したアドレスの内容を確認することができます。

これは最初に出てきた Flash Memory の先頭番地になります。
プログラムはここから動きます。

回路図を見ると BOOT0端子が GND にプルダウンされています。

そしてリファレンスマニュアル(RM0368)には以下の表が記載されています。

以上のことから、このマイコンは 0x8000000 番地から動き始めることがわかります。

回路を設計する場合には、ほとんどの場合 Boot0端子は GND に接続するのでしょう。
回路図では抵抗でプルダウンしてコネクタとつないでいますが、GPIOポートにつないでおいて操作する方法もありそうです。
ちょっと脱線しました。

ARM Coretex-M ではこのフラッシュの先頭番地から

最初の4バイトがスタックの初期値、その次の4バイトにリセットハンドラが置かれる仕様です。

少し話がそれたので、Memory Browser の方を見てみましょう。

0x08000000 20018000 08000581 … となっています。

20018000 は sp に設定する値です。
そして 08000581 がリセットハンドラの値です。
あれ、ちょっと待ってください。先ほどの

Reset_Handler:
08005080:

とはアドレスが 1つずれています。これは何でしょうか。

難しい話は他に譲るとして概略だけお話します。
ARMマイコンはARM命令とThumb命令があります。
ARMは32ビットの命令長なのですが、そんなに必要ないこともあり16ビット長で扱える命令が増えました。それがThumbです。
この最下位ビットは分岐先のコードがどちらの命令なのかを判断するためにあるようです。
ですから実質的にアドレスとしての最下位ビットは0と考えておけば良いでしょう。

こちら を参考にさせて頂きました。

命令の覚え方は簡単です。
Thumb(親指)はARM(腕)の半分にも満たない。誰が名付けたの(笑)
またまた脱線してしまいました。

そんなわけでスタックの初期値をスタックポインタにセットした後にReset_Handlerから処理が始まります。
アセンブラのソースファイルのもう少し下の方を見ると bl main が見つかります。
bl は分岐命令です。ここから main() が始まるわけですね。

おさらいです。
Disassembly では逆アセンブルしたコードを確認することができ、アドレスの確認もできます。
Memory Browser では指定したアドレスの内容を確認することができます。

Memory Browser は見るだけですが、Memory Window では指定したRAMのアドレスの値を書き換えることもできます。
いろいろと試してみてはいかがでしょうか。

IDEカテゴリの最新記事