So, I have a problem sending a value to a function at different parts of my code. Here is my code:
void LongRightShift(unsigned char NumBitsShift) { // My Code Here NumBitsShift = NumBitsShift; // So you can place a breakpoint here and read NumBitsShift }
Now, when I call
LongRightShift(2);
in the main part of my program, NumBitsShift = 2. When I call it in the Decimator2_ISR, NumBitsShift = 1;
Does this have to do with the way I'm passing it or is there a conflict with running other functions in an ISR?
Any help you can give me would be appreciated. Thanks!
or is there a conflict with running other functions in an ISR?
Yes, there is a conflict with running the same function from both the main code and an ISR. There is also a conflict with calling a function from any other one (including an ISR) that's running off a different register bank.
If you need more help than that, you'll have to show more of your actual source code. Try to find the smallest possible example source that still shows the problem. And don't be to ashamed if halfway through this reduction process you have one of those "DOH! What was I tinking?" moments --- that's happened to everyone.
Could the problem for this be related to another problem I'm having? I have the following code:
void AverageOutput(void) { unsigned char tempvar = 0; unsigned char NumOutSamples = 0; unsigned char Pressure1 = 500; if(Pressure1<600) { NumOutSamples = 0; AveragedPressureOut=Pressure1; } else { //More code here } tempvar+=1; // Place breakpoint on this line }
The trouble I'm having is that the code I run never makes it to the breakpoint (tempvar+=1). For whatever reason, it finishes the if statement and then completely exits the routine.
My if statement used to read:
if(((Pressure1-AveragedPressureOut)>410)||((Pressure1-AveragedPressureOut)<-410))
But even when Pressure1 was equal to AveragedPressure, it would still enter that loop and then would exit prematurely as you are seeing in the simplified code I have above it. Something funny is going on but I don't really know what it is.
I am calling this function from within another function, which you had mentioned could be a problem, but it is being called from the same .C file. I have this function defined in my VARS.H file using this line:
void AverageOutput(void);
Am I doing something wrong here that might be causing this problem? Codewise, I'm at 7000 or so so I still have available codespace and I'm not overflowing in my Data, IData, or Xdata registers.
I hesitate to blame this on Keil and realize it's probably something I'm doing wrong but for the life of me, I don't really know what's going on and it's hard to write code when the compiler itself begins to develop logic errors, my fault or not. I need to resolve this issue or I can't move any further.
Any help would be GREATLY appreciated. Thanks a lot!
Two things to consider.
One is that if you have code that gets called using different register banks or can be called asynchronously from different places, then you fool the compiler/linker. The compiler/linker converts auto variables into nameless global variables where each of these global variables may represent one or more auto variables. The flow control of the compiler/linker looks at what auto variables that may exist at the same time and matches them to different global variables. While auto variables that may not exist at the same time can reuse the same global variable.
The above is very complicated, and only done because the 8051 has such a lousy support for a real hardware stack.
If you mix register banks when calling a function, then the compiler/linker assumptions will break. If both main loop and an ISR calls the same function, then the compiler/linker assumptions will break.
But there is another thing to consider too - the compiler/linker looks for common code. So quite often, a function may run the initial source lines, but then suddenly jump somewhere else. The compiler/linker have noticed that more than one function in the program have a code block that looks identical. Either it's the tail of two functions, in which case one of the functions can end with a jump into the middle of the other function. Or maybe it is some sequence in the middle of a function that is common with other code somewhere - so the code sequence can be broken out into a new, auto-generated, function. This can surprise a lot when trying to use breakpoints - the code is run. But the code isn't in this function, but instead identical code is run somewhere else.
That makes a lot of sense and definitely brings attention to how little I know about what's actually going on behind the scenes. I'm not sure I follow 100% of what you're saying but I'll read it over a bit and see if I can wrap my head around everything you wrote here.
Is there a place I can look to find out how to see what register banks each variable is being stored in to see if the auto assign is placing something in a different register bank and causing issues?
I guess my question is where do I start to learn a solution to this issue? Is there something I can do in code to work around this?
As far as "identical looking code" being compiled in an odd way (at least, I think that's what you're referring to), I don't believe I have much optimization set (it's currently set to 8 - Reuse Common Entry Code . . . maybe that's what you're referring to though).
As far as other settings go, I have the memory model set to Small, the Code Rom Size set to Large, and no operating system (I am currently using a M8051W chip from Mentor Graphics).
If you need any additional information, please let me know.
One last thing I should note, the NumOutSamples and Pressure1 variables are being stored as global variables and I have them in my VARS.C file as:
signed short idata Pressure1 = 0; unsigned char NumOutSamples = 0;
and my VARS.H file as:
extern signed short idata Pressure1; extern unsigned char NumOutSamples;
I apologize in advance if this causes any confusion or seems to conflict with my previous code posts, I was trying to create a simple piece of code that is quick and easy to read and evaluate.
Thanks again for the help!
I just realized that the lower the setting, the less optimization. I guess I misunderstood the optimization ratings because setting the number lower makes my code bigger. Which is concerning, already being at 7k . . . :p
I guess I have a lot more optimization in my code than I realized. That might explain a few things . . .
Unfortunately, that means the code you showed so far has esentially no relation any more to the code you actually used. That makes it all but impossible to help you meaningfully.
You've not only messed up the type of your key variable, Pressure1, from short to unsigned char, but also changed its storage duration (from static to automatic) and linkage (from function-internal to global). In short, you kept nothing but the name intact.
If you have problems with some code, you really have to show that actual code, or at least a reduction of it that actually exhibits all the problems you have.
View all questions in Keil forum