Hello all, I'm having problem declaring bit as global in header file to avoid including extern bit xxx in other files. I've followed Keil instruction from this link: http://www.keil.com/support/docs/1868.htm
So far all the variables are good, and I don't have to use extern type variable xxx any more. For bit I try to do this:
_DECL bit xxx _INIT(x);
but it doesn't work. Is there any way to get it through? Would it be good to use struct in this case? If so, how should I do this? Any inputs would be greatly appreciated.
Best Regards, T.L
but it doesn't work.
There's no way anyone can help you based on a problem description that vague. Be specific. Show what exactly you tried, and how exactly it failed. A complete, reproducible example input and error log would be best.
Hans, Thank you for your input, and sorry for being late. I just get back to work this morning. This is what I did in the header file called Vars_Defs.h and this file is included in a Post.c using #include <Vars_Defs.h>
#ifndef VAR_DEFS #define VAR_DEFS 1 #ifndef VAR_DECLS # define _DECL extern # define _INIT(x) #else # define _DECL # define _INIT(x) = x #endif _DECL unsigned char Capt_0_H _INIT(0); _DECL unsigned char Capt_0_L _INIT(0); _DECL unsigned char Capt_1_H _INIT(0); _DECL unsigned char Capt_1_L _INIT(0); _DECL unsigned char Er0_H_Pos _INIT(0); _DECL unsigned char Er0_L_Pos _INIT(0); _DECL unsigned char Er0_H_Neg _INIT(0); _DECL unsigned char Er0_L_Neg _INIT(0); _DECL unsigned char Er1_H_Pos _INIT(0); _DECL unsigned char Er1_L_Pos _INIT(0); _DECL unsigned char Er1_H_Neg _INIT(0); _DECL unsigned char Er1_L_Neg _INIT(0); _DECL unsigned char Err_A _INIT(0); _DECL unsigned char Err_B _INIT(0); _DECL unsigned char Capt_Good_A _INIT(0); _DECL unsigned char Capt_Good_B _INIT(0); _DECL unsigned char A_Setpoint _INIT(0); _DECL unsigned char A_Set_half _INIT(0); _DECL unsigned char B_Setpoint _INIT(0); _DECL unsigned char B_Set_half _INIT(0); _DECL unsigned char A_Current _INIT(0); _DECL unsigned char B_Current _INIT(0); _DECL bit Capt_Done _INIT(0); _DECL bit Toggle_flag _INIT(0); _DECL bit Dual_flag _INIT(0); _DECL bit AB_On _INIT(0); _DECL bit Ready _INIT(0); #endif
and here is the warning message, not error:
Build target 'Target 1' compiling Main.c... compiling Post.c... linking... *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: CAPT_DONE MODULE: Post.obj (POST) *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: READY MODULE: Post.obj (POST) *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: READY MODULE: Post.obj (POST) ADDRESS: 00A5H *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: CAPT_DONE MODULE: Post.obj (POST) ADDRESS: 00A8H *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: CAPT_DONE MODULE: Post.obj (POST) ADDRESS: 00D5H *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: READY MODULE: Post.obj (POST) ADDRESS: 00ECH Program Size: data=13.4 xdata=0 code=454 "DigitalFS" - 0 Error(s), 6 Warning(s).
If I comment out the bit part in header file and make them global in Main.c and use extern bit directive in Post.c then no more warning like this
Build target 'Target 1' compiling Main.c... compiling Config.c... compiling Delay.c... compiling A2d.c... compiling Post.c... assembling STARTUP.A51... linking... Program Size: data=14.1 xdata=0 code=454 "DigitalFS" - 0 Error(s), 0 Warning(s).
<i_DECL unsigned char Capt_0_H _INIT(0);
I do not get it (something like _DECL is quite common) but what the ... is _INIT(0)
Erik
Hello Erik
_DECL unsigned char Capt_0_H _INIT(0);
the _INIT (0) part according to the link from Keil in my first post is to set initial value of that variable. In this case Capt_0_H is set to 0x00.
You are expected to define
#define VAR_DECLS #include <Var_Defs.h>
in one and exactly one source file. If you do it in more than one file, you will get multiple defined variables. If you don't do it in any file, you will get missing symbols.
not very clear
the trick where the op use "_DECL" takes care of the 'multiple definitions' HOWEVER he come us with extern unsigned char Err_B _INIT(0);
which is a no-no
The trick where the op use "_DECL" does not work for initialized variables.
btw what is Init(0) never heard of it I would make it
unsigned char Err_B = 0;
I just reviewed the thread and saw _INIT() defined.
my guess is that it still is a problem with _INIT().
You are expected to define #define VAR_DECLS #include <Var_Defs.h> in one and exactly one source file. If you do it in more than one file, you will get multiple defined variables. If you don't do it in any file, you will get missing symbols.
Yes, I do have it in Main.c. Had i have not had it, I would get more warning message regarding to all my variables.
To Erik,
The trick where the op use "_DECL" does not work for initialized variables. btw what is Init(0) never heard of it I would make it unsigned char Err_B = 0; Erik
Yes, initialize variable as you show will do the job and I have no problem doing that. The point is I just want to avoid listing a bunch of global variables and bit with initial value in the Main.c I don't know why, but the cause of warning message is about this part of the header file:
_DECL bit Capt_Done _INIT(0); _DECL bit Toggle_flag _INIT(0); _DECL bit Dual_flag _INIT(0); _DECL bit AB_On _INIT(0); _DECL bit Ready _INIT(0);
If I take these lines out of the file and declare them as global in main.c and use extern bit xxx in files wherever they are used then there are no warnings. My intention is to get rid off the extern type xxx in other files.
what happens if you remobe init from the bit defs
BTW the init(0) is totally unnecesaty, the code does that automatically in startup.
Erik, Thank you for your input. I did as you suggested but it still doesn't help. Warning messages still pop out everytime I compile the project.
In this case, for the testing purposes I initialized these bits as 0, and you got the point there as MCU at start up, startup.asm file should take care off the initialization and set them all to 0 as it clears all RAM. My intention was to find a general solution for further usage in case I want to set these bits = 1. So far I'm OK with variables using Keil's approach. Looks like I have to stick with the way I did before as declaring them global in main.c and use extern bit xxx. I will try to dig around and see if I can do anything else with this.
IMO, these "clever" preprocessor tricks are always dubious at best. As this one doesn't even work, perhaps it's best abandoned now?
Even the Keil article that you cited says, "this is not necessarily recommended"
But, if you still want to pursue this, you need to check that your macros are actually expanding correctly. For this, try Andy's Handy Hint for Debugging Preprocessor Problems:
"Most compilers provide a facility to save the Preprocessor output to a file; with Keil C51, it's the PREPRINT command-line option. Conventionally, this creates a file with a .i extension.
"If you have unexplained errors, or suspect that your macros might not be quite working properly, I recommend that you should check this preprocessor listing!"
To Andy Thank you for you input. Looks like this is not a common practice and somewhat troublesome. I don't like to give up but it seems this practice will cause more trouble than good. As you said, I should abandone the dead horse now. Thank you all for your time and inputs.
"Looks like this is not a common practice..."
Actually, it's not uncommon
"... and somewhat troublesome"
That bit is true!
See also: c-faq.com/.../decldef.html
"It is possible to use preprocessor tricks ... but it's not clear if this is worth the trouble"