6.7 キーワード
6.7.6 far キーワード
C/C++ コンパイラのデフォルト・アドレス空間は、メモリの下位 64K に制限されて います。すべてのポインタのサイズはデフォルトで 16 ビットです。TMS320C28x は、
16 ビットを超えたアドレッシングをサポートします。C では、コンパイラは far 型 の修飾子を使って C 言語を拡張することで、4 メガワードのデータまでアクセスで きます。far ポインタのサイズは、22 ビットになります。
注: C++ での far のサポート
TMS320C/C++ コンパイラは、C++ では far キーワードをサポートしません。C++ で
far オブジェクトにアクセスするにはラージ・メモリ・モデル・オプションを指定す るか、組み込み関数を使用します。詳細については、6.7.7 項「ラージ・メモリ・モ デルを使用する方法(-ml オプション)」(6-21 ページ)および 6.7.8 項「C++ で far メ モリをアクセスする組み込み関数を使用する方法」(6-22 ページ)を参照してくださ い。
6.7.6.1 セマンティック
オブジェクトを far 宣言することは、そのオブジェクトを far メモリに配置すること を示します。これは、デフォルトの .bss とは異なるセクションにそのオブジェクト 用の空間を確保することで行われます。far 宣言したグローバル変数は、.ebss と呼ば れるセクションに配置されます。このセクションは、TMS320C28x データ・アドレ ス空間の任意の場所にリンク可能です。同様に、far 宣言した const オブジェクトは、
.econst セクションに配置されます。
far オブジェクトを指すように宣言されたポインタのサイズは 22 ビットです。これ らのオブジェクトは、データを格納するために 2 つのメモリ・ロケーションを必要 とし、アドレッシングを実行するために XAR レジスタを必要とします。
注: ポインタの使い分け
far データを指すポインタを宣言する方法(far int *pf;)とポインタ自体を far 宣言す
キーワード
6.7.6.2 構文
コンパイラは、far または __far を同じ意味のキーワードとして認識します。far キー ワードは、修飾子型として機能します。変数宣言時に、far は型修飾子の const と volatile と同様に使われます。例 6-3 に、変数を宣言するための正しい方法を示しま す。
例 6-3. 変数を宣言する方法
int far sym; // sym is located in far memory.
far int sym; // sym is located in far memory.
struct S far s1; // Likewise for structure s1.
int far *ptr; // This declares a pointer that points to a far int.
// The variable ptr is itself near.
int * far ptr; // This declares a pointer to a near int. The variable // ptr, however, is located in far memory.
int far * far ptr; // The pointer and the object it points to are both far.
int far *func(); // Function that returns a pointer to a far int.
int far *memcpy_ff(far void *dest, const far void *src, int count);
// Function that takes two far pointers as arguments // and returns a far pointer.
int *far func() // ERROR: Declares the function as far. Since the // program address space is flat 22-bit, this has no // meaning. Far applies to data only.
int func() {
int far x; // ERROR: Far only applies to global/static variables.
: // Auto variables on the stack are required to be near :
int far *ptr // Ok, since the pointer is on the stack, but points // to far
}
struct S // Declaring structure members as far is meaningless, {
// unless it's a pointer to far. Structure objects int a; // can, of course, be declared far.
int far b;
int far *ptr;
};
キーワード
6.7.6.3 ランタイム・ライブラリによる far のサポート
ランタイム・ライブラリは、ポインタを引数としてもっていたり、値を戻したり、
RTS グローバル変数を参照したりする、ほとんどの RTS 関数の far バージョンを組 み込むように拡張されています。far ヒープを管理するサポート機能もあります。RTS による far のサポートには、C 入出力ルーチンや C 入出力ルーチンを参照するような 関数は組み込まれていません。RTS による far のサポートの詳細は、8.5 節「ランタ イムサポート関数およびマクロのまとめ」(8-31 ページ)を参照してください。
6.7.6.4 far ポインタによる数値計算
ANSI/ISO 規格では、有効なポインタ演算は同じ型のポインタの代入、ポインタと整 数の加算または減算、同一配列のメンバへの 2 つのポインタの減算と比較、ゼロへ の代入および比較であると規定しています。これ以外のすべてのポインタによる演 算は不正なものです。
これらの規則は、far ポインタに適用されます。2 つの far ポインタの減算の結果は、
16 ビット整数型になります。これは、サイズが 64K ワードを超える大きな配列では、
コンパイラはポインタによる減算をサポートしていないことを表しています。
6.7.6.5 far 型の文字列定数
文字列定数を far メモリに配置する方法の詳細は、7.1.8 項「文字列定数」(7-9 ペー ジ)および 7.1.9 項「far 文字列定数」(7-10 ページ)を参照してください。
6.7.6.6 .econst をプログラム・メモリに割り当てる方法
ブート時に .econst セクションをプログラム・メモリからデータ・メモリへコピーす る方法の詳細は、7.1.3 項「.const/.econst をプログラム・メモリに割り当てる方法」
(7-6 ページ)を参照してください。
6.7.7 ラージ・メモリ・モデルを使用する方法(-ml オプション)
キーワード
6.7.7.1 ラージ・メモリ・モデル・オプション
コンパイラに対してラージ・メモリ・モデルを指定するオプションは、-ml です。各 コンパイラ・ツールを別々に起動する場合、次のオプションを使う必要があります。
❏ パーサ: -ml オプション
❏ オプティマイザ: -m オプション
❏ コード・ジェネレータ: -l オプション
❏ アセンブラ: -mf オプション
アセンブラに対する -mf オプションは、ラージ・メモリ・モデルのコードをもつ 16 ビ ッ ト・コ ー ド を 条 件 付 き コ ン パ イ ル で き る よ う に す る た め に 使 わ れ ま す。
LARGE_MODEL シンボルはアセンブラによって事前定義されていて、-mf オプショ ンを指定しない限り自動的に偽に設定されています。
6.7.7.2 ラージ・メモリ・モデルのランタイムサポート・ライブラリ
ランタイムサポート・ライブラリは、条件付きコンパイルを使ってラージ・メモリ・
モデルをサポートしています。ランタイムサポート・ライブラリをコンパイルする
場合、LARGE_MODEL シンボルを定義しておく必要があります。このシンボルは、
size_t 引数を渡したり、またはsize_t 引数を戻したりする任意のランタイムサポート
関数を自分のコードからアクセスする場合に必要です。このシンボルは、ランタイ ムサポート va_arg or offsetof( ) マクロを使用する場合にも必要です。したがって、
ラージ・メモリ・モデルでコンパイルする場合には、-d コンパイラ・オプション( 2-13 ページを参照)を指定して、LARGE_MODEL シンボルを事前に定義してください。
6.7.8 C++ で far メモリをアクセスする組み込み関数を使用する方法
far キーワードが拡張するのは、C 言語だけです。C++ では far キーワードはサポー トされていません。ラージ・メモリ・モデルを使わない場合に、C++ の rts ライブラ リのヒープ管理サポート・ルーチンと組み合わせて C++ で far メモリにアクセスで きるようにするために、組み込み関数が用意されています。組み込み関数は、アド レスを表す長整数型を受け付けます。組み込み関数の戻り値は、基本データ型(word、
long、float、long long、long double)にアクセスできるようにするために、参照先に なりうる暗黙的な far ポインタです。
❏ __farptr_to_word(long 型のアドレス)
❏ __farptr_to_long(long 型のアドレス)
❏ __farptr_to_float(long 型のアドレス)
❏ __farptr_to_llong(long 型のアドレス)
❏ __farptr_to_ldouble(long 型のアドレス)
キーワード
far メモリをアクセスできる long 型のアドレスを生成するには、次の 2 つの方法があ ります。
❏ C++ ランタイムサポート・ライブラリに付属している C++ ランタイムサポート・
ライブラリのヒープ管理関数を使用することができます。
■ long far_calloc (unsigned long num, unsigned long size);
■ long far_malloc (unsigned long size);
■ long far_realloc (long ptr, unsigned long size);
■ void far_free (long ptr);
これらの関数は、far ヒープ領域にメモリを割り当てます。組み込み関数を使っ て、そのメモリにアクセスすることができます。たとえば次のとおりです。
#include <stdlib.h>
extern int x;
extern long y;
extern float z;
extern void func1 (int a);
extern void func2 (long b);
extern void func3 (float c);
//create a far object on the heap
long farint = far_malloc (sizeof (int));
long farlong = far_malloc (sizeof (long));
long farfloat = far_malloc (sizeof (float));
//assign a value to the far object
*_ _farptr_to_word (farint) = 1;
*_ _farptr_to_word (farint) = x;
*_ _farptr_to_long (farlong) = 78934;
*_ _farptr_to_long (farlong) = y;
*_ _farptr_to_float (farfloat) = 4.56;
*_ _farptr_to_float (farfloat) = z;
キーワード
❏ far メモリにリンクされている変数をデータ・セクションに配置するために、
DATA_SECTION プラグマをインライン・アセンブリと一緒に使うことができま
す。インライン・アセンブリを使って、これらの変数に対して long 型のアドレ スを作成します。その後、組み込み関数を使って、これらの変数にアクセスでき ます。たとえば次のとおりです。
#pragma DATA_SECTION (var, “.mydata”) int var;
extern const long var_addr;
asm ("\t .sect .const");
asm ("var_addr .long var");
int x;
x = *_ _farptr_to_word (var_addr);
プラグマ疑似命令