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!
the preprocessor, which handles the #... thingies do NOT look at char, int etc.
thus if you have #ifdef RALPH
RALPH must be a #define
the ussual way to do this is in xxx.h to have something like //#define BUILD1 //uncomment this line for build1
Erik
So you're saying I would just need to change all my:
if(DiagMode==1)
statements to
#if(BUILD1)
Is that correct? I just want to make sure before I change my whole program.
Thanks, Erik!
Note that #if BUILD1 tests if the preprocessor symbol BUILD1 is nonzero. #if defined(BUILD1) (or the older #ifdef BUILD1) just tests if it is defined.
#define BUILD1 // just defines this symbol #define BUILD1 1 // also gives it a value
if you give the define a value, you can also do
#define BUILD_TYPE 2 #if BUILD_TYPE==0 ... #elif BUILD_TYPE==1 ... #elif BUILD_TYPE==2 ... #else #error "Unsupported build type." #endif
Well, found the issue with the errors with
#define DiagMode 0
in my VARS.H file. Turns out, I just need to comment out:
unsigned char idata DiagMode = 0; extern unsigned char idata DiagMode;
Now I don't have to change anything (which is convenient). Thanks!
Well remember that #define does symbol replacement.
So your
unsigned char idata DiagMode = 0;
will look like
unsigned char idata 0 = 0;
and the compiler is not impressed by that.
if(DiagMode==1) statements to
#if(BUILD1) Is that correct? I just want to make sure before I change my whole program.
of course not, Names in an example are just that
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:
#ifndef _D4_VARS_H #define _D4_VARS_H //extern unsigned char idata DiagMode; #define DiagMode 0
#include "VARS.H" //unsigned char idata DiagMode = 0;
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.
Look at my example.
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
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.