STM32F2:商用IDEを使用しないMakefile、リンカースクリプト、起動ファイルの組み合わせ


16

私はSTM32F2で働いている(具体的には、開発ボード上のSTM32F217IGH6)約2ヶ月間。はるかに私の最大の問題はメイクファイル、リンカスクリプトと起動ファイルを含む「セットアップ」、としなければなりませんでした。

特に、割り込みベクターテーブルを適切に設定できず、割り込みハンドラーを呼び出すことができませんでした。STは、商用IDEに合わせた例を提供しています。代わりに、私は(JTAG経由で画像をロードし、OpenOCD)GCCツールチェーンの自由YAGARTOの再コンパイルを使用しています。

呼び出される割り込みハンドラ用に設定されている非商用のIDEに適したメイクファイル、リンカスクリプトと起動ファイルの組み合わせを含むが例の私のボードのためのプロジェクト(またはそれの近いいとこ)がありますか?


2
Cortex M3の例を探す必要があります。正確なボードとプロセッサは、求めるものにとってそれほど重要ではありません。おそらく、リンカスクリプトのメモリレイアウトとメイクファイルのフラッシュ方法を変更する必要がありますが、それですべてです。
スターブルー

1
これらすべてをgitリポジトリに入れて、githubなどに配置できますか?
AngryEE

1
これが、私が試してすぐにSTMの使用をやめた理由です。彼らは厄介なツールチェーンとの私の生活を困難にするつもりなら、私はどこか別の場所に行きますよ。PSoC3とPSoC5のIDEを試したとき、それは違いの世界でした。
Rocketmagnet

あなたはYAGARTOにコミットしていますか?それは完全に罰金だと偉大な質問になりますが、私は精通していCodeSourceryのライトツールチェーン。別のツールチェーンのための答えは、おそらく適合させることができるが、アウト・オブ・ボックス機能しません。
ケビンフェルメール

回答:


20

http://github.com/dwelch67

特にstm32f4とstm32vldがありますが、他のものも役に立つかもしれません。mbedおよびmbedの下のmzeroディレクトリ(cortex-m0)。

シンプルで愚かなアプローチ、最小限のリンカスクリプト、最小限の起動コードなどを維持するのが好きです。特定のツールチェーンではなく、コードによって作業が行われます。

私は、ライブラリの呼び出しのためのリソースとしてではないコンパイルするコンパイラを使用して(親指が可能)gccとbinutilsののほとんどの形態はこれらの例により多少動作しますが、私は株式リンカスクリプトを使用してはいけない、などの古いgccとbinutilsの約知ることができません新しいthumb2パーツは、いくつかの変更が必要になる場合があります。

私は独自のgcc、binutils、llvm / clangを構築し、たとえばcodesourceryを使用します(現在はメンターグラフィックスですが、free / liteバージョンを入手できます)。

新しいターゲットのために一緒にプロジェクトを入れ始めたときにESPのあなたは、いくつかの解体を行う必要があります。特に、あなたがそれらを配置したい場所を確認してくださいアイテムは、例えば、ベクタテーブルあるようにします。

例えばstm32f4d / blinker02を見てください。これは、例外/ベクタテーブルに加えて、いくつかのASMサポートルーチンvectors.sで始まります。

/* vectors.s */
.cpu cortex-m3
.thumb

.word   0x20002000  /* stack top address */
.word   _start      /* 1 Reset */
.word   hang        /* 2 NMI */
.word   hang        /* 3 HardFault */
.word   hang        /* 4 MemManage */
.word   hang        /* 5 BusFault */
.word   hang        /* 6 UsageFault */
.word   hang        /* 7 RESERVED */
.word   hang        /* 8 RESERVED */
.word   hang        /* 9 RESERVED*/
.word   hang        /* 10 RESERVED */
.word   hang        /* 11 SVCall */
.word   hang        /* 12 Debug Monitor */
.word   hang        /* 13 RESERVED */
.word   hang        /* 14 PendSV */
.word   hang        /* 15 SysTick */
.word   hang        /* 16 External Interrupt(0) */
.word   hang        /* 17 External Interrupt(1) */
.word   hang        /* 18 External Interrupt(2) */
.word   hang        /* 19 ...   */

.thumb_func
.global _start
_start:
    /*ldr r0,stacktop */
    /*mov sp,r0*/
    bl notmain
    b hang

.thumb_func
hang:   b .

/*.align
stacktop: .word 0x20001000*/

;@-----------------------
.thumb_func
.globl PUT16
PUT16:
    strh r1,[r0]
    bx lr
;@-----------------------
.thumb_func
.globl PUT32
PUT32:
    str r1,[r0]
    bx lr
;@-----------------------
.thumb_func
.globl GET32
GET32:
    ldr r0,[r0]
    bx lr
;@-----------------------
.thumb_func
.globl GET16
GET16:
    ldrh r0,[r0]
    bx lr

.end

この例には、割り込みが、あなたが必要とする他のものはここにはありません。

blinker02.cには、mainの呼び出しを回避するためにnotmain()を呼び出すCエントリポイントを持つCコードの本体が含まれています(main()がある場合、一部のコンパイラはバイナリにジャンクを追加します)。

あなたにカット&ペーストを惜しまます。メイクファイルは、コンパイルとリンクについての物語です。私の例の数は同じコードから二つ以上のバイナリをコンパイルすることに注意してください。GCCコンパイラ、LLVMのコンパイラ打ち鳴らす、親指のみとthumb2、異なる最適化など

ソースファイルからオブジェクトファイルを作ることから始めます。

vectors.o : vectors.s
    $(ARMGNU)-as vectors.s -o vectors.o

blinker02.gcc.thumb.o : blinker02.c
    $(ARMGNU)-gcc $(COPS) -mthumb -c blinker02.c -o blinker02.gcc.thumb.o

blinker02.gcc.thumb2.o : blinker02.c
    $(ARMGNU)-gcc $(COPS) -mthumb -mcpu=cortex-m3 -march=armv7-m -c blinker02.c -o blinker02.gcc.thumb2.o

blinker02.gcc.thumb.bin : memmap vectors.o blinker02.gcc.thumb.o
    $(ARMGNU)-ld -o blinker02.gcc.thumb.elf -T memmap vectors.o blinker02.gcc.thumb.o
    $(ARMGNU)-objdump -D blinker02.gcc.thumb.elf > blinker02.gcc.thumb.list
    $(ARMGNU)-objcopy blinker02.gcc.thumb.elf blinker02.gcc.thumb.bin -O binary

blinker02.gcc.thumb2.bin : memmap vectors.o blinker02.gcc.thumb2.o
    $(ARMGNU)-ld -o blinker02.gcc.thumb2.elf -T memmap vectors.o blinker02.gcc.thumb2.o
    $(ARMGNU)-objdump -D blinker02.gcc.thumb2.elf > blinker02.gcc.thumb2.list
    $(ARMGNU)-objcopy blinker02.gcc.thumb2.elf blinker02.gcc.thumb2.bin -O binary

リンカ、ldは、これらのは時々ではない、時には正当な理由のために、非常に痛みを伴うことができ、私はmemmapを呼び出すリンカスクリプトを使用しています。私は少ないが、より多くのすべてのワンサイズフィットへのアプローチは、すべてが、台所の流しのアプローチであることを好みます。

私は通常.dataを使用しません(ほとんどありません)。この例では.bssは必要ありません。そのため、ここにリンカースクリプトがあります。それを使用。

MEMORY
{
    ram : ORIGIN = 0x08000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > ram
}

私は名前について何も特別なあなたは、それだけのセクションにメモリアイテムを結ぶ重要でdoesntのFOOまたはバーやボブやテッドそれを呼び出すことができますラムがあり、それを定義するためのメモリ領域を持っています。セクションは.textセクション、.dataセクション、.bssの、.rodataのように、彼らはメモリマップに行く事を定義します。

あなたはこれをビルドするとき、あなたはこれを見て、私の逆アセンブルすべて(objdumpの-D)を参照してください

Disassembly of section .text:

08000000 <_start-0x50>:
 8000000:       20002000        andcs   r2, r0, r0
 8000004:       08000051        stmdaeq r0, {r0, r4, r6}
 8000008:       08000057        stmdaeq r0, {r0, r1, r2, r4, r6}
 800000c:       08000057        stmdaeq r0, {r0, r1, r2, r4, r6}
 8000010:       08000057        stmdaeq r0, {r0, r1, r2, r4, r6}

注意すべき重要な点は、左側のアドレスが目的の場所であり、vectors.sコードがバイナリの最初にあることです(リンカーコマンドで項目を表示しない限り、ldコマンドラインで最初にあるためです)彼らはldコマンドライン上にあるために、バイナリでアップ)。正常に起動するために、あなたのベクタテーブルが正しい場所にあることを保証しなければなりません。最初の項目は結構です、私のスタックアドレス、です。第2項は_startするアドレスであり、それは奇数でなければなりません。ラベルの前に.thumb_funcを使用すると、これが発生するため、他のい見た目をする必要はありません。

08000050 <_start>:
 8000050:       f000 f822       bl      8000098 <notmain>
 8000054:       e7ff            b.n     8000056 <hang>

08000056 <hang>:
 8000056:       e7fe          

そう0x08000051と0x08000057は_startとハングアップのための適切なベクタエントリです。()notmain通話を開始

08000098 <notmain>:
 8000098:       b510            push    {

ルックスの良いこと(彼らは、解体中奇数番地を示してはいけません)。

すべては順調です。

例blinker05にスキップ、これはサポート割り込みを行います。.bssのが定義されるように、いくつかのラムを必要とします。

MEMORY
{
    rom : ORIGIN = 0x08000000, LENGTH = 0x100000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1C000
}

SECTIONS
{
    .text : { *(.text*) } > rom
    .bss  : { *(.bss*) } > ram
}

覚えているRAMとROMは任意の名前、ボブとテッド、FOOであり、うまくすべての作業をバー。

あなたが完全なものを作る場合のCortex-M3は、(チップ・ベンダーで選択したオプションに応じて、同じコア内に多分コアからコアに変化して)ベクタテーブルに膨大な数のエントリを持っているので、全体vectors.sを表示するつもりはありません関連する部分は解体後に現在地:

08000000 <_start-0x148>:
 8000000:       20020000        andcs   r0, r2, r0
 8000004:       08000149        stmdaeq r0, {r0, r3, r6, r8}
 8000008:       0800014f        stmdaeq r0, {r0, r1, r2, r3, r6, r8}
...
8000104:       0800014f        stmdaeq r0, {r0, r1, r2, r3, r6, r8}
 8000108:       08000179        stmdaeq r0, {r0, r3, r4, r5, r6, r8}
 800010c:       0800014f        stmdaeq r0, {r0, r1, r2, r3, r6, r8}

それがこの1と同じ場所で、必ずしもイマイチする必要があり、非常に多くの割り込みを使用すると、別の割り込みとにかくを探している可能性があり、あなたのチップを搭載した小切手は、ハンドラ正確に適切な場所で、その場所にはいくつかの試行錯誤を要します。皮質-Mプロセッサ、通常の武器とは異なり、あなたは割り込みのために必要なトランポリンコードをいけないので、彼らは、レジスタの一定数を維持し、リンク・レジスタの内容を介してプロセッサモードの切替管理それを作ります。長い間、ハードウェアとコンパイラのABIとして十分に近いそれをすべて作品です。この場合、私はCでのハンドラは、他のプラットフォームと過去とは違って、あなただけの機能を作る(ただし、機能/ハンドラで愚かなことを行ういけない)コンパイラ/構文で何も特別な操作を行う必要性をいけないんでした

//-------------------------------------------------------------------
volatile unsigned int intcounter;
//-------------------------------------------------------------------
// CAREFUL, THIS IS AN INTERRUPT HANDLER
void tim5_handler ( void )
{
    intcounter++;
    PUT32(TIM5BASE+0x10,0x00000000);
}
// CAREFUL, THIS IS AN INTERRUPT HANDLER
//-------------------------------------------------------------------

blinker02の例のようになりますblinker05用のmakefileは、大部分が切断され、これらのほとんどのために貼り付けます。その後、リンクオブジェクトに個々のソースファイルをオンにします。私はgccと打ち鳴らすを使用してthumb2、親指用のビルドを行います。あなただけが持っていけない場合は/ gccの項目が含ま打ち鳴らす(LLVM)が関与したい時にライン:あなたはすべてを変更することができます。私はところで打ち鳴らす出力を組み立てるとリンクするのbinutilsを使用しています。

これらのプロジェクトはすべて無料、既製品、オープンソース、ツールを使用しています。いいえIDEは、コマンドラインのみ、です。はい、WindowsではなくLinuxだけを台無しにしますが、これらのツールはWindowsユーザーも利用できます。rm-fのようなものをmakefileで削除するように変更します。それまたはVMwareやVirtualBoxのか、QEMU上でLinuxを実行します。IDEを使用しないということは、テキストエディタも選択することを意味します。私はそれには入りません。お気に入りがあります。GNUのmakeプログラムの非常に迷惑な機能は、それはメイクファイル内の実際のタブは、私が情熱を持って目に見えないタブを憎む必要なことであることに注意してください。そのため、タブを残すメークファイル用のテキストエディタと、スペースを作成するソースコード用のテキストエディタがあります。私は、窓について知りません

私はそれが正確なチップ/ボードが、この議論のためだけでなくm4にはない立方メートルのCortex-M4、近くには十分ではありません、このことができます願っています。実際のcortex-m3についてはmbedまたはstm32vld dirを参照してください(メイクファイルやブートコードなどのm4との十分な違いはありません)が、stによって作成されません。皮質-M3コアのベンダー間で同じである必要があり、皮質-M3とのCortex-M4は両方ARMv7mであり、近いというよりも異なっています。cortex-m0はARMv6mであり、気になるほどのthumb2命令はほとんどありません。コンパイラはそれに追いついていないので、親指だけを使用します(必要に応じてARMv4T(thumbのみ)のためにビルドしているふりをします)。マイthumbulatorシミュレータは、唯一の無thumb2親指ではありません、それは私が、私はそれが何らかの形または方法で割り込みを実行したと思う、同様にあなたに役に立つかもしれません。


私は答えを読んでいたので、この答えの著者はあなただと思います。あなたの答えは私をたくさん助けたとAVRとPICおたくであることよりも、ARMプロセッサに移動するために私を動機としています。ありがとう
-MaNyYaCk

どういたしまして...お支払いください...
old_timer

2

あなたはそれがコード中のリンカーとlow_level_initの基本を説明しようと、このサイトを見てすることができます。

このページは問題の説明に焦点を合わせているため、nvicベクトルは最小限のものであることに注意してください。

次に、「STM32F2xx標準周辺機器ライブラリ」にさらに完全な例があり、gccセクションを見るだけです(Yagartoはgccベースであるため)。そして、NVIC(割り込みベクタテーブル)の正しいセットアップをお届けしますそこにサンプルコードがあります。

これは完全な答えではない場合でも、だから私はそれが参考にとにかくの一種であると思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.