※当サイトではアフィリエイト広告を利用しています

プログラミング

【初心者向け解説】セクションとリンカスクリプトの役割について

section-and-linker_thumbnail

  • 現場のコードでたまに「__attribute__((section(".my_code")))」「#pragma section "my_code" text」という記述を見るけど、これは一体どんなことをやっているの?
  • セクションは変数やプログラムコードをROM/RAMのどこに配置するかを決めるものらしいけど、何のために配置を決めるの?
  • セクションと併せてリンカスクリプトというものも編集しなくてはいけないらしいけど、これは何をするためのもの?

 これらの疑問に回答します。

 セクションやリンカスクリプトはマイコン制御を行う上では必須の設定になるものの、こちらを解説した書籍やネット記事は驚くほど数がありません。僕自身何度かここの設定をしたことがありますが、それもあくまでコーディングルールに沿って機械的に実施したのみで、中身の機能についてはよく理解していませんでした。

 現在であれば僕も中身については理解していますので、初心者でも分かるようにこの記事で解説していきたいと思います。

セクションとは?

マイコンのプログラムを書く際に、「セクション」という概念がよく出てきます。これは、プログラムのデータやコードを特定のメモリ領域に配置する仕組みのことを指します。

 

セクションとは?

C言語のプログラムをコンパイルすると、コードやデータはROMやRAMの決められた領域に格納されます。この配置を管理するために、セクション(section)という仕組みが使われます。

例えば、以下のように分けられます。

  • .text セクション:プログラムの実行コード(関数の処理)を格納
  • .data セクション:初期値を持つ変数(グローバル変数など)を格納
  • .bss セクション:初期値を持たない変数を格納
  • .rodata セクション:変更されないデータ(定数など)を格納

section-and-linker_01

 

各セクションの役割

セクション名 内容
.text プログラムの実行コード void func() { /* 何かの処理 */ }
.data 初期値を持つ変数 int x = 10;
.bss 初期値なしの変数 int y;(デフォルトで0になる)
.rodata 読み取り専用データ const char msg[] = "Hello";

 

セクションを明示的に指定する方法

 組み込み開発では、特定の変数を特定のメモリ領域に配置したいことがあります。その場合、セクションを指定することができます。

 例えば、__attribute__(GCCコンパイラ)や#pragma(ルネサス系コンパイラ)を使うと、以下のように特定のセクションに変数を配置できます。またセクションについては自作することも可能です。(セクションを自作した場合は後述するリンカスクリプトでの追記が必要になります)

 これにより、special_var は .my_section という特別なセクションに配置されます。

 

 なぜセクションを使うのか?

 あるべきデータをあるべきメモリに配置することでプログラムを正しく動作させるためにセクションは使われるのですが、最近は特にセクションを指定していいなくてもコンパイラ側が自動で判断して最適な位置に配置してくれるそうです。

 そしてもうひとつセクションを使う目的としては「どのコンポーネントがどれだけROM/RAMを使用しているか一発で分かるようになる」というメリットがあります。

 先ほどセクションは自作することが可能と言いましたが、特定のコンポーネントのROM/RAMを特定のセクションに配置しておくとあとからコンパイルツールを使えばセクションごとのメモリ使用量が一覧で見えるようになります。

 

リンカスクリプトファイルについて

 簡単に言うと、
 「コンパイルしてできたプログラムを、マイコンのどこに置くかを指示する設計図」
 です。

 

リンカスクリプトがやること

 リンカスクリプトファイルは「***.ld」という拡張子で表され、中身は以下のようになっています。

 

MEMORY/SECTIONブロックでやることについて

・MEMORYブロック

 →マイコンが持つ物理メモリの範囲を定義。 ROMは512KB、RAMは128KB、など

・SECTIONブロック

 →プログラムやデータをどこに置くか決める。 .textはROM、.dataと.bssはRAM

 

自作のセクションをリンカスクリプトファイルに追加する方法

 先ほどセクションのお話で「.my_section」という領域を作成する例を挙げました。
 この場合のリンカスクリプトファイルの修正の仕方を下記に示します。

 14~16行目が追加されたところですね。

 実質は.dataと同じ扱いなので、こちらを真似して.my_sectionを追加すればOKです。

 

セクション定義をしていると出来ること

 セクションを定義していると、そこで定義している変数だけ定周期で値をインクリメントするということも可能です。
 ですのでカウンタ変数だけ特定のセクションに配置してしまえば、そこに配置されている変数は勝手にカウントアップという動作も出来るのです。

 

 以上が「セクション」と「リンカスクリプト」の解説でした。

 コンパイラが関わってくるところはなかなか書籍でもネット記事でも解説がされていないので、本記事でみなさんの理解が深まれば良いなと思います!



-プログラミング
-

© 2025 名古屋とエンジニアリング