2016年2月12日金曜日

エンディアンの変換 __REV()関数

リトルエンディアンからビッグエンディアンに変換するためにバイト単位で入れ替えていたが、__REV()という(マクロ)関数が用意されていた。Cortex-M用のGCCの関数のようだ。

1バイトずつ入れ替え
v = (sineTable[index] >> 0);
p8 = (uint8 *)(&v);
waveBuffer_0[i]   = *(p8 + 3);
waveBuffer_0[i+1] = *(p8 + 2);
waveBuffer_0[i+2] = *(p8 + 1);
waveBuffer_0[i+3] = *p8;
__REV()を使用
v = (sineTable[index] >> 0);
*((uint32 *)waveBuffer_0) = __REV(v);

__REV()はARMのasmにrevと言う命令があってこれを呼び出していて一発でエンディアンを変換できるようだ。


演算の前後でPinにH/Lを出力して実行時間を比較。


1バイトずつ入れ替え

ch1:実行時間 ch2:I2SのWS

(1)PW:1.520us

__REV()

(1)PW:1.070us

※横軸の縮尺が違います。

PWはパルスの+側の時間で、比較すると__REV()を使ったほうがかなり短縮されている。

また、1バイトずつ入れ替えている方は、実行時間より、WSがHiの時間のほうが長い。つまり2ch出力すると間に合っていなかったようだ。