Keil Logo Arm Logo

Discussion Forum

wrong compilation with bdata in .h (use of extern)

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Read-Only
Author
vincent heyvaert
Posted
8-Sep-2011 10:49 GMT
Toolset
C51
New! wrong compilation with bdata in .h (use of extern)

hello,

this the version of my keil µvision sofware:

IDE-Version:
µVision3 V3.51

Tool Version Numbers:
Toolchain Path: C:\Keil\C51\BIN\
C Compiler: C51.Exe V8.08
Assembler: A51.Exe V8.00d
Linker/Locator: BL51.Exe V6.05
Librarian: LIB51.Exe V4.24
Hex Converter: OH51.Exe V2.6
CPU DLL: S8051.DLL V3.11
Dialog DLL: D500.DLL V2.46

my problem:
I have a wrong compilation with the use a global bdata variable.

here is my code in multiple file:

global.c

#include global.h

unsigned char bdata buffer;
sbit buffer_0 = buffer^0;
sbit buffer_1 = buffer^1;
sbit buffer_2 = buffer^2;
sbit buffer_3 = buffer^3;
sbit buffer_4 = buffer^4;
sbit buffer_5 = buffer^5;
sbit buffer_6 = buffer^6;
sbit buffer_7 = buffer^7;

xdata struct struct_plateau plateau[6]  _at_    0x4001;

global.h

extern unsigned char bdata buffer;
extern bit buffer_0;
extern bit buffer_1;
extern bit buffer_2;
extern bit buffer_3;
extern bit buffer_4;
extern bit buffer_5;
extern bit buffer_6;
extern bit buffer_7;

extern xdata struct struct_plateau plateau[6];

struct struct_plateau {

        unsigned char lampe_tilt_ou_bonus;
        unsigned char lampe_carte_et_stop;

};

reglage.c

#include global.h

void test_switch_bandeau_et_lampe_bandeau_et_tilt () {

        buffer = memorisation_lecture_switch_carte;

        plateau[0].lampe_carte_et_stop = buffer_0;   //ligne 1
        plateau[1].lampe_carte_et_stop = buffer_1;   //ligne 2
        plateau[2].lampe_carte_et_stop = buffer_2;   //ligne 3
        plateau[3].lampe_carte_et_stop = buffer_3;   //ligne 4
        plateau[4].lampe_carte_et_stop = buffer_4;   //ligne 5
        plateau[5].lampe_carte_et_stop = buffer_5;   //ligne 6

        buffer = memorisation_lecture_switch_stop;  //don't compile this ligne 7

        plateau[0].lampe_tilt_ou_bonus = buffer_0;   //ligne 8
        plateau[1].lampe_tilt_ou_bonus = buffer_1;   //ligne 9
        plateau[2].lampe_tilt_ou_bonus = buffer_2;   //ligne 10
        plateau[3].lampe_tilt_ou_bonus = buffer_3;   //ligne 11
        plateau[4].lampe_tilt_ou_bonus = buffer_4;   //ligne 12
        plateau[5].lampe_tilt_ou_bonus = buffer_5;   //ligne 13

}

the problem is that the compilator don't take a look of the ligne 7.
I have take a look in the desasembly file and It save the result of the ligne 1 to 6
in register R0 to R5 and restore this value in ligne 8 to 13.

I have try this second solution and all is ok

void test_switch_bandeau_et_lampe_bandeau_et_tilt () {

unsigned char i;

        buffer = memorisation_lecture_switch_carte;

        for (i=0 ; i<6; i++) {
                if (buffer_0 == 0) {
                        plateau[i].lampe_carte_et_stop = 0;
                }
                else {
                        plateau[i].lampe_carte_et_stop = 1;
                }
                buffer >>= 1;
        }

        buffer = memorisation_lecture_switch_stop;

        for (i=0; i<6; i++) {
                if (buffer_0 == 0) {
                        plateau[i].lampe_tilt_ou_bonus = 0;
                }
                else {
                        plateau[i].lampe_tilt_ou_bonus = 1;
                }
                buffer >>= 1;
        }
}

I have also try to declare directly de buffer in the reglage.c file without extern
and all is ok, I have just this problem if the buffer_0 to buffer_7 are declare with extern in .h file.

what do you think about this ?

Read-Only
Author
Per Westermark
Posted
8-Sep-2011 11:26 GMT
Toolset
C51
New! RE: wrong compilation with bdata in .h (use of extern)

If you use extern, then the compiler will not know that the bit accesses are aliased with the "buffer" variable. So your function contains code that assigns multiple values to "buffer" but does not seem to make use of the value.

Are you sure that it isn't the first buffer assign that doesn't happen? I.e. that the compiler assumes that this value will be overwritten with the second value, and just assign this second value directly?

Having the variable volatile would force a need for performing all writes.

Read-Only
Author
vincent heyvaert
Posted
8-Sep-2011 13:45 GMT
Toolset
C51
New! RE: wrong compilation with bdata in .h (use of extern)

If you see this page of the C51 user's guide :

http://www.keil.com/support/man/docs/c51/c51_le_bitaddrobj.htm

it's explain that using extern is ok for multiple file or module.

secondly, in the second solution (this solution work perfecly) with bit testing the value of buffer_0 to buffer_5 take the second value off buffer and all bit test are good.

Read-Only
Author
Hans-Bernhard Broeker
Posted
8-Sep-2011 11:30 GMT
Toolset
C51
New! RE: wrong compilation with bdata in .h (use of extern)

sbit buffer_0 = buffer^0;
/*...*/
extern bit buffer_0;

Doesn't that look like a contradiction to you? sbit is not the same as bit. So what's happening is that, essentially, you're lying to the compiler while it's working on reglage.c. You've hidden from the compiler the information you now wonder it's not applying.

sbit doesn't follow the usual distinction between declaration and definition. It's the only memory class where you have to put the definition into the .h file.

Read-Only
Author
vincent heyvaert
Posted
8-Sep-2011 14:00 GMT
Toolset
C51
New! RE: wrong compilation with bdata in .h (use of extern)

hello,

in this page of the user guide: it's explain the use of sbit and bit

http://www.keil.com/support/man/docs/c51/c51_le_bitaddrobj.htm

and here a exemple of declaration in .c file and extern in .h file

http://www.keil.com/forum/618/

Read-Only
Author
Andy Neil
Posted
13-Sep-2011 09:30 GMT
Toolset
C51
New! RE: wrong compilation with bdata in .h (use of extern)

See also: http://www.keil.com/forum/19527/

and: http://www.keil.com/support/docs/1175.htm

Read-Only
Author
Andy Neil
Posted
13-Sep-2011 09:35 GMT
Toolset
C51
New! RE: Doesn't that look like a contradiction to you?

Yes, it does - but that is the way that Keil tell you to do it!

See: http://www.keil.com/support/docs/1175.htm

And see my rant at the end of this thread: http://www.keil.com/forum/618/ - that was 10 years ago; it doesn't seem to have improved.

Read-Only
Author
vincent heyvaert
Posted
16-Sep-2011 08:28 GMT
Toolset
C51
New! RE: Doesn't that look like a contradiction to you?

I thing, with your response, that my syntax is corect,

for my problem, I think that is a bug of the compilator, Have I a too old version of keil ?

this problem is maybe not in the new version.

Read-Only
Author
rank amateur
Posted
16-Sep-2011 09:20 GMT
Toolset
C51
New! Have I a too old version of keil ?

9.05

http://www.keil.com/download/product/

Read-Only
Author
Hans-Bernhard Broeker
Posted
16-Sep-2011 12:46 GMT
Toolset
C51
New! RE: Doesn't that look like a contradiction to you?

but that is the way that Keil tell you to do it!

Well, that means sbit and bdata cannot be used for the kind of thing the OP is trying to do.

In translation units other than the one holding the sbit definitions, there is no way for the compiler to know that those bit objects are actually sbits overlaying that particular bdata object. I.e. there's no way the compiler can know that writes to that bdata object cannot be interleaved with accesses to those particular bit variables.

What this example basically created is a secret union. It's a union because these are objects occupying the same space by design, and it's secret because the compiler doesn't know about it. And yes, that will cause problems as soon as the optimizer is used at all.

A possible solution to that might be to make both the bdata and bits volatile.

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Keil logo

Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.