DSPボードという特殊な環境で動作するプログラムを作成するため、 通常のC言語とは異なる部分があります。 機能が制限される場合もありますが、 拡張されている部分もあります。
dm」と「pm」
SHARC DSP
には2組のデータバスがあるので、
両方を同時に使用すると2個のデータを1命令サイクルで読み書きすることができます。
この機能を有効に使うために、
どちらのバス/メモリを使用するのかを指定できるように拡張されています。
「dm」と「pm」で、
特に指定しなければDMになります。
一部のライブラリ関数では、 高速化のためにデータを配置するメモリを規定しています。 その場合は、データを規定されたメモリに配置する必要があります。
section」
「section」は、
「dm」や「pm」よりも細かい
メモリ配置の制御を行います。
例えば、
#define DELAYLEN 48000
section("seg_sdram") float delay0[DELAYLEN];
というプログラムでは、
配列「delay0」は
「seg_sdram」という領域に格納されます。
今回使用するDSPボードには、4Mワード×32bitのSDRAMが搭載されています。 DSPの内蔵メモリは小さいので、 大容量のデータはSDRAMに配置することになります。 SDRAMを使うためにはいろいろ準備が必要ですが、 演習で使うサンプルプログラムには既に組み込まれているので、 詳細は気にしなくてもかまいません。
SDRAMにデータ領域を確保する手段を二通り用意してあります。 これら二通りは、同時には使用できません。 同時に使用すると確実に誤動作します。
最初の方法は
「section」を使うものです。
sectionのプログラム例は、SDRAM上に配列を確保します。
これが真っ当なやり方です。
ただし、プログラムをダウンロードする際には
SDRAM上の配列データもDSPにダウンロードしようとするので、
ダウンロード時間が長くなります。
第2の方法は、初期値が不要な配列専用で、 ダウンロード時間を短縮しようとするものです。 Sample1はこの方法を使っています。 該当部分を抜き出すと、
#define DELAYLEN 48000
float *delay0;
float *delay1;
void Init(void){
delay0 = AllocFloat(DELAYLEN); // Allocate large array on SDRAM
delay1 = AllocFloat(DELAYLEN);
}
となります。
関数「AllocFloat()」は
allocSDRAM.cで定義されています。
プログラムやデータは主としてDSPの内蔵メモリに配置されるので、 そのサイズはPCやWSよりも小さなものに制限されます。 Sample1では、下記の容量が割り当てられています。
| 種類 | 場所 | サイズ | 備考 |
|---|---|---|---|
| プログラム | 内蔵SRAM block 0 | 16k×48bit | |
| DMデータ | 内蔵SRAM block 1 | 16k×32bit | グローバル変数やスタティック変数 |
| C言語スタック | 内蔵SRAM block 1 | 8k×32bit | ローカル変数とリターンアドレス |
| PMデータ | 内蔵SRAM block 2 | 8k×32bit | 2データ同時アクセス用 |
| C言語ヒープ | 内蔵SRAM block 3 | 8k×32bit | malloc()等 |
| データ | 外部SDRAM | 4M×32bit | 内蔵SRAMの10倍以上遅い |
例として、下記のプログラムを考えてみましょう。
float data1[8];
pm float data2[8];
void Init(void)
{
float tmp[2];
static float *p;
p = malloc(sizeof(float) * 16);
}
このプログラムでは、
data1: DMデータ (グローバル変数)
data2: PMデータ
tmp: C言語スタック (ローカル変数)
p: DMデータ (スタティック変数)
*p: C言語ヒープ (malloc()の戻り値)
pm」というキーワードについては、
拡張機能
を参照してください。