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 ?
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.