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

Runtime / Simulation Specific Code

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!

Parents Reply Children
  • I have a question for you. So, if you look at my last post, you can see what I did and it seemed to work without updating any of my if statements to #if statements. Is this because Keil fixed the issue for me with the compiler (which probably means I am still doing it incorrectly, regardless of how Keil fixes it for me) or is what I did actually correct?

    I found an area that had an if/else diagmode statement and changed them to #if and #else and noticed no change in code size (ie the code I had was executing correctly with my fixes) so it appears to be doing what I wanted it to do correctly.

    I just want to know if my procedure is incorrect and, for best practices or when using other compilers (or even changing optimization levels, possibly), I need to implement it differently or if my coding is correct.

    Let me know if my wording is confusing and I can try and explain it again. Thanks!

  • you are mixing precompiler and compiler directive

    THIS IS AN EXAMPLE VARIABLE NAMES ARE FICTIONAL

    common.h

    //#define OMIT1 //uncomment if certain code is to be omitted
    //#define OMIT2 //uncomment if certain other code is to be omitted
    

    whatever.c

    #include common.h
    
    code
    #ifndef OMIT1
    code that is to be excluded if omit 1
    #endif
    code
    #ifndef OMIT2
    code that is to be excluded if omit 2
    #endif
    code
    #ifndef OMIT1
    more code that is to be excluded if omit 1
    #endif
    code
    

  • Ok, I understand.

    Out of curiosity, is it really easier to create your own examples from scratch rather than to simply demonstrate by correcting code that is incorrect (such as my examples)? Could save a few posts.

  • Oh, and for the record, I don't want to come off as ungrateful because I do appreciate the help I'm getting.

    And so you know, I used "BUILD1" for reference purpose, not because I thought BUILD1 was the required variable (I understand you weren't being literal with that name). So that part wasn't lost on me, in case I gave you the impression I didn't know how variables worked . . . :p

  • The compiler is smart. If it see C code that is unreachable, it can remove it.

    So:

    int charlie=1
    if (charlie == 1) {
        ...
    } else {
        ...
    }
    


    the compiler can throw away the code inside the else statement.

    If the code instead looks like:

    void my_function(int charlie) {
        if (charlie == 1) {
            ...
        } else {
            ...
        }
    }
    


    Then the compiler can't throw away any code.

    But when using #ifdef x or #if defined(x) or #if x == y then the preprocessor will filter away non-matching code and the compiler don't need to worry about what can be resolved at compile time and what needs to be resolved at runtime.

  • Out of curiosity, is it really easier to create your own examples from scratch rather than to simply demonstrate by correcting code that is incorrect (such as my examples)?
    I consider it more important that you get to understand how this works than giving you code.
    Giving you code will not help you next time

    Erik

  • I don't do it because i worry about "giving code". I do it because I want to show a skeleton showing the concept without any extra noise around.

    Remember that threads on this forum are read by people who find the threads using search engines at a much later time. They don't care about your specific source code. But they may care about the concept that is covered in the thread.

  • So it's likely that Keil is overcompensating for errors in my code. I should still use the #if statements rather than if statements, even if it seems to be working correctly, just to play it safe. Thanks for the help.

  • No - Keil is not overcompensating.

    But compilers do optimize code. So if the compiler knows that specific code lines can never be reached, then the compiler still need to process the lines to verify that they are grammatically correct. But the compiler can decide to not generate any code. You may potentially get a warning "unreachable code".

    The #if version is the only one where all information is known at compile time.

    The if (expr) version depends on the contents of the expression, if the compiler will be able to deduce that the expression has a fixed value or not.

  • 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"

    Erik

    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

    Erik


  • 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:

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

    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:

    #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).

    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.