4.2.4.1
データとプログラムのセクション割り当て
CC-RHでは,C言語レベルでモジュールやデータを任意のセクションに割り当てることができます。これにより,それぞれのセクション再配置属性の性質を利用した配置を指定することができます。
#pragma section指令で次のような書式で記述します。
#pragma section 属性指定文字 "セクション名"
変数/関数の宣言/定義
|
#pragma section 属性指定文字
変数/関数の宣言/定義
|
#pragma section [文字列]
変数/関数の宣言/定義
|
属性指定文字でセクション再配置属性を,“セクション名”でセクション名をそれぞれ指定します。本pragma以降に記述された静的変数はセクション再配置属性に沿って,指定されたセクションに配置されます。
“#pragma section 属性指定文字”の形式と“#pragma section [文字列]”の形式で,「属性指定文字」と「文字列」が同一の場合は,メッセージを出さずに“#pragma section 属性指定文字”の形式とみなします。ただし,-Xcheck=shcオプションを指定した場合は,“#pragma section 属性指定文字”の形式とみなした場合にメッセージが出力されます。
「属性指定文字」と「文字列」の同一性は,大小文字を含めて同一性を確認します。そのため,たとえば,大文字のR0_DISP32は属性指定文字とみなしません。
#pragma section r0_disp32 /*これはdataが属性指定文字と一致するので,*/
/*“#pragma section 属性指定文字”の形式とする*/
#pragma section R0_DISP32 /*これは属性指定文字と大小文字が異なるので,*/
/*“#pragma section [文字列]”の形式とする*/
|
セクション名が数値(0〜9)で始まる場合,セクション名先頭に“_”を付加します。
例 | #pragma section 123 → セクション名:_123.bss,_123.const,_123.text,... |
文字列に使用可能な文字は,次のとおりとする。
- 0〜9
- a〜z, A〜Z
- _
- @
- .
#pragma sectionの効果は変数と関数で異なります。
#pragma section系は「宣言,定義のいずれか一方のみ#pragma sectionが指定されている」場合,#pragma section指定されている側が有効です。
#pragma section系は「宣言,定義で別の#pragma sectionが指定されている」場合,最初に現れた#pragma section指定が有効です。
#pragma section系は常に関数定義に対してのみ有効です。
(a) | “#pragma section 属性指定文字 "セクション名" ”の指定方法 |
デフォルト・セクション名を変更し,#pragma 以降で宣言した変数を新しいセクション名で配置します。
- | 本pragma指令は,デフォルト・セクション名をユーザ指定のセクション名に変更します。 |
- | 本pragma 指令は,外部変数/文字列リテラル/関数内static変数/関数に対して有効です。 |
- | 本pragma指令は,記述された時点で以前の同じ属性への指定は無効になり,新たなセクション指定が有効となります。新たなセクションを指定しない場合,ファイルの終わりまで有効です。 |
- | 再配置属性にdefaultを指定した場合,それ以降#pragma section のないデフォルトの割り付けに戻ります。defaultはすべての#pragma section 記述が無効になります。 |
- | 変数の初期化がない場合は,指定された再配置属性に対し対応するbss系のセクションに配置されます。 |
- | 文字列リテラルは,デフォルトでは.constに割り付けられます。#pragma sectionに対しては他のconstオブジェクトと同様に配置先が決定されます。 |
- | セクション名には,ユーザ指定文字列に続けて,自動で再配置属性を示す文字列が付加されます。これは,初期化の有無により,自動で再配置属性を切り替えた場合,同名のセクションができてしまうのを避けるためです。
例)#pragma section r0_disp32 "xxx" → セクション名:xxx.data |
|
|
|
|
定義系
(data系)
|
r0_disp16
r0_disp23
r0_disp32
ep_disp4
ep_disp5
ep_disp7
ep_disp8
ep_disp16
ep_disp23
gp_disp16
gp_disp23
|
.zdata
.zdata23
.data
.tdata4
.tdata5
.tdata7
.tdata8
.edata
.edata23
.sdata
.sdata23
|
xxx.zdata
xxx.zdata23
xxx.data
xxx.tdata4
xxx.tdata5
xxx.tdata7
xxx.tdata8
xxx.edata
xxx.edata23
xxx.sdata
xxx.sdata23
|
宣言系
(bss系)
|
.zbss
.zbss23
.bss
.tbss4
.tbss5
.tbss7
.tbss8
.ebss
.ebss23
.sbss
.sbss23
|
xxx.zbss
xxx.zbss23
xxx.bss
xxx.tbss4
xxx.tbss5
xxx.tbss7
xxx.tbss8
xxx.ebss
xxx.ebss23
xxx.sbss
xxx.sbss23
|
const系
|
const
zconst
zconst23
|
.const
.zconst
.zconst23
|
xxx.const
xxx.zconst
xxx.zconst23
|
text系
|
text
|
.text
|
xxx.text
|
指定解除
|
default
|
すべての指定を解除して,デフォルトのセクション名に戻します。
|
注 | セクション名を“xxx”と書いた場合の実セクション名です。 |
#pragma section r0_disp32 "mydata"
int i = 0; /*“mydata.data”に割り当てられる*/
int j; /*“mydata.bss”に割り当てられる*/
#pragma section gp_disp16 "mydata2"
int i2 = 1; /*“mydata2.sdata”に割り当てられる*/
#pragma section const "myconst"
const int c2 = 0; /*“myconst.const”に割り当てられる*/
int j2; /*“.bss”に割り当てられる*/
|
#pragma section ep_disp4 "XXX"
extern int i;
void func()
{
i = 5;
}
#pragma section r0_disp32 "OOO"
int i = 5; /*"XXX.tdata4"に割り当てられる*/
/*最初の宣言にかかる #pragma section がある場合,*/
/*それが有効*/
|
#pragma section ep_disp4
int i;
#pragma section ep_disp23
int i; /*".tbss4"に割り当てられる*/
/*最初の宣言にかかる#pragma sectionがある場合,*/
/*それが有効*/
|
<def.c>
#pragma section ep_disp4
extern int i;
#pragma section ep_disp4 "XXX"
int i = 5; /*".tdata4"に割り当てられる*/
/*最初の宣言にかかる#pragma sectionがある場合,*/
/*それが有効*/
<use.c>
#pragma section ep_disp4
extern int i;
void func()
{
i = 5; /*アクセスに問題なし*/
}
|
#pragma section ep_disp4 "XXX"
extern int i;
#pragma section ep_disp4 "OOO"
int i = 5; /*".tdata4"に割り当てられる*/
/*最初の宣言にかかる#pragma sectionがある場合,*/
/*それが有効*/
|
#pragma section r0_disp16 "myzdata"
#pragma section const "myconst" /*この行で"myzdata"の指定はなくなる*/
int i = 0; /*.data constでないので効かない*/
const int ci = 0; /*myconst.const*/
#pragma section r0_disp16 "myzadata" /*再度指定*/
int j = 0; /*myzdata.zdata になる*/
const int cj = 0; /*.const 直前のpragmaでmyconst指定は*/
/*打ち消され".const"に配置される*/
|
extern int i;
#pragma section ep_disp4
int i; /*".tbss4"に配置する*/
/*宣言側と相違あるが,仮に他翻訳単位で*/
/*#pragma section ep_disp23なしでアクセスしたとしても,*/
/*長距離(効率悪い)アドレッシング・モードでアクセスが正常動作する*/
|
#pragma section ep_disp23
#pragma section default
extern int i;
#pragma section ep_disp4
int i; /*".tbss4"に配置する*/
/*デフォルト・セクション名に戻す#pragma section defaultは,*/
/*セクション指定とみなさない*/
/*extern宣言側は,セクション指定がないものとみなす*/
|
(b) | “#pragma section 属性指定文字”の指定方法 |
#pragma以降で宣言した変数をデフォルト・セクション名で配置します。
- | デフォルトのセクション名で,データの配置位置を指定します。 |
- | デフォルトのセクション名に配置されることを除けば,配置規則は“#pragma section 属性指定文字 "セクション名" ”と同一です。 |
|
|
|
定義系
(data系)
|
r0_disp16
r0_disp23
r0_disp32
ep_auto
ep_disp4
ep_disp5
ep_disp7
ep_disp8
ep_disp16
ep_disp23
gp_disp16
gp_disp23
|
.zdata
.zdata23
.data
.tdata4/.tdata5/.tdata7/.tdata8から自動選択
.tdata4
.tdata5
.tdata7
.tdata8
.edata
.edata23
.sdata
.sdata23
|
宣言系
(bss系)
|
.zbss
.zbss23
.bss
.tbss4
.tbss5
.tbss7
.tbss8
.ebss
.ebss23
.sbss
.sbss23
|
const系
|
const
zconst
zconst23
|
.const
.zconst
.zconst23
|
text系
|
text
|
.text
|
指定解除
|
default
|
すべての指定を解除して,デフォルトのセクション名に戻します。
|
#pragma section gp_disp16
int a = 1; /*.sdataセクションに配置する*/
int b; /*.sbssセクションに配置する*/
|
- | ep_autoは宣言の型に応じて,ep_disp4/ep_disp5/ep_disp7/ep_disp8のいずれかとして動作します。 |
|
|
unsigned char
|
ep_disp4
|
unsigned short
|
ep_disp5
|
signed char
char
_Bool
|
ep_disp7
|
signed short
signed int
unsigned int
signed long
unsigned long
signed long long
unsigned long long
float
double
long double
ポインタ
列挙型(int型サイズの場合)
|
ep_disp8
|
備考 1. | 配列型は,要素の型に応じて対応するep_dispnを選択します。ただし,多次元配列(配列の配列)の場合は,多次元配列に格納する要素の型とします。 |
#pragma section ep_auto
char c_ary[3][5] = {0}; //.tdada7 (char)
char* p_ary[3][5] = {0}; //.tdata8 (ポインタ)
|
備考 2. | -Xenum_typeオプションの作用により列挙型がintよりも小さな型になる場合,小さくなった型に応じて対応するep_dispnを選択します。 |
備考 3. | 構造体および共用体は,.tdata4/.tdata5/.tdata7/.tdata8のいずれにも配置しません。 |
- | ep_autoは宣言の型に応じて,ep_disp4/ep_disp5/ep_disp7/ep_disp8のいずれかとして動作するため,宣言と定義でep_autoとep_dispnが同一の意味になる場合はエラーになりません。異なる意味となる場合はコンパイル・エラーとなります。 |
#pragma section ep_auto
extern unsigned char ch;
#pragma section ep_disp4
unsigned char ch; /*エラーも警告もなしで,.tbss4 に配置する*/
|
#pragma section ep_auto
extern unsigned char ch;
#pragma section ep_disp7
unsigned char ch; /*エラーも警告もなしで,.tbss4 に配置する*/
/*最初の宣言にかかる#pragma sectionがある場合,*/
/*それが有効*/
|
(c) | “#pragma section [文字列]”の指定方法 |
コンパイラが出力するセクション名を切り替えます。
デフォルトのセクション名と切り替え後のセクション名は,次のとおりです。
|
|
|
|
プログラム
|
#pragma section xxx
|
text
|
xxx.text
|
定数
|
const
|
xxx.const
|
初期値ありデータ
|
data
|
xxx.data
|
初期値なしデータ
|
bss
|
xxx.bss
|
- | 文字列を省略した場合,すべてのセクション名をデフォルトに設定します。 |
#pragma section abc
int a; /*aはセクションabc.bssに割り付きます*/
const int d=1; /*dはセクションabc.constに割り付きます*/
void f(void) /*fはセクションabc.textに割り付きます*/
{
a = d;
}
#pragma section
int b; /*bはセクション.bssに割り付きます*/
void g(void) /*gはセクション.textに割り付きます*/
{
b = d;
}
#pragma section 123
int c; /*cはセクション_123.bssに割り付きます*/
void h(void) /*hはセクション_123.textに割り付きます*/
{
c = d;
}
|