for
ループを使用して、UARTRXバッファからメモリに配列をコピーしています。
これは次のようになります。
UART2_readTimeout(uartR2, rxBuf3, 54, NULL, 500);
GPIO_toggle(CONFIG_GPIO_LED_3);
if ((rxBuf3[4] == 0x8C) && (rxBuf3[10] != 0x8C)) {
int i;
for (i = 0; i < 47; i++) {
sioR2[i]=rxBuf3[i];
}
次にstruct
、次のようなものを使用して、データを操作および整理するときにドット表記を使用できるようにします。
typedef struct
{
uint16_t voltage;
uint16_t current;
uint16_t outTemp;
uint16_t inTemp;
uint16_t status;
uint32_t FaultA;
uint32_t FaultB;
uint32_t FaultC;
uint32_t FaultD;
uint8_t softwareMode;
uint8_t logicLoad;
uint8_t outputBits;
uint16_t powerOut;
uint32_t runHours;
uint16_t unitAddresses[6];
} unitValues;
これらの全長が同じであると仮定すると、memcpy
構造体の単一のインスタンスに対して配列全体でを実行することは可能ですか?
Array : 001110101....110001
||||||||||||||||||| <- memcpy
vvvvvvvvvvvvvvvvvvv
Struct : 001110101....110001
C実装が、構造のレイアウトが、問題のドライバーがバッファーの書き込みに使用するレイアウトと同じであることを確認する方法を提供する場合、これを実行するためのかなり良い方法は、ドライバーに直接書き込むことです。構造。ここでドライバー関数のシグネチャを推測していますが、おそらく次のようになります。
UART2_readTimeout(uartR2, (uint8_t *) &values, 54, NULL, 500);
それuint8_t
がのエイリアスであるunsigned char
か、おそらくchar
であると仮定すると、タイプのポインタを介して構造体の表現に書き込むことが有効ですuint8_t *
。したがって、これにより、コピーを作成する必要がなくなります。
ただし、秘訣は構造のレイアウトです。データが指定された構造体メンバーとして指定された順序で、ギャップなしでレイアウトされることを期待すると、そのような構造体レイアウトは、すべてのメンバーがそれらの倍数であるアドレスに整列されるように構造体インスタンスがメモリに配置されるのを防ぎますサイズ。ハードウェアの配置ルールによっては、これで問題ない場合もありますが、一部のメンバーへのアクセスが遅くなるか、一部のメンバーにアクセスしようとするとプログラムがクラッシュする可能性があります。
それでも続行したい場合は、構造の必要なレイアウトを取得する方法について、コンパイラのドキュメントを確認する必要があります。構造体の「パッキング」、構造体のレイアウト、または構造体のメンバーの配置への参照を探す場合があります。これを行う標準的な方法はありません。C実装がそれをサポートしている場合、それは実装固有の詳細を含む拡張機能を構成します。
memcpy
バッファの内容を構造タイプのインスタンスにコピーするために使用する場合にも、同じ問題と警告がすべて当てはまります。したがって、データの複数のコピーを作成せず、構造に一括コピーを作成するように手配できる場合は、次のようになります。別のバッファに書き込んでからコピーするよりも、構造体に直接書き込む方がよいでしょう。
一方、安全で標準的な代替策は、実装が最適と思われる方法で構造をレイアウトできるようにすることです。また、データをバッファからメンバーごとに構造にコピーします。メンバーmemcpy()
の。はい、コードは少し面倒ですが、配置関連の問題や、構造体メンバーの並べ替えや新しいメンバーの追加にさえ敏感ではありません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加