CH32V003F4P6の開発環境としては、MounRiverStudioが用意されています。
コンパイラ/アセンブラ/リンカについてはGCC環境が用意されています。
今回は、リンカ設定を確認していきたいと思います。
正直、リンカ設定は分からないことも多いですが、組み込みソフトウェアでは必須だと思いますので、頑張って読み進めましょう。
サンプルソフトにあるリンカを見ていきます(サンプルの場所など紹介).
GCCのリンカ設定ファイルは、拡張子.ldを使う事が多いです。MounRiverStudioでサンプルを開くと、Link.ldというファイルがあります。これがリンカ設定ファイルです。
このLink.ldを上の方からすこしずつ確認していきます。
こちらでは、ENTRYでリセット直後に実行される関数(ラベル)を指定しています。
リンカはこの_startからプログラムを追いかけて、実行ファイルを作成していきますので、正しく設定する必要があります。
スタックサイズを256バイトで指定しています。Provideはユーザコードなどでこの_stack_sizeが指定された場合にはそちらを使い、ユーザコードでの指定が無い場合には__stack_size(256です)が使用されます。
MEMORYは今回のリンクで使用するメモリ領域を指定しています。
FLASHは0x0000_0000から16KB, RAMは0x2000_0000から2KB領域で定義されています。
FLASHはrxの指定がありますが、readと実行が出来る領域として定義されています。
RAMはxrwの指定で、readとwriteと実行が出来る領域として定義されています。
次からがSECTION定義になり、実際のプログラムの配置を決定しています。
セクションごとに配置する領域をしていく事になります。
セクションはユーザコードまたはライブラリで指定しているセクションは入力セクションと呼びます。それに対して、出力する実行形式に対しては出力セクションと呼びます。ここが混乱しやすいので注意ください。
.initセクションとは何か?というと、通常は初期化に関するコードが配置されています。
この配置の結果はMAPで見る事が出来ます。スタートアップコード_startが配置されています(これは、ENTRYで指定されたものですね)。アドレスも0x0000_0000に配置されていますので、リセット直後はここからスタートすることも分かります。
続いてLink.ldを見ていきましょう。出力セクション.textが一般的なコードを配置するセクションとなります。記述は.initと同じなのでそんなに難しくないですね。
その中で入力セクションで.text/.text.*がコード、.rodataや.rodata*が定数などのReadonlyデータとなります。
続いて.finiがありますが、これはプログラムが終了処理に実行される命令が配置されます。
ここもMAPファイルで結果を確認してみましょう。全部だと大きいので初めの方をまず見てみます。右側は切れていますが、.textではファイルごとにどの関数をどのアドレスに配置するのか?が記載されています。LDファイルで.text.*とあったところには、割込みハンドラなどの入力セクションを持ったコードが配置されています。
すすんで、MAPファイルの出力セクション.finiのところを見ると、配置するものが無かったことが分かります。
リンカ設定ファイルで.dataと.bssの領域を見てみます。
出力セクション.dataに配置するセクション指定などがあり、最後に>RAM AT >FLASHという記載があります。
まず、.dataは初期化データ付きの変数となります。そのため変数はRAMに配置するのですが、
初期化データをFLASHに配置します。それが>RAM AT >FLASHの意味となります。
.bssも同様の指定ですが、.bssはゼロ初期化変数なので、初期化データは不要となります。
ここもMAPファイルを見てみます。変数やテーブルなどが配置されると
RAMとFLASHに配置されていきます。
最後にスタックの部分を見てみましょう。スタックは入力されるセクションがないです。単純に領域を確保するだけなので、メモリの後ろ側から__statck_size戻した部分に配置をしています。
これもMAPファイルを見ておきましょう。0x2000_0700から0x2000_0800の領域がスタックになったとわかります。
リンカ設定はあまりなれていない人も多いかもしれませんが、
まずはこうしたサンプルを見ながら勉強を進めると理解がしやすいと思います。