开发者

What does "variable|variable" mean in C++?

I was looking into this ITE8712 watchdog timer demo code when I saw this:

void InitWD(char cSetWatchDogUnit, char cSetTriggerSignal)
{
OpenIoConfig();     //open super IO of configuration for Super I/O

SelectIoDevice(0x07);   //select device7

//set watch dog counter of unit
WriteIoCR(0x72, cSetWatchDogUnit|cSetTriggerSignal);

//CloseIoC开发者_运维百科onfig();      //close super IO of configuration for Super I/O
}

and, I wonder what is meant by this line:

cSetWatchDogUnit|cSetTriggerSignal

because the WriteIoCR function looks like this:

void WriteIoCR(char cIndex, char cData)
{
//super IO of index port for Super I/O
//select super IO of index register for Super I/O
outportb(equIndexPort,cIndex);

//super IO of data for Super I/O
//write data to data register
outportb(equDataPort,cData);
}

So cIndex should be 0x72, but what about the cData? I really don't get the "|" thing as I've only used it for OR ("||") in a conditional statement.


It's a bitwise or, as distinct to your normal logical or. It basically sets the bits in the target variable if the corresponding bit in either of the source variables was set.

For example, the expression 43 | 17 can be calculated as:

43 = 0x2b = binary 0010 1011
17 = 0x11 = binary 0001 0001
                   ==== ====
        "or" them: 0011 1011 = 0x3b = 59

See this answer for a more thorough examination of the various bitwise operators.

It's typically used when you want to manipulate specific bits within a data type, such as control of a watchdog timer in an embedded system (your particular use case).

You can use or (|) to turn bits on and and (&) to turn them off (with the inversion of the bitmask that's used to turn them on.

So, to turn on the b3 bit, use:

val = val | 0x08; // 0000 1000

To turn it off, use:

val = val & 0xf7; // 1111 0111

To detect if b3 is currently set, use:

if ((val & 0x08) != 0) {
    // it is set.
}

You'll typically see the bitmasks defined something like:

#define B0 0x01
#define B1 0x02
#define B2 0x04
#define B3 0x08
#define B4 0x10

or:

enum BitMask {
    B0 = 0x01,
    B1 = 0x02,
    B2 = 0x04,
    B3 = 0x08,
    B4 = 0x10
};

As to what this means:

WriteIoCR (0x72, cSetWatchDogUnit|cSetTriggerSignal);

More than likely, 0x72 will be an I/O port of some sort that you're writing to and cSetWatchDogUnit and cSetTriggerSignal will be bitmasks that you combine to output the command (set the trigger signal and use a unit value for the watchdog). What that command means in practice can be inferred but you're safer referring to the documentation for the watchdog circuitry itself.

And, on the off chance that you don't know what a watchdog circuit is for, it's a simple circuit that, if you don't kick it often enough (with another command), it will reset your system, probably by activating the reset pin on whatever processor you're using.

It's a way to detect badly behaving software automatically and return a device to a known initial state, subscribing to the theory that it's better to reboot than continue executing badly.


That's a bitwise or. It is used here to combine flags.


x | y is generally used with Plain Old Datas in C/C++. It means bitwise OR.

e.g.

char x = 0x1, y = 0x2;
x | y ==> 0x3

[Note: operator | can be overloaded for class/struct according to your need.]


| is a bitwise or. It toggles the bits on (1 instead of 0) if one OR the other of the same bit in either integer is on.

|| is the logical or. It returns true if one OR the other are true.


OK, here's why you use a bitwise or, or see them used, in this sort of situation.

Often times, those variables are flags that are used to pack multiple pieces of data into one char

If cSetWatchDogUnit and cSetTriggerSignal

have non-overlapping bits (imagine cSetWatchDogUnit = 1 << 0 and cSetTriggerSignal = 1 << 1 you can check later to see if they are set with a bitwise and, like this contrived example:

if cData & cSetWatchDogUnit
    do something
if cData & cSetTriggerSignal
    do something else

The whole time, both of these flags can be packed into and passed around in a single char. That way, you don't end up passing an array of bools, you can add new constants cSetSomeOtherDamnfoolThing = 1 << 2 and you can refer to flags as variables in your code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜