|
|
View previous topic :: View next topic |
Author |
Message |
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
18F6722 possible math issue from compiler v5.074 to 5.105 |
Posted: Wed Jan 19, 2022 9:30 am |
|
|
I've sent this off to tech support, but I thought you guys might spot something quicker.
I'm not sure if it's my code or a math issue with the latest compiler. My code worked fine in previous versions of the compiler.
The code compiled in 2019 worked and the code I recently compiled has the issue. From the dates of my compiler updates I
concluded it must be a difference between v5.074 and v5.105.
Unfortunately I don't save the lst files of previous iterations of code. Only the source & hex. And I've never had to try to compile with a previous version of the compiler, so I'm not sure how to do that. I'm hoping this might be enough to notice a problem with my code or the compiler.
This is the context of the problem line.
The intention is to calculate a count that would be a percentage of full-scale.
Default_SP[i] is a % of full scale of the adc count. range 0-100 with 255=unused.
With i=1 SP = 35 and I expect 1433 but get 20971. The lst is a bit overwhelming and I'm not confident I could read it well enough to spot a problem.
Code: |
#include <18F6722.h> // changed F or LF as needed
.
.
const unsigned int Default_SP[CALPOINTS]={0,35,100,255,255,255,255,255,255,255,255}; // fill from bottom, ascending order; unused must be 255
.
.
.
void Load_Table_Defaults(int Option)
{
.
.
.
Active.Table.FlowCnt[i]=((int32)Default_SP[i]*4095)/100; // was =((int32)Default_SP[i]*40 (you can ignore the comment, that was a very old change)
if(Default_SP[i]==100)Active.Table.FlowCnt[i]=4000; // adjust so 98% flow = max
.
.
.
}
|
and this is the current list:
Code: |
.................... Active.Table.FlowCnt[i]=((int32)Default_SP[i]*4095)/100; // was =((int32)Default_SP[i]*40
036B6: BCF FD8.0
036B8: MOVLB 1
036BA: RLCF xEA,W
036BC: CLRF 03
036BE: ADDLW 89
036C0: MOVWF FE9
036C2: MOVLW 01
036C4: ADDWFC 03,W
036C6: MOVWF FEA
036C8: CLRF 03
036CA: MOVF xEA,W
036CC: MOVLB 0
036CE: CALL 00CA
036D2: MOVWF 01
036D4: MOVLB 1
036D6: CLRF xEF
036D8: CLRF xEE
036DA: MOVWF xED
036DC: MOVFF FEA,1F2
036E0: MOVFF FE9,1F1
036E4: MOVLB 2
036E6: CLRF x1D
036E8: MOVLB 2
036EA: CLRF x1C
036EC: MOVLB 2
036EE: CLRF x1B
036F0: MOVLB 1
036F2: MOVFF FE8,21A
036F6: CLRF x21
036F8: CLRF x20
036FA: MOVLW 0F
036FC: MOVWF x1F
036FE: SETF x1E
03700: MOVLB 0
03702: RCALL 30FA
03704: MOVFF 1F2,FEA
03708: MOVFF 1F1,FE9
0370C: MOVFF 03,1F0
03710: MOVFF 02,1EF
03714: MOVFF 01,1EE
03718: MOVFF 00,1ED
0371C: MOVFF FEA,1F4
03720: MOVFF FE9,1F3
03724: BCF FD8.1
03726: MOVFF 03,220
0372A: MOVFF 02,21F
0372E: MOVFF 01,21E
03732: MOVFF 00,21D
03736: MOVLB 2
03738: CLRF x24
0373A: CLRF x23
0373C: CLRF x22
0373E: MOVLW 64
03740: MOVWF x21
03742: MOVLB 0
03744: RCALL 3156
03746: MOVFF 1F4,FEA
0374A: MOVFF 1F3,FE9
0374E: MOVFF 01,FEC
03752: MOVF FED,F
03754: MOVFF 00,FEF
|
Thoughts? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 19, 2022 9:58 am |
|
|
Make us a test program that fails.
I made this one and it gives me 1433.
Code: |
#include <18F6722.h>
#fuses NOWDT
#use delay(internal=4M)
#use rs232(UART1, baud=9600, ERRORS)
const unsigned int Default_SP[]=
{0,35,100,255,255,255,255,255,255,255,255};
//=================================
void main()
{
int16 result;
int i;
i = 1;
result = ((int32)Default_SP[i]*4095)/100;
printf("result = %lu \r", result);
while(TRUE);
}
|
|
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Wed Jan 19, 2022 11:12 am |
|
|
Hmm...well that's embarrassing!
I just copied your code into a test program and ran it thru PICSIM and mine worked, too.
I guess I should have tried that first, eh?
I will have to dig deeper. I was certain this is where the problem was being created.
Thanks PCM for helping me rule out this line of code. I guess I'll have to look at the other 3000 lines of code now, LOL. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Wed Jan 19, 2022 11:12 am |
|
|
FYI, the 'overwhelming' lst, is only a tiny part of the code involved.
The actual maths, is in the RCALL 3156, and the RCALL 30FA routines....
What you have posted is perhaps one tenth of the actual code... |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Thu Jan 27, 2022 6:50 am |
|
|
Update:
Even though the short example version worked, the full program still did not.
I commented out the entire program and got it down to one line of code that would cause the failed calculation. So I got the enter program down to 2 lines in Main().
The first one was the LoadDefault() that had the math problem. The second was a TerminalCheck() function that checked for terminal activity and, if a key were pressed, would launch the terminal menu/interaction etc. I could uncomment all of the other code and it would calc properly as long as the TerminalCheck() remained commented out.
The TerminalCheck() contained a lot of functions and some of those functions called functions. So it had a lot of potential depth, although none of it actually executed because no key was ever pressed. I commented out it's contents and the calc worked again. Uncommented and it failed.
That was the point where I figured I was probably wasting my time and sent it off to CCS support. It seemed more likely to be a hidden issue within the compiler rather than the result of some awkward coding.
CCS responded remarkably fast with a patch. But, unfortunately, no explanation. I just sent a reply asking for a brief summary of what the problem was. I put a lot of time & effort into trying to figure out if it was me or the compiler, and in trying to narrow it down (and trying to create a simple test program). Hopefully they will respond with some info and I'll be a little smarter for it.
Bottom line: I'm glad the problem is behind me and CCS support is great! I just wish I could have posted a better answer here. |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Thu Jan 27, 2022 8:45 am |
|
|
response from CCS support:
"It was an optimization bug related to the CLRF instruction. A bank selection instruction was incorrectly removed.
It showed up when that statement used registers in both bank 1 and 2. When all the registers used where bank 1
it worked. #opt 0 should also have worked."
So, I guess it was because of the compound math statement. That would explain why, when I broke it down, it worked.
I totally get how that crazy bank switching can be complicated!!!
Code: |
TestVal = Default_SP[i];
TestVal = (TestVal * 4095) / 100;
printf("\nusing separate var: = %u -> %ld", Default_SP[i], TestVal);
|
Vs:
Code: |
printf("\ncast = %ld",(((signed int32)Default_SP[i]*4095)/100));
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Thu Jan 27, 2022 10:42 am |
|
|
They seem to have done quite a few optimisation changes around 5.100,
suspect this is from then. These are what cause the problems for me
when using the multiple interrupt levels in PCD. before this local variables
in different priority interrupts respect each other, after this they don't.
Seems they are going a little too far on some of the 'savings'... |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Thu Jan 27, 2022 11:51 am |
|
|
another one of my sources of confusion. This is right out of the CCS manual:
Quote: |
#opt
Syntax:
#opt n
Elements:
All Devices: n is the optimization level 1-9 or by using the word "compress" for PIC18
and Enhanced PIC16 families.
[PCD] All Devices: n is the optimization level 0-9
Description:
The optimization level is set with this directive. This setting applies to the entire program
and may appear anywhere in the file. The default is 9 for normal. When Compress is
specified the optimization is set to an extreme level that causes a very tight ROM image,
the code is optimized for space, not speed. Debugging with this level my be more
difficult.
Examples:
#opt5
|
I don't know what the number means. Is 0 optimized for speed or for space? And apparently "compress" is not the same as any of the #'s.
Although it would be easy to compile and see the size difference, it would have been better if they just stated it.
Luckily I've never touched that option. Chip memory sizes have increased faster than my ability to write slow, bloated code. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Thu Jan 27, 2022 11:54 am |
|
|
0 turns it off.
The point is that the problem is part of their optimisation, and they are
saying that if you use zero (so this is off), this isn't done. |
|
|
kda406
Joined: 17 Sep 2003 Posts: 97 Location: Atlanta, GA, USA
|
|
Posted: Thu Jan 27, 2022 2:06 pm |
|
|
I cannot believe I ran into this thread today.
I have been having to simplify single, complex math statements down to 2-3-4 lines since around 5.09x, Ttelmah. Statements that have worked for years through 3,x, 4.x, even in other C compliers, suddenly no longer work in 5.x and must be rewritten.
Recently, I have been struggling with interrupts. I could not understand why ISRs that had worked for years with CCS and various PIC families no longer worked. Today an ISR for INT0 stopped working. I was troubleshooting that.
I noticed I was using optimization level 9 and could not remember if that was correct. I saw the same ridiculous explanation in the manual as was quoted above. I was confused so I searched the forum and found this thread where you are discussing the same issues I'm having today. Wow.
So I changed my #opt to 0 and guess what? The ISR for INT0 that I have been troubleshooting for 3 days magically works again.
I cannot begin to total up all the lost-time troubleshooting, rewriting, and simplifying math code that used to work recently. I bet it is months of lost productivity. Frustrating!
Even so, I say thanks for the helpful discussion guys.
-Kyle |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Fri Jan 28, 2022 6:13 am |
|
|
I'm thinking, yeah..like the dinosaur I am.., that the 'optimization' default should be ZERO.
Only when a program is 'up and running', should 'optimization' be enabled, kinda like the WDT.
I'm betting no one KNOWS what happens for levels 1 thru 9, what exactly the compiler's doing or HOW it's doing it. Maybe level 4 is great for project 'x', and 7 perfect for project 'Z'.
It is scary that a feature designed to HELP programmers, actually can cause so much pain ! |
|
|
kda406
Joined: 17 Sep 2003 Posts: 97 Location: Atlanta, GA, USA
|
|
Posted: Fri Jan 28, 2022 7:28 am |
|
|
Especially considering the recent "improvements", I agree, it should be zero unless set otherwise. Good idea.
Every one of my projects includes the same header file as the first element. I'm curious about using #opt 0 as a line there.
Here is why I ask about the inline directive though. I use multiple compile units (MCU) and my larger projects have dozens of program and header files. If your code is solid and elegant it works. I use MPLabX and love it - it's the same as NetBeans that I use for C and other languages mostly for programming Windows and Linux stuff. With MPLabX, you set the project up and hidden in the project is an assignment for code optimization. It defaults to 9. It passes this as a CL parameter to the compiler (and linker?) as it builds the project. The projects are setup automatically and I will need to remember to punch in and change the optimization parameter on every project.
Do any of you know: If I put #opt 0 in the configuration header of every compile unit and MPLabX passes the default CL parameter of 9, which one will "win" and be used for the build? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Jan 28, 2022 8:37 am |
|
|
Hm. I'd have expected the ones 'in code' to override the ones on the build
line. However the answer would probably be to test. You can usually see
changes in the OPT level in the build size, so see if the code gets a little
larger with the optimisation turned down in code. If it does, you know
which has priority. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Fri Jan 28, 2022 8:45 am |
|
|
hmmmm I wouldn't guess (it'd be wrong...Murphy's Laws..)
yes, try a small program and see what happens... |
|
|
kda406
Joined: 17 Sep 2003 Posts: 97 Location: Atlanta, GA, USA
|
|
Posted: Fri Jan 28, 2022 9:00 am |
|
|
GOOD NEWS
I was hoping one of you guys could just tell me...
This morning I'm working on a project with just a few compile units. No math to simplify like the OP for this thread, but this one does have the ISR routines that work with optimize set to 0 and simply do not work (at all) when set to 9.
I put #opt 0 as the first line of the single config header that is included in every compile unit. I made sure the project (IDE) was set for the default 9, and verified the CL arguments passed to the compiler included +Y=9.
In my experiment, the #opt 0 line takes precedence over the command line for PCH 5.107. That's good news for what temtronic mentioned above where the optimization could be different for different projects. This will allow us to embed the best optimization for a project right into the code. I believe that will be better than worrying about potential changes in our IDE affecting CL parameters in the future.
HTH,
Kyle |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|