We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello everyone,
So, I am working with an 8051W core processor (with OTP, once again, that's a whole other discussion) and I'm pretty maxed out on code space and looking to trim it down a bit. I need to check the functionality of some of my interrupts so I've had to create code that looks like this:
void main (void) { DiagMode = 0; /* Loop for standard/hardware diagnostics mode */ if ((DiagMode == 0) || (DiagMode == 2)) { while (1) { // Insert code here }; /* Loop forever */ } /* Loop for simulation/software diagnostic mode */ else if (DiagMode == 1) { while(1) { decimator2_ISR(); // Insert code here }; /* Loop forever */ } }
So if I wanted to use the code in simulation mode, I set DiagMode = 1. When I go to burn the chip, I set it equal to 0 (or 2 if I'm doing some hardware diagnostics, I have various case statements throughout the code that run only if DiagMode = 1 or 2).
Currently, if I want to cut down the code I have, I can comment out any unnecessary code portions (anything with DiagMode = 1, etc). I was wondering if there was a way to set my code to build the code differently if it is being used in simulation mode and when I compile it to hex (or set DiagMode to 0), the portions in code with DiagMode set to 1 are not built into the hex code, saving space.
I apologize if what I'm asking for is confusing. Realistically, it probably isn't possible but I figure if anyone would know how to do something along these lines (or has a better alternative), this would be the place to go.
Let me know when you get the chance. Thanks!
Well, I did define DiagMode using the following code:
#define DiagMode 0
So, if I understand correctly, it knows the value of DiagMode at compile time. If the code is generated based on that, does this mean I don't need to convert all my if/else statements to #if/#else statements?
It makes sense in my head that this should work but I want to do it the right way, so if this leaves it open for future errors, I'd rather make the correction now than wait until it fails down the road.
if (xxx) { code }
the code will always be included in memory and only execute if the if is valid. . .
#if (xxx) code #endif
the code will only be included in memory if xxx is valid . .
so, if xxx is not valid the second build will be smaller than the first.
Erik
Maybe not but it sounds like you and Per are saying two conflicting things. What the heck am I supposed to think?
If I understand Per, he seems to imply that if a variable is declared at compile time, it won't compile statements that don't meet that criteria. That seems to be what my code is doing, even without your #if statements.
I am now asking HIM based on what he is telling me if I need to do what YOU are suggesting. I completely understand what you are saying. Don't get me wrong. But I'm trying to understand why it appears to be working correctly with what I have, even if it contradicts what YOU are saying. I WANT to do it the correct way so I'm trying to get more information.
If you disagree with Per on something, just SAY it. But don't get annoyed with me when I try to piece bits of information together from two different people that seem to be saying different things.
Right now, my code is acting the same with my if statements as it SHOULD be acting with #if statements, which is what is leaving me conflicted. Me changing to #if statements should change the way it acts if what you are saying is correct but when I changed a few of them, the code space did not change at all, implying that either my current code is correct (without changing the #if statements BECAUSE I added the #define statement) or Keil is correcting for me and I SHOULD have the #if statements just to play it safe (which is what you seem to suggest).
The problem here is I'm having a conversation with Per about trying to understand what is going on with Keil and you're spitting out the same data over and over with no real explanation as to what Keil is doing or why I should correct my code to do it your way if it works just fine without it. I UNDERSTAND WHAT IT IS YOU'RE TRYING TO GET ME TO DO! I want to understand HOW Keil works and what it's doing and that's what Per is trying to help me understand.
If you want to help out and give me more information, that's fine. But don't judge me ("you just don't get it do you") because I'm not immediately jumping on your suggestion without fully understanding WHY it's necessary. That's the point of why you post here, correct?
If I understand Per, he seems to imply that if a variable is declared at compile time, it won't compile statements that don't meet that criteria. That seems to be what my code is doing, even without your #if statements. true IF the 'variable' (which, in this case, it is not) is used in a # statement find a 'C' book, it will have a chapter "the preprocessor"
If you disagree with Per on something, just SAY it. But don't get annoyed with me when I try to piece bits of information together from two different people that seem to be saying different things. I do not disagree with Per, however I do disagree with your interpretation of what he says. Do we have a language problem? is English your first language?
Right now, my code is acting the same with my if statements as it SHOULD be acting with #if statements, which is what is leaving me conflicted. Me changing to #if statements should change the way it acts if what you are saying is correct but when I changed a few of them, the code space did not change at all show a simple example
I want to understand HOW Keil works in this respect, just like any C compiler and what it's doing find a 'C' book, it will have a chapter "the preprocessor"
without fully understanding WHY it's necessary. find a 'C' book, it will have a chapter "the preprocessor"
read this msdn.microsoft.com/.../ew2hz0yd(v=vs.80).aspx
if I want to cut down the code I have, I can comment out any unnecessary code portions (anything with DiagMode = 1, etc). I was wondering if there was a way to set my code to build the code differently if it is being used in simulation mode
I have posted with the understanding that you want to build a code two ways a) for the processor excludng some code b) for the simulator including all code
I hope this is correct, if not please clarify
if this is correct, you NEED to use preprocessor conditionals
true IF the 'variable' (which, in this case, it is not) is used in a # statement
Maybe this is where we're not seeing eye to eye. Is #define not a preprocessor statement? If not, then that's my confusion and yes, you are correct, I need to change all my statements to #if statements.
However, my code appears to be acting as if that #define statement is a preprocessor statement. At your request, here's my example.
I have code that says
if(DiagMode==1) { //Execute Code 1 } else { //Execute Code 2 }
When I use the line:
my code size is set to code size x and it executes Code 1. When I change it to:
#define DiagMode 1
my code size now changes to code size y and executes Code 2. So for all intents and purposes, my code is acting the way I want it, changing what is compiled based on the value of DiagMode.
I then went back to my code and altered it in this way:
#if(DiagMode==1) { //Execute Code 1 } #else { //Execute Code 2 } #endif
When I use:
I now have it executing Code 1 and the size is the previously mentioned code size x (just as it was prior to me adding the # signs). When I change my DiagMode to:
It executes Code 2 and the code size changes to size y (once again, the same way it was WITHOUT the # signs).
Now from this, I conclude that the #define is acting as a preprocessor statement and that the # signs that you insist I need are absolutely necessary but I have no proof that that is the case, hence my confusion and my questions.
Now, about this . . .
Do we have a language problem? is English your first language? You can easily read my statements here and have a pretty good idea of whether or not my first language is English. Me having a different interpretation of something than you doesn't mean I don't understand the english language. Honestly, you do give a lot of helpful information but sometimes, you're just a complete ass.
Now, you say that my interpretation of what Per is saying is incorrect. Then correct me! If you understand it differently, explain what it is YOU understand from it and where my thinking is wrong. Simply saying "You're wrong because I understand it differently" is not helpful at all. And it just proves your blind arrogance.
Or rather APPEARS like blind arrogance (I'm not trying to cast judgement on you, I don't know you outside this forum. That's just how it comes off).
the 1000 pound elephant is the optimizer
Is #define not a preprocessor statement? If not, then that's my confusion and yes, you are correct, I need to change all my statements to #if statements. # define is a preprocessor statement #if is a preprocessor statement if is not a preprocessor statement regardless if whether the x in if(x) is #defined
However, my code appears to be acting as if that #define statement is a preprocessor statement. At your request, here's my example. not because #define is a preprocessor statement, see below
if(DiagMode==1) { //Execute Code 1 } else { //Execute Code 2 } When I use the line:
#define DiagMode 0 my code size is set to code size x and it executes Code 1. When I change it to:
#define DiagMode 1 my code size now changes to code size y and executes Code 2. So for all intents and purposes, my code is acting the way I want it, changing what is compiled based on the value of DiagMode
#if(DiagMode==1) { //Execute Code 1 } #else { //Execute Code 2 } #endif When I use:
#define DiagMode 0 I now have it executing Code 1 and the size is the previously mentioned code size x (just as it was prior to me adding the # signs). When I change my DiagMode to:
#define DiagMode 1 It executes Code 2 and the code size changes to size y (once again, the same way it was WITHOUT the # signs). as it should be
AAAH, got it, you have heavy optimization which will do this
if(0) { lines will be excluded }
THUS, if you reduce optimization level (heavy optimization while debugging is a ***) you need the # for the if's, if you optimize heavy, you do not
so with heavy optimization Per and I are both right, with low optimization Per is wrong and I'm right.
by the NASA philosophy "we fly what we test" I do not use heavy optimizations.
I actually wondered if that was the case and should have mentioned I had it on optimization 8 (which is very high).
Unfortunately, it's a custom ASIC with only 8k of code space and we're at 7.4k already WITH the optimizer already set to 8. Ideally, I'd like to drop it down but we don't have the space for it (and we haven't even added the I2C or SPI code to it yet).
Thanks for your help, that makes a lot more sense. In future projects when we have more available code space, I'll be sure to set the #if statements correctly. At least now I understand why it's acting in the way it is.
Oh, and please use the appropriate tags when posting code! Heh . . .
Unfortunately, it's a custom ASIC with only 8k of code space and we're at 7.4k already WITH the optimizer already set to 8. Ideally, I'd like to drop it down but we don't have the space for it (and we haven't even added the I2C or SPI code to it yet). OH, what fun fitting I²C and SPI (and the code that uses it) into 600 bytes. I hope your costom chip has it in hardware, NOW, beware - if you need delay routine(a) you need to do it) in assembly, that high optimization will simply drop routines that "do nothing'
Yeah, to be honest with you, I might have to look at compiling separate code for digital output code because I doubt it's going to fit (then maybe we can reduce the optimization).
Thanks for the heads up regarding delay routines, that will probably save me a lot of headaches.
I wish OUR company had the NASA attitude . . . "Well, it may be expensive, but we need it." Oh well, not much I can do about it except make the most of the situation. Brings up new challenges and I develop new skills, I guess.
some things I have a problem with with, when doing huge projects, is inactive code showing up as active on global scans and, sometimes, getting lost studying inactive code when the problem is elsewhere.
in such cases I, sometimes do the following (which seems silly in an example this small)
#ifdef TEST #define TESTCODE #endif then the following var47 = ADCinput; #ifdef TEST TESTCODE if var47 > 222 TESTCODE { TESTCODE var47 = 222; TESTCODE } #endif vr47 =/ 10;