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
  • Ok, now I'm confused. What is it you guys are proposing me to do at this point?

    Originally, I had:

    VARS.H

    #ifndef _D4_VARS_H
    #define _D4_VARS_H
    
    extern unsigned char idata DiagMode;
    

    vars.c

    #include "VARS.H"
    unsigned char idata DiagMode = 0;
    

    main.c

    #include "VARS.H"
    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 */
            }
    
    }
    

    I have now changed it to:

    VARS.H

    #ifndef _D4_VARS_H
    #define _D4_VARS_H
    
    //extern unsigned char idata DiagMode;
    #define DiagMode 0
    

    vars.c

    #include "VARS.H"
    //unsigned char idata DiagMode = 0;
    

    main.c

    #include "VARS.H"
    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 */
            }
    
    }
    

    This appears to work as I can change the Diagmode = 0 to 1 and it gives me a different code size, which I assume means it's working (maybe I'm wrong). Am I doing this right or are you suggesting I need to do it a bit differently?

    I understand that you guys generally want to give guidance without giving sample code but at this point, I think you're losing me with what it is you're suggesting. Can you give me a quick code example for what you think I should be doing because, if I'm doing something incorrectly right now, I really don't understand what it is you are suggesting.

Reply
  • Ok, now I'm confused. What is it you guys are proposing me to do at this point?

    Originally, I had:

    VARS.H

    #ifndef _D4_VARS_H
    #define _D4_VARS_H
    
    extern unsigned char idata DiagMode;
    

    vars.c

    #include "VARS.H"
    unsigned char idata DiagMode = 0;
    

    main.c

    #include "VARS.H"
    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 */
            }
    
    }
    

    I have now changed it to:

    VARS.H

    #ifndef _D4_VARS_H
    #define _D4_VARS_H
    
    //extern unsigned char idata DiagMode;
    #define DiagMode 0
    

    vars.c

    #include "VARS.H"
    //unsigned char idata DiagMode = 0;
    

    main.c

    #include "VARS.H"
    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 */
            }
    
    }
    

    This appears to work as I can change the Diagmode = 0 to 1 and it gives me a different code size, which I assume means it's working (maybe I'm wrong). Am I doing this right or are you suggesting I need to do it a bit differently?

    I understand that you guys generally want to give guidance without giving sample code but at this point, I think you're losing me with what it is you're suggesting. Can you give me a quick code example for what you think I should be doing because, if I'm doing something incorrectly right now, I really don't understand what it is you are suggesting.

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