|
|
View previous topic :: View next topic |
Author |
Message |
davesch2008
Joined: 12 Dec 2008 Posts: 4
|
Question on bitfield assignments |
Posted: Fri Dec 12, 2008 5:39 pm |
|
|
I recently updated to version 4.083 PCB/PCM. While evaluating the SW that was built with the new compiler I found one particular feature that no longer worked. I narrowed it down to a single line of code, where a bitwise structure member was being assigned. The code is shown below, with my added comments for context...
Code: | // When executed, smbus_data == 0x05
// poweroff_pend_flag is the least signicant bit of the flag2 structure
flag2.poweroff_pend_flag = smbus_data & 0x04;
00E5 0873 MOVF 0x73, W // smbus_data variable location
00E6 3904 ANDLW 0x4
00E7 00F8 MOVWF 0x78 // SCRATCH area, ends up with a value of 0x04
00E8 1046 BCF 0x46, 0 // clear poweroff_pend_flag member of flag2 data structure
00E9 1878 BTFSC 0x78, 0 // Tests bit 0, should be testing bit 2!!!
00EA 1446 BSF 0x46, 0 |
As noted above, the offending line of assembly code is that at 00e9 where it is testing the wrong bit.
I fixed this problem by changing the code to...
Code: | if (smbus_data & 0x05)
{
flag2.poweroff_pend_flag = 1;
} |
One interesting thing about this fix, the resulting assembly code is now reduced to...
Code: | BTFSC 0x73, 0x2
BSF 0x46, 0 |
So is this a compiler bug or am I abusing the C standard on how bitwise structure members can be assigned?
Dave Schmidt
Tektronix, Inc. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Dec 12, 2008 5:53 pm |
|
|
Post your PIC. |
|
|
davesch2008
Joined: 12 Dec 2008 Posts: 4
|
|
Posted: Fri Dec 12, 2008 5:56 pm |
|
|
Sorry, the target is a PIC16F76.
Dave Schmidt |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Dec 12, 2008 6:01 pm |
|
|
Can you post a little test program with the structure declaration, etc.,
so I can duplicate this ? |
|
|
davesch2008
Joined: 12 Dec 2008 Posts: 4
|
|
Posted: Fri Dec 12, 2008 6:10 pm |
|
|
I will, but not until the first of next week.
Dave Schmidt |
|
|
Ttelmah Guest
|
|
Posted: Sat Dec 13, 2008 4:35 am |
|
|
What you don't say, is how old the previous version compiler was?.
There was a change some time ago, in the way a logic test, would assign to a bitfield. Historically, the compiler assigned the test as 'non zero, assigns to true'. More recently (last year!), it switched to 'bit 0 == 1 assigns to true'.
This was supposedly done to make the compiler closer to ansi specification....
This would explain your older test failing, since the bitwise and, will always result in bit0 == 0, so in a 'false' return.
The new test, as shown in C, does not quite give the same functionality as the old. You would get the bitfield set to 1, if the incoming number == 1, 4, or 5. However the assembler you post, would be for:
Code: |
if (smbus_data & 0x04)
{
flag2.poweroff_pend_flag = 1;
}
|
Mispost?.
There is a big difference in the new' code, in that it won't ever _clear_ the bit, while the old, would.
The correct replacement, would be:
Code: |
flag2.poweroff_pend_flag = ((smbus_data & 0x04)!=0);
|
Best Wishes |
|
|
davesch2008
Joined: 12 Dec 2008 Posts: 4
|
|
Posted: Sat Dec 13, 2008 12:40 pm |
|
|
I don't know the exact version (its not installed anymore) but it was at least three years old. So thanks for the explanation on why the behavior is now different with the new compiler.
The posted workaround code is correct. The flag can only be set there, it is cleared in another portion of the code (i.e., it could be set multiple times prior to being cleared later).
Thanks for the help,
Dave Schmidt
Tektronix, Inc. |
|
|
Guest
|
|
Posted: Sat Dec 13, 2008 1:37 pm |
|
|
Will this be the same?
Bit evaluation
Code: | flag2.poweroff_pend_flag = ((smbus_data & 0x04)!=0); |
Logical evaluation
Code: | flag2.poweroff_pend_flag = (smbus_data && 0x04); |
|
|
|
Ttelmah Guest
|
|
Posted: Sat Dec 13, 2008 4:18 pm |
|
|
Given you don't have to clear the bit, the test and direct assignment, will always be much more efficient. Sometimes it is easy to forget that a simple assignment like this, wil be copying both the '1' result, and the '0' result, while a single test and assign, only has to deal with half this work.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|