質問
MDK が提供するテンプレートを使用して、外部フラッシュ ダウンロード アルゴリズムを作成します。独自のコードを追加した後、コンパイルすると、リンク中にエラーが発生します。
リンク中…
エラー: L6248E: PI 領域 'PrgData' の sfud.o(.data) は、PI 領域 'PrgCode' の .conststring にアドレス タイプを再配置できません。
解決
int a[ ] = {1,2,3}; などのグローバル配列を使用する場合、主にグローバル変数の使用が原因で発生します。
次のように const を先頭に追加してください: const static int a[ ] = {1,2,3}; グローバル ポインターは使用しないでください。
このリンカ エラーは、「位置に依存しない」コードをビルドしようとすると発生することがあります。次のような小さな例を考えてみましょう。
#include <stdio.h>
char *str = "test";
int main(void)
{
printf ("%s",str);
}
コンパイルしてリンクした場合:
armcc -c -apcs /ropi pi.c
armlink -ropi pi.o
リンカーは次の形式のメッセージを報告します。
Error: L6248E: pi.o(.data) in ABSOLUTE region 'ER_RW' cannot have address/offset type
relocation to .constdata in PI region 'ER_RO'.
上記のコードの場合、コンパイラは文字列「test」へのグローバル ポインタ「str」を生成します。グローバル ポインタ「str」は、.constdata セクション内の文字列「test」のアドレスに初期化する必要があります。ただし、PI システムでは絶対アドレスを使用できないため、ABS32 が (位置に依存しない) .constdata に再配置されるため、リンク ステップは失敗します。
これを解決するには、明示的なポインタを避けるようにコードを書き直す必要があります。考えられる 2 つの方法を以下に示します。
-
- グローバル ポインターの代わりにグローバル配列を使用します。
#include <stdio.h>
const char str[] = "test";
int main(void)
{
printf ("%s",str);
}
-
- グローバル ポインタの代わりにローカル ポインタを使用します。
#include <stdio.h>
int main(void)
{
char *str = "test";
printf ("%s",str);
}
次のような複数の要素を含むリストを使用している場合は、注意してください。
char * list[] = {
"zero", "one", "two"};
配列内の要素ごとに個別のリンク エラーが発生します。この場合、推奨される解決策は次のとおりです。
char list[3][5] = {
"zero", "one", "two"};
印刷命令は(たとえば)次のようになります。
printf("%s", list[1]);
リストの 2 次元配列を宣言する必要があることに注意してください。最初の次元は配列内の要素の数、2 番目の次元は配列内の要素の最大サイズになります。