web-dev-qa-db-ja.com

Cプロジェクトでの.sファイルの役割は何ですか?

ARM Cortex M3チップ(STM32F2))を使用しており、STは「標準ペリフェラルライブラリ」を提供しています。これには、いくつかの便利な.cファイルと.hファイルがあります。また、.sファイルも含まれています。

Cプロジェクトのコンテキストでこれらの.sファイルの目的は何ですか?コンパイラ/リンカー/を入手するにはどうすればよいですか?それらを考慮に入れますか?

23
Randomblue

.s拡張子は、GNUおよびその他の多くのアセンブラファイルのツールチェーンで使用される規則です。

最後に、STM32標準ペリフェラルライブラリ自体にはアセンブラファイルが含まれていませんが、CMSISライブラリにはさまざまなSTM32パーツのスタートアップコードが含まれています。たとえば、startup_stm32f2xx.sはすべてのSTM32F2xxシリーズデバイスのスタートアップコードです。ツールチェーンごとに異なる実装があります。特定のパーツとツールチェーンに関連付けられたファイルをビルドしてリンクする必要があります。ビルドして実行するサンプルプロジェクト、またはIDEがパーツ固有のプロジェクトを作成するプロジェクトを使用している場合、これはおそらくすでに行われています-実行するコードがある場合は確かにそうです。

コードをビルドしてリンクする方法は、使用しているツールチェーンによって異なります。ほとんどのIDEベースのツールは、拡張子を自動的に認識し、アセンブラを呼び出して、他のようにリンクされるオブジェクトファイルを生成します。正確な内容は、ツールチェーンのバージョン間でわずかに異なりますが、主にCランタイム環境(スタックおよびヒープ)、プロセッサーを初期化し、初期割り込み/例外ベクターテーブルを定義し、静的データを初期化して、main()にジャンプします。

たとえば、Keil/ARM RealViewバージョンのファイルのコアは次のようになります。

_; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP
_

_Reset_Handler_は、プロセッサのリセット後にプログラムカウンタ(PC)レジスタが設定されるアドレスです。

SystemInitは、初期化の大部分を実行する外部Cコード関数です。ハードウェアのカスタマイズが必要になる場合があります。 Cortex-Mは、ベクトルテーブルにリセットアドレスと初期スタックポインタアドレスの両方が含まれているため、リセット直後にCコードの実行を開始できるという点で異常です。これは、SPレジスタに自動的にロードされますその結果、1つを実行するためにアセンブラの知識はあまり必要ありません。

__main()は、コンパイラが提供するCコードのエントリポイントです。これはあなたが書くmain()関数ではありませんが、 `main() '関数を呼び出す前に、標準ライブラリ、静的データ、ヒープの初期化を実行します。

GCCバージョンは、Keil/ARM RealViewバージョンの__main()によって行われる作業の多くを行うため、多少複雑ですが、基本的に同じ機能を実行します。

CMSISでは、SystemInit()はsystem_stm32f2xx.cで定義されており、ボードのカスタマイズが必要な場合があります(正しい水晶周波数、PLL設定、外部SRAM構成など)。これはCコードであり、よくコメントされているので、おそらくより快適になります。

35
Clifford

通常、アセンブリコードが含まれています。アセンブラはそれらをオブジェクトファイルに変換し、後でリンカによって主要なものとリンクされます。しかし、コンパイラ、ツールチェーンなどに依存すると思います。

8
cnicutar

通常、.sファイルにはベクターテーブルが含まれています。割り込みが発生したときにシステムが行うべきことを定義します。このテーブル(コード)は、リンカーファイルでユーザーが定義したメモリアドレスに配置されます。たとえば、リセットが発生するたびに、プロセッサが何から、またはどこから開始するか、どのコードを実行するかなどです。同様に、他のハンドラー(割り込みベクトル)があります。 STM32では、通常、コントローラーは特定のハンドラーでループします。以下の例に示すように: 詳細な説明についてはこのリンクを参照してください

    .section INTERRUPT_VECTOR, "x"
    .global _Reset
    _Reset:
      B Reset_Handler /* Reset */
      B . /* Undefined */
      B . /* SWI */
      B . /* Prefetch Abort */
      B . /* Data Abort */
      B . /* reserved */
      B . /* IRQ */
      B . /* FIQ */

    Reset_Handler:
      LDR sp, =stack_top
      BL c_entry
      B .

このアセンブリコードは後でオブジェクトファイルに変換され、.cファイルおよび.ldとリンクされて、.elfファイルまたは.binファイルが作成されます。

2
Chandrika Joshi

おそらく、STキット用のKeilベースの開発環境があるはずです。コンパイラのバージョンに応じて、プロジェクトファイルには、C、C++、およびアセンブラコード用の異なるセクションが必要です。 IDEでプロジェクトを開き、「プロジェクトのプロパティ」などを探します。

アセンブラコードとの間でシンボルをインポートおよびエクスポートして、シンボルとC/C++コードをリンクさせることができます。 Keilを使用すると、すべてが適切に統合されます。

EXPORTディレクティブは、C/C++コードがリンクできるように、指定されたシンボルをパブリックにするようにアセンブラーに指示します。

IMPORTディレクティブは、指定されたシンボルが他の場所で定義されており、リンク時に解決されることをアセンブラに通知します。

1
Craig Mc