3

まず、移植性には関心がなく、エンディアンは変わらないと安全に推測できます。ハードウェアレジスタ値を読み取ると仮定して、ビットマスクを使用せずにレジスタ内の個々のフィールドを参照できるように、そのレジスタ値をビットフィールドにオーバーレイしたいと思います。

編集: GManによって指摘された問題を修正し、将来の読者にとってより明確になるようにコードを調整しました。

参照:より雄弁な解決策については、以下のAndersK.とMichaelJの回答を参照してください。

#include <iostream>

/// \class HardwareRegister
/// Abstracts out bitfields in a hardware register.
/// \warning  This is non-portable code.
class HardwareRegister
{
   public:
      /// Constructor.
      /// \param[in]  registerValue - the value of the entire register. The
      ///                             value will be overlayed onto the bitfields
      ///                             defined in this class.
      HardwareRegister(unsigned long registerValue = 0)
      {
         /// Lots of casting to get registerValue to overlay on top of the
         /// bitfields
         *this = *(reinterpret_cast<HardwareRegister*>(&registerValue));
      }


      /// Bitfields of this register.
      /// The data type of this field should be the same size as the register
      /// unsigned short for 16 bit register
      /// unsigned long for 32 bit register.
      ///
      /// \warning Remember endianess! Order of the following bitfields are
      ///          important.
      ///          Big Endian    - Start with the most signifcant bits first.
      ///          Little Endian - Start with the least signifcant bits first.
      unsigned long field1: 8;
      unsigned long field2:16;
      unsigned long field3: 8;
}; //end class Hardware


int main()
{

   unsigned long registerValue = 0xFFFFFF00;
   HardwareRegister  testRegister(registerValue);

   // Prints out for little endianess machine
   // Field 1 = 0
   // Field 2 = 65535
   // Field 3 = 255
   std::cout << "Field 1 = " << testRegister.field1 << std::endl;
   std::cout << "Field 2 = " << testRegister.field2 << std::endl;
   std::cout << "Field 3 = " << testRegister.field3 << std::endl;
}
4

4 に答える 4

5

ビットフィールドはそのようには機能しません。struct完全なビットフィールドにスカラー値を割り当てることはできません。を使っていたので、すでに知っているようですreinterpret_castが、reinterpret_castはあまりうまくいくとは限らないので、サイコロを振っているだけです。

ビットフィールド構造体とスカラーの間で変換する場合は、値をエンコードおよびデコードする必要があります。

    HW_Register(unsigned char value)
      : field1( value & 3 ),
        field2( value >> 2 & 3 ),
        field3( value >> 4 & 7 )
        {}

編集:出力が得られない理由は、フィールドの数字に対応するASCII文字が印刷されていないためです。これを試して:

std::cout << "Field 1 = " << (int) testRegister.field1 << std::endl;
std::cout << "Field 2 = " << (int) testRegister.field2 << std::endl;
std::cout << "Field 3 = " << (int) testRegister.field3 << std::endl;
于 2010-08-25T05:08:13.543 に答える
5

これをしないでください

 *this = *(reinterpret_cast<HW_Register*>(&registerValue));

「this」ポインターをそのようにいじってはいけません。

HW_Register reg(val)
HW_Register *reg = new HW_Register(val)

ここで「これ」はメモリ内の 2 つの異なる場所にあります

代わりに、値を保持するための内部共用体/構造体を用意してください。そうすれば、簡単に前後に変換できます (移植性には関心がないため)。

例えば

union
{
   struct {
     unsigned short field1:2;
     unsigned short field2:4;
     unsigned short field3:2;
    ...
   } bits;
   unsigned short value;
} reg

編集:「登録」という名前で十分です

于 2010-08-25T05:35:18.313 に答える
2

これを試して:

class HW_Register
{
public:
    HW_Register(unsigned char nRegisterValue=0)
    {
        Init(nRegisterValue);
    }
    ~HW_Register(void){};

    void Init(unsigned char nRegisterValue)
    {
        nVal = nRegisterValue;
    }

    unsigned Field1() { return nField1; }
    unsigned Field2() { return nField2; }
    unsigned Field3() { return nField3; }

private:
    union
    {
        struct 
        {
            unsigned char nField1:2;
            unsigned char nField2:4;
            unsigned char nField3:2;
        };
        unsigned char nVal;
    };
};


int main()
{
    unsigned char registerValue = 0xFF;
    HW_Register  testRegister(registerValue);

    std::cout << "Field 1 = " << testRegister.Field1() << std::endl;
    std::cout << "Field 2 = " << testRegister.Field2() << std::endl;
    std::cout << "Field 3 = " << testRegister.Field3() << std::endl;

    return 0;
}
于 2010-08-25T07:18:43.640 に答える
1
HW_Register(unsigned char registerValue) : field1(0), field2(0), field3(0) 
于 2010-08-25T05:06:00.470 に答える