加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何使用C构造函数初始化位域?

发布时间:2020-12-16 10:28:03 所属栏目:百科 来源:网络整理
导读:首先,我不关心可移植性,并且可以安全地假设字节顺序不会改变.假设我读取了硬件寄存器值,我想将该寄存器值覆盖在位域上,这样我就可以参考寄存器中的各个字段而不使用位掩码. 编辑:修复了GMan指出的问题,并调整了代码,以便将来读者更清楚. 见:Anders K.迈克
首先,我不关心可移植性,并且可以安全地假设字节顺序不会改变.假设我读取了硬件寄存器值,我想将该寄存器值覆盖在位域上,这样我就可以参考寄存器中的各个字段而不使用位掩码.

编辑:修复了GMan指出的问题,并调整了代码,以便将来读者更清楚.

见:Anders K.&迈克尔J的答案如下,以获得更有说服力的解决方案.

#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;
}

解决方法

不要这样做

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

‘this’指针不应该以这种方式摆弄:

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

这里’这’在记忆中有两个不同的地方

而是有一个内部联合/结构来保存值,这样很容易转换
来回(因为你对便携性不感兴趣)

例如

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

编辑:足够真实,名称为’register’

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读