This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

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 ?

Parents
  • 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.

Reply
  • 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.

Children