Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Usage of bitset ?

Usage of bitset ?

Scheduled Pinned Locked Moved C / C++ / MFC
csshardwaredata-structuresquestion
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    Vaclav_
    wrote on last edited by
    #1

    My task is to modify selected bits in 8 bit (char) words. At present I have declared an array of two words. The array gets "filled" from hardware source - I2C adapter. I can manage to manipulate required bits using plain Boolean code - KISS. I have found this template class " bitset " . I have never used a template class and not sure if using it would be less code or confusion. Since I need to pass the char pointer of the array I am not sure if changing to template class would be as obvious as passing a char array pointer. I am open to suggestions. Cheers

    D K 2 Replies Last reply
    0
    • V Vaclav_

      My task is to modify selected bits in 8 bit (char) words. At present I have declared an array of two words. The array gets "filled" from hardware source - I2C adapter. I can manage to manipulate required bits using plain Boolean code - KISS. I have found this template class " bitset " . I have never used a template class and not sure if using it would be less code or confusion. Since I need to pass the char pointer of the array I am not sure if changing to template class would be as obvious as passing a char array pointer. I am open to suggestions. Cheers

      D Offline
      D Offline
      Daniel Pfeffer
      wrote on last edited by
      #2

      The problem with a bitset is that you have no control over the internal representation of the bits. 1. There is no way to know whether the representation is 1 bit/value or 1 byte/value (this is a quality of implementation issue) 2. There is no way to know whether the underlying type is an array of chars, ints, or some other type 3. There is no way to know whether bit 0 is the MSB or the LSB of the underlying type If you are getting data from an external source, the only safe (and portable) way to read the data is as an array of char / unsigned char. Note that std::vector<> and std::array<> guarantee that the allocated memory will be contiguous, so a pointer to the zeroth element of either would be OK as well.

      Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

      1 Reply Last reply
      0
      • V Vaclav_

        My task is to modify selected bits in 8 bit (char) words. At present I have declared an array of two words. The array gets "filled" from hardware source - I2C adapter. I can manage to manipulate required bits using plain Boolean code - KISS. I have found this template class " bitset " . I have never used a template class and not sure if using it would be less code or confusion. Since I need to pass the char pointer of the array I am not sure if changing to template class would be as obvious as passing a char array pointer. I am open to suggestions. Cheers

        K Offline
        K Offline
        k5054
        wrote on last edited by
        #3

        I suspect what you want to use is bit-field struct members. e.g. your device sends you 2 bytes, formatted as follows 1-2 op status code 1 3-6 op status code 2 7-12 error code 13-16 unused You could model that as follows

        struct op_status {
        unsigned int status_1:2;
        unsigned int status_2:2;
        unsigned int error:6;
        };

        If you are unfamiliar with this construct a struct member like unsigned int item:2 defines a member only 2 bits wide. The type of a bit-field member should be integral, (e.g. char, short, int, etc) but can be signed or unsigned as needed. You can use the struct members as short ints e.g

        int devfd = open("/dev/a_device", O_RDWR);

        struct op_status i2c_status;

        read(devfd, &i2c_status, sizeof(i2c_status));

        if(i2c_status.status_1 == 1) {
        /* do something */
        } else if ( i2c_status.status_1 == 2 && i2c_status.status_2 = 1) {
        switch(i2c_status.error) {
        case 1: /* handle error code 1 */
        break;
        case 2: /* handle error code 2 */
        break;
        ...
        default: /* do something else */
        }
        }

        looking a , I don't see a nice way to group the bits together to treat them as a single unit, like you can using bit-fields. Usually, bit-fields are packed together, but check your compiler documentation to make sure. Also, don't forget that bit and/or byte order coming from your device might not match your CPU, so you may need to declare various fields out-of-order with respect to the documentation.

        D V 2 Replies Last reply
        0
        • K k5054

          I suspect what you want to use is bit-field struct members. e.g. your device sends you 2 bytes, formatted as follows 1-2 op status code 1 3-6 op status code 2 7-12 error code 13-16 unused You could model that as follows

          struct op_status {
          unsigned int status_1:2;
          unsigned int status_2:2;
          unsigned int error:6;
          };

          If you are unfamiliar with this construct a struct member like unsigned int item:2 defines a member only 2 bits wide. The type of a bit-field member should be integral, (e.g. char, short, int, etc) but can be signed or unsigned as needed. You can use the struct members as short ints e.g

          int devfd = open("/dev/a_device", O_RDWR);

          struct op_status i2c_status;

          read(devfd, &i2c_status, sizeof(i2c_status));

          if(i2c_status.status_1 == 1) {
          /* do something */
          } else if ( i2c_status.status_1 == 2 && i2c_status.status_2 = 1) {
          switch(i2c_status.error) {
          case 1: /* handle error code 1 */
          break;
          case 2: /* handle error code 2 */
          break;
          ...
          default: /* do something else */
          }
          }

          looking a , I don't see a nice way to group the bits together to treat them as a single unit, like you can using bit-fields. Usually, bit-fields are packed together, but check your compiler documentation to make sure. Also, don't forget that bit and/or byte order coming from your device might not match your CPU, so you may need to declare various fields out-of-order with respect to the documentation.

          D Offline
          D Offline
          Daniel Pfeffer
          wrote on last edited by
          #4

          k5054 wrote:

          looking a <bitset>, I don't see a nice way to group the bits together to treat them as a single unit, like you can using bit-fields.

          All the usual logical and shift operators are defined on **bitset**s. You can also convert a bitset to an integer type, and construct a bitset from an integer type. The major issue is the internal representation, which is implementation-defined. This is why a bitset should not be used to interface to hardware.

          Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

          1 Reply Last reply
          0
          • K k5054

            I suspect what you want to use is bit-field struct members. e.g. your device sends you 2 bytes, formatted as follows 1-2 op status code 1 3-6 op status code 2 7-12 error code 13-16 unused You could model that as follows

            struct op_status {
            unsigned int status_1:2;
            unsigned int status_2:2;
            unsigned int error:6;
            };

            If you are unfamiliar with this construct a struct member like unsigned int item:2 defines a member only 2 bits wide. The type of a bit-field member should be integral, (e.g. char, short, int, etc) but can be signed or unsigned as needed. You can use the struct members as short ints e.g

            int devfd = open("/dev/a_device", O_RDWR);

            struct op_status i2c_status;

            read(devfd, &i2c_status, sizeof(i2c_status));

            if(i2c_status.status_1 == 1) {
            /* do something */
            } else if ( i2c_status.status_1 == 2 && i2c_status.status_2 = 1) {
            switch(i2c_status.error) {
            case 1: /* handle error code 1 */
            break;
            case 2: /* handle error code 2 */
            break;
            ...
            default: /* do something else */
            }
            }

            looking a , I don't see a nice way to group the bits together to treat them as a single unit, like you can using bit-fields. Usually, bit-fields are packed together, but check your compiler documentation to make sure. Also, don't forget that bit and/or byte order coming from your device might not match your CPU, so you may need to declare various fields out-of-order with respect to the documentation.

            V Offline
            V Offline
            Vaclav_
            wrote on last edited by
            #5

            Thanks, this will definitely give me a good start in using bitset, specially when I need to process more than two characters. Appreciate it. At current I have this code to process single char.

            // build a common function to set / reset bits
            // shift data into correct bit postion
            cout << " data 0x" << hex << +data << endl;
            data <<= iLSbit;
            cout << " shifted data 0x" << hex << +data << endl;
            int iDataBit;
            for (int iBit = iLSbit; iBit != iMSbit + 1; iBit++) {
            

            #ifdef DEBUG
            cout << "processing bit " << dec << +iBit << endl;
            // clear bit
            buf[0] &= ~(1UL << iBit); // don't need this
            #endif
            // set or reset bit
            // check data bit @ position
            iDataBit = (data >> iBit) & 1U;
            #ifdef DEBUG
            cout << " iDataBit " << hex << +iDataBit << endl;
            #endif
            if (iDataBit) {
            #ifdef DEBUG
            cout << "set bit @ position " << dec << iBit << endl;
            #endif
            buf[0] |= (1UL << iBit);
            } else {
            #ifdef DEBUG
            cout << "clear bit @ position " << dec << iBit << endl;
            #endif
            // clear bit
            buf[0] &= ~(1UL << iBit);
            }
            }

            Since I need to read the data (hardware register ) before modifying it , then writing it back to hardware it seems simpler than using bitset. At present I am modifying / checking single register parameter ( A/D converter input MUX ) , but in future I like to modify all parameters in single access. I think that is where bitset will do the job. Thanks again Cheers Vaclav

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups