配列と構造体を共用体にしてエンディアンが逆さにならないようにするには?

こんばんは、NAKAといいます。

初心者あるあるで申し訳ないんですが、C言語を教えてください。

8バイト(DATA[0]~DATA[7])の送受信データをやり取りしてます。

配列データのDATA[0]=0x12,DATA[1]=0x34 から変数SPEED=0x1234というデータを作りたく、両者を共用したいので

struct
{
 union                                  
 {
  struct
  {
   unsigned short SPEED;
   unsigned short RPM;
   unsigned short NE;
   unsigned char SIG1;
   unsigned char SIG2;
  }SIG;
  unsigned char DATA[8];
 }BYTE; 
}TXRX;

配列と構造体を共用体として宣言しました。

配列に

    TXRX.BYTE.DATA[0] = 0x12;
    TXRX.BYTE.DATA[1] = 0x34;
    TXRX.BYTE.DATA[2] = 0x56;
    TXRX.BYTE.DATA[3] = 0x78;
    TXRX.BYTE.DATA[4] = 0x9A;
    TXRX.BYTE.DATA[5] = 0xBB;
    TXRX.BYTE.DATA[6] = 0xCC;
    TXRX.BYTE.DATA[7] = 0xDD;

ようにデータをいれたのですが、エンディアンが逆なので

のようにSPEED=0x1234 となってほしいのですが SPEED=0x3412となってしまいます。

当然

TXRX.BYTE.SIG.SPEED = 0x1234;

とするとDATA[0]に0x34、DATA[1]に0x12が入っちゃいます。

 

SPEED=0x1234と入るように作るにはどうすれば良いのでしょうか?

 

あぁ情けない!(T_T)

Parents
  • NAKAさん、こんにちは。NoMaYです。

    余りスレッドを引き延ばすつもりは無いですが、やりたかったことのイメージは、こんな感じですか?データとCPUのエンディアンが同じなら、素朴にビットフィールドを使って実現出来そうなことに思います。データとCPUのエンディアンが異なる今回の場合、更に、#pragma bit_order leftを併用すれば良いような気がします。([追記] ←これは#pragma bit_order leftでは片付かない話のような気がして来ました。すみません。) 具体的なデータの構造を教えて頂ければ、もう少し考えを進められそうですが、さすがにそれは業務上無理そうですかね?(やりたかった事が私がイメージしたようなことであれば、ですが、、、) あと、教えて頂ければと思うのは、コンパイラが何か?ですね。

    データのエンディアンはビッグエンディアン
    CPUのエンディアンはリトルエンディアン

    ch1バスのデータ (↓のch2バスのデータとはデータの構造が異なる)

    8バイト
    12bitがバイトをまたいで配置
    スイッチなどは1bitが混じってたり
    ch1⇒ch2に渡す信号のデータbit数が変わるものもある

    ch2バスのデータ (↑のch1バスのデータとはデータの構造が異なる)

    8バイト
    12bitがバイトをまたいで配置
    スイッチなどは1bitが混じってたり
    ch1⇒ch2に渡す信号のデータbit数が変わるものもある

    やりたかった事?

    ch2.SPEED = ch1.SPEED;
    ch2.SW = ch1.SW;
    等々

     

  • NoMaY先生、いつも!いつも!ありがとうございます。NAKAです。

    まさにそんな感じです。

    配列DATA[8]とSPEED、SWなどの構造体が共用されており

    受信
    CAN_1ch_RX(ID_100.DATA);
    CAN_1ch_RX(ID_200.DATA);

    送信

    ID_100.SPEED=ID_100.SPEED+0x1000; //※時々
    ID_300.SPEED = ID_100.SPEED;
    ID_300.SW=ID_200.SW;
    CAN_2ch_TX(ID_300.DATA);

    みたいにできたらなと思いました。

    コンパイラはCC-RX(RX63N)やCC-RL(RL78/F15)などです。

    ビットシフトやマスクで何とか並べ替えは出来てはいるのですが(汗)
    そのうち間違えそうな気がして........

  • NAKAです。

    前の返信を書いてて思ったのですが、別にエンディアンが逆さのままでもいいのかな?という気に
    なってきました。値をいじるときだけ気を付けて、受信で逆さになっても結局、送信でまた逆さになるなら
    そのままでいいのかな?もう少しよく考えてみます。

  • NAKAさん、こんにちは。NoMaYです。

    >値をいじるときだけ気を付けて
    気を付ける、という意気込みだけでは間違えそうな気がします、、、せめて変数の末尾に_BE_DATA等付けて気付き易くするとか、でしょうか、、、

    あと、ベタなネーミング/やり方ですが、以下のようにいっそのことバラバラにしてしまうとか、、、

    union
    {
        struct
        {
            unsigned    char    SPEED_h;
            unsigned    char    SPEED_l;
            unsigned    char    RPM_h;
            unsigned    char    RPM_l;
            unsigned    char    NE_h;
            unsigned    char    NE_l;
            unsigned    char    VAL_h4:4;   /* DATA[6] bit3-bit0 */
            unsigned    char    SIG1:2;     /* DATA[6] bit5,bit4 */
            unsigned    char    SIG2:2;     /* DATA[6] bit7,bit6 */
            unsigned    char    VAL_l8;
        }SIG;
        unsigned    char    DATA[8];
    }CH1;

    union
    {
        struct
        {
            unsigned    char    SPEED_h;
            unsigned    char    SPEED_l;
            unsigned    char    RPM_h;
            unsigned    char    RPM_l;
            unsigned    char    NE_h;
            unsigned    char    NE_l;
            unsigned    char    VAL_h6:6;   /* DATA[6] bit5-bit0 */
            unsigned    char    SIG1:2;     /* DATA[6] bit7,bit6 */
            unsigned    char    VAL_l8;
        }SIG;
        unsigned    char    DATA[8];
    }CH2;

     

        CH2.SIG.SPEED_h = CH1.SIG.SPEED_h + 0x10;
        CH2.SIG.SPEED_l = CH1.SIG.SPEED_l;

        CH2.SIG.RPM_h   = CH1.SIG.RPM_h;
        CH2.SIG.RPM_l   = CH1.SIG.RPM_l;

        CH2.SIG.NE_h    = CH1.SIG.NE_h;
        CH2.SIG.NE_l    = CH1.SIG.NE_l;

        CH2.SIG.SIG1    = CH1.SIG.SIG1;

        CH2.SIG.VAL_h6  = CH1.SIG.VAL_h4 + 0x20;
        CH2.SIG.VAL_l8  = CH1.SIG.VAL_l8;

     

Reply
  • NAKAさん、こんにちは。NoMaYです。

    >値をいじるときだけ気を付けて
    気を付ける、という意気込みだけでは間違えそうな気がします、、、せめて変数の末尾に_BE_DATA等付けて気付き易くするとか、でしょうか、、、

    あと、ベタなネーミング/やり方ですが、以下のようにいっそのことバラバラにしてしまうとか、、、

    union
    {
        struct
        {
            unsigned    char    SPEED_h;
            unsigned    char    SPEED_l;
            unsigned    char    RPM_h;
            unsigned    char    RPM_l;
            unsigned    char    NE_h;
            unsigned    char    NE_l;
            unsigned    char    VAL_h4:4;   /* DATA[6] bit3-bit0 */
            unsigned    char    SIG1:2;     /* DATA[6] bit5,bit4 */
            unsigned    char    SIG2:2;     /* DATA[6] bit7,bit6 */
            unsigned    char    VAL_l8;
        }SIG;
        unsigned    char    DATA[8];
    }CH1;

    union
    {
        struct
        {
            unsigned    char    SPEED_h;
            unsigned    char    SPEED_l;
            unsigned    char    RPM_h;
            unsigned    char    RPM_l;
            unsigned    char    NE_h;
            unsigned    char    NE_l;
            unsigned    char    VAL_h6:6;   /* DATA[6] bit5-bit0 */
            unsigned    char    SIG1:2;     /* DATA[6] bit7,bit6 */
            unsigned    char    VAL_l8;
        }SIG;
        unsigned    char    DATA[8];
    }CH2;

     

        CH2.SIG.SPEED_h = CH1.SIG.SPEED_h + 0x10;
        CH2.SIG.SPEED_l = CH1.SIG.SPEED_l;

        CH2.SIG.RPM_h   = CH1.SIG.RPM_h;
        CH2.SIG.RPM_l   = CH1.SIG.RPM_l;

        CH2.SIG.NE_h    = CH1.SIG.NE_h;
        CH2.SIG.NE_l    = CH1.SIG.NE_l;

        CH2.SIG.SIG1    = CH1.SIG.SIG1;

        CH2.SIG.VAL_h6  = CH1.SIG.VAL_h4 + 0x20;
        CH2.SIG.VAL_l8  = CH1.SIG.VAL_l8;

     

Children
  • NoMaY先生 NAKAです。

    なるほどぉ、バラバラにする手もありますね!!(^^♪
    行数が増えるのが、難点といえば柊の実ですが(笑)←やばいオヤジが出てしまった!!
  • ヒイラギ
     モクセイ科モクセイ属に分類される常緑小高木の一種

    ナンテン
     メギ科ナンテン属の常緑低木

    ヒイラギナンテン
     メギ科メギ属の常緑低木

    セイヨウヒイラギ
     モチノキ科モチノキ属の常緑小高木

    ヒラギノ
     macOSおよびiOSの標準日本語フォント