なぜそんなに過酷なのか、あなたは尋ねます。 まず、何かをうまくマスターするために、基本から始める必要があります。 読者がデバイスの別のスーパープログラムのテキストを入力しているときにキーボードのキーを無造作にクリックしたくはありません。デバイスの動作を理解しているわけではありません。 stm32は、たとえばatmega8-atmega328(arduinoシリーズの最も人気のあるボードにインストールされているマイクロコントローラー)と比較して、はるかに複雑なマイクロコントローラーです。 第二に、私自身はビジネスをゼロから理解したいので、この記事は将来のニュアンスを発見して思い出すためのメモであると言えます。
はい、Linuxで開発を行うことを忘れていました。 例えば、私はArch Linuxを持っています。 ubuntuの場合、必要なユーティリティのインストールプロセスを次のパートで説明します。 Windows、MacOSを試すことができますが、このためには、コンパイルとファームウェアに必要なユーティリティをインストールする方法を自分で理解する必要があります。
最初に行う必要があるのは、stm32f103コントローラーに基づく開発ボードの購入です。 私はこの青い錠剤を持っています:
![画像](https://habrastorage.org/webt/9b/bx/xa/9bbxxaggablvy7ri_xx2_bf77oo.png)
開始するもう1つのことは、st-linkプログラマーです。
![画像](https://habrastorage.org/webt/wn/4r/cb/wn4rcb2hobj2-qu7u1pouzy6v3c.png)
私は青い丸薬ボードとaliexpressのプログラマーを購入し、200ルーブルを支払いました。 すべてのために。
2番目に行うことは、arm GNU GCCのコンパイルキットをダウンロードすることです。
Arch Linuxの場合、gcc-arm-none-eabiパッケージをインストールする必要があります。
yaourt -Syy arm-none-eabi-gcc
次に、同じ名前のst-link2プログラマと連携するst-linkユーティリティが必要です。
yaourt -Syy stlink
それでは、プログラマーを介してボードをコンピューターに接続してみましょう。
プログラマを次の順序で青い錠剤ボードに接続します。
- GNDピン(グランド-グランド、ピン2、いずれか1つ、たとえば4番目)をプログラマワイヤに接続し(いくつかの標準に従うことをお勧めします。グランドには黒または青を使用します)、ボード上のGNDのピンに接続します。
- プログラマのSWCLKピン(クロック-同期)をボードのSWCLKピンに接続します。
- プログラマのSWDIOピン(IO-入力/入力)をボードのSWIOピンに接続します。
- 最後に、プログラマの3.3Vピンをボードの3.3Vピンに接続します。
これまでのところ、すべてが非常に簡単です。 プログラマーをコンピューターのUSBポートに接続し、ターミナルを開いて、システムでデバイスが正常に検出されたことを確認します。
dmesg
![画像](https://habrastorage.org/webt/sx/p-/wl/sxp-wlvdy_cklggtgb9veterkii.png)
同時に、ボード自体で2つのダイオードが点灯します。1つは赤色に点灯し、電源が供給されていることを示し、2つ目の緑色が点滅します。 これはデフォルトのファームウェアで動作します。
では、デモボードの特性を確認しましょう。 これを行うには、ターミナルで、このパッケージの前にインストールされたstlinkからst-infoコマンドを実行します。
![画像](https://habrastorage.org/webt/1u/er/9h/1uer9hz61qo-6fdkikfcexne1ee.png)
選択肢を見ることができます:
--version-st-infoユーティリティの現在のバージョン
--flash-マイクロコントローラのプログラムのフラッシュメモリのサイズに関する情報を表示します。私の場合は0x10000(65536バイト)です。
--sram-静的メモリ容量-0x5000(20480バイト)
--descr-説明-F1中密度デバイス
--pagesize-メモリページサイズ-0x400(1024バイト)
--hla-serial-"\ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x31"
--probe-1人のstlinkプログラマが見つかりました
シリアル:30303030303030303030303031
openocd: "\ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x30 \ x31"
フラッシュ:65536(ページサイズ:1024)
スラム:20480
chipid:0x0410
descr:F1中密度デバイス
私たちにとって重要なのは、フラッシュメモリのサイズと静的メモリのサイズです。また、中密度のデバイスがあることを覚えておく価値があります。
手元のドキュメントなしで開発を開始しないでください。 まず、 公式のリファレンスマニュアルWebサイトからダウンロードします。 周辺機器全体、マイクロコントローラ周辺機器レジスタの完全な説明が含まれています。 次に、同じリンクからプログラマーマニュアルをダウンロードします。 その中で、STM32F10xxx / 20xxx / 21xxx / L1xxxx Cortex-M3コントローラファミリのマイクロプロセッサ、そのアーキテクチャ、および一連のコマンドについて学習します。
次に、マイクロコントローラーでのプログラム実行が一般的にどのように開始するかを分析します。
- スイッチをオンにした直後のマイクロコントローラstm32f103c8は、SPレジスタの値を0x08000000(読みやすくするために、ノートブックをスペースで割る-0x0800 0000)で読み取りを開始します。 SP(スタックポインター)-スタックポインターのレジスタ(p。15プログラマーマニュアル)。 スタックは使用可能なRAMの最後から始まり、大きくなります。
- アドレス0x0800 0004では、値がPCレジスタ-プログラムカウンタに読み込まれます。 この値は、メインプログラムへのエントリポイントのアドレスです。つまり、アドレス0x0800 0004フラッシュ、Cのアドレス、メイン()関数(後で定義します)があります。
- マイクロコントローラーがプログラムを開始します。
初期スタック位置(SPレジスタの値)を計算するには、65ページのリファレンスマニュアルを参照してください。RAMが0x2000 0000から始まることを示しています。マイクロコントローラーのRAM容量は20,480バイトであると以前に判断しました。
0x2000 0000 + 0x5000 = 0x2000 5000
つまり、アドレス0x0800 0000に、値0x2000 5000を配置する必要があります。
0x0800 0004では、プログラムの先頭へのポインターを配置する必要があります。 各ポインターのサイズは4バイトです。つまり、フラッシュメモリ内の0x0800 0004の次のアドレスは0x0800 0004 + 4 = 0x0800 0008になります。この値は0x0800 0004に配置する必要があります。
これは、ファームウェアの最初のセクションのようになります。
+-------------+-------------+ | flash | | +-------------+-------------+ | 0x0800 0000 | 0x2000 5000 | | 0x0800 0004 | 0x0800 0008 | +-------------+-------------+
次に、stm32マイクロコントローラーの1つの機能について説明します。 実際、stm32のコマンド形式は、標準のARMではなくThumb表現にする必要があります。 これは、ポインターを指定するときに、1を追加する必要があることを意味します。このルールを覚えておいてください。
十分な理論がありましたので、練習に移りましょう。 あなたがまだ起きていることを願っています。 お気に入りのコードエディターを開き、コントローラーを起動するための初期ファイルを作成します。 スタートアップファイルから開始し、アセンブラーで記述します。 これは、退屈なアセンブラーで書くことを強制する唯一の時間ですが、あなたは内部からデバイスを理解し、「感じる」ようになります。
私たちは最初に書いています:
@stm32f103
これはアセンブリ言語のコメントで、各コメントは@記号で始まります。
次に、アセンブラディレクティブを指定します
.syntax unified @ stm32 - Thumb! .thumb @ cortex-m3 @( ) .cpu cortex-m3
そして、短いブートストラッププログラム:
@ . !
@.equ
@ define C
@,
.equ StackPointer 0x20005000
@.word - , - 4
@ (0x0800 0000)
@
.word StackPointer
@”” .
@Reset - , .
@ , Thumb,
@
.word Reset + 1
@ Reset. ,
@ ,
@ . B -
@ ARM,
@ JMP x86,
@ goto .
@ B - ,
@ Reset, .
Reset: B Reset
リンクhttps://bit.ly/2rc7bcfからプログラム全体をダウンロードできます。
bootstrap.sとして保存します。
それでは、ボードをコンパイルしてフラッシュしましょう。
まず、ボードからデフォルトのファームウェアをダウンロードする方法を示します。これはLEDで点滅します。 突然いつか便利になります。
繰り返しますが、USBに接続されたボードを持つプログラマーを挿入し、Linuxターミナルでコマンドを実行します。
st-flash read ./default.bin 0x08000000 0x10000
ここでは、アドレス0x08000000から始まり、0x10000(64K)を測定するdefault.binファイルにフラッシュメモリ、つまりすべてのフラッシュメモリを読み込むことを示します。
st-flash-マイクロコントローラーファームウェアを操作するためのユーティリティ。端末で詳細な説明を読んでください:
st-flash --help
その後、ファームウェアが正しくカウントされたことを確認します。 古いものを上書きして、もう一度ダウンロードします。
st-flash write ./default.bin 0x08000000
default.binをアドレス0x08000000から始まるコントローラーのフラッシュメモリに書き込むとはどういう意味ですか。
プログラマを取り外して再挿入すると、ボード上の緑色のダイオードが以前と同様に点滅します。
では、独自のファームウェアをコンパイルしましょう。 保存したディレクトリと同じディレクトリにあるターミナルで、次を実行します。
arm-none-eabi-as -o bootstrap.o bootstrap.s
ここで、ソースファイルをオブジェクトコードにコンパイルします。 これはまだ準備ができていないファームウェアであり、マイクロコントローラーに注ぐのに適しています。 また、プログラムを配置する場所、アドレスを「示す」必要があります。 リンカがこれを行います。 パッケージarm-none-eabi-gccに含まれている最も人気のあるLDリンカーを使用します。 次のパートで、リンカーの詳細とldリンカーのスクリプトの説明について、超単純なファームウェアの自動アセンブリに移ります。 それまでの間、この小さなstm32f103.ldファイルhttps://bit.ly/2HXIyduをダウンロードして、コマンドを実行します。
arm-none-eabi-ld -o main.elf -T stm32f103.ld bootstrap.o
このコマンドでは、stm32f103.ldスクリプトを使用してオブジェクトファイルを作成し、出力はelfファイルです。
最後に、elf実行可能ファイルをフラッシュ用に準備するには、最後のコマンドを実行します。
arm-none-eabi-objcopy main.elf main.bin -O binary
ここで、elfファイルを、ボードへのアップロードに適した純粋なバイナリ形式に変換します。
これで、stm32コントローラーの最初のプログラムの準備ができました! ステッチ!
st-flash write ./main.bin 0x08000000
おめでとうございます! これで、マイクロコントローラーは無条件の遷移を永遠に実行する運命にあります。 またね!