The firmware I inherited which was originally compiled on version 3.1.1 uses a number of double floating point numbers/calculations. When switching to V21.6 or V21.6.1 compiler a simple double calculation does not work. Is this a known problem?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
The firmware I inherited which was originally compiled on version 3.1.1 uses a number of double floating point numbers/calculations. When switching to V21.6 or V21.6.1 compiler a simple double calculation does not work. Is this a known problem?
No error, just the result I get is not correct. Expected result is .018675 and what I get is -8.8 E+82. When I use the old compiler I get the expected result.
Thanks for your reply.
Hi Martin,
If you step through the code in debug mode do you see correct intermediary results?
If you are comfortable with it and its not proprietary, could you share the code relevant to the floating point calculations you are doing? There is a code block tool under the Insert option when you post that will format C code for readability.
Best Regards,
Brandon Fisher
So what started me on this journey was that the two doubles being calculated are actually constants that were being calculated every time the function was called (and wasting RAM at the same time). I have just finished making the calculation a constant and to my surprise the resulting double constant is the correct value. So a compile time double calculation is done correctly but a run time calculation using RAM is not. Below are the constant assignments and the two calculations.
const unsigned int analogInputCounts1 = 5788; // counts (around 5761) const float analogInputConc1 = 0.5; // The ppm used for analogInputCounts1. const unsigned int analogInputCounts2 = 59308; // counts (around 59066) const float analogInputConc2 = 1000; // The ppm used for analogInputCounts2; const double conc_slope = (analogInputConc2 - analogInputConc1) / (float)(analogInputCounts2 -analogInputCounts1); // v2.0.0 moved float outside () const double conc_yInt = analogInputConc2 - conc_slope * analogInputCounts2;// **double
Hi Martin,
Are you printing out/using the values somewhere to determine that the calculations are done incorrectly, or viewing this in the watch window of CCS during run time?
Best Regards,
Brandon Fisher
Brandon,
I am using the watch window. When I changed slope and yInt to const double they were correct in the watch window. Also when I compiled using ver 3.1.1 they were correct in the watch window (non constants at the time I did this). One other thing I have noticed is that the execution time of floating point calculations runs almost 10 times longer when compiled with ver 21.6. The code that I inherited has both float and double in multiple places. My team is adding a function that will be using float so I would like to understand what is going on and why the difference between the old and new compiler.
Thanks,
Marty
Hi Marty
If you are verifying these in the CCS watch window you may also want to declare them as volatile to ensure that this isn't occurring due to optimization.
One other thing I have noticed is that the execution time of floating point calculations runs almost 10 times longer when compiled with ver 21.6. The code that I inherited has both float and double in multiple places. My team is adding a function that will be using float so I would like to understand what is going on and why the difference between the old and new compiler.
I don't expect floating point operations to be exactly quick on the MSP430, typically we recommend avoiding them, but a 10x difference between these compiler versions seems quite large. For my reference how are you measuring this?
Because v3.1.1 is so far back, it would be difficult to pin point what change/changes could be causing this just by looking at differences between compiler versions. You may have to do some legwork here by comparing the disassembly generated between the two compiler versions to see if they differ significantly. If you were going to go that route I would also recommend doing this on the absolute minimum code base that recreates this issue (i.e. just your floating point math). Before you went this far though you could also compare your project settings, although I don't have knowledge of any specific setting or compiler option that could cause this.
Best Regards,
Brandon Fisher
Brandon,
To measure the time of the floating point I toggle a port pin high before and low after and use a scope to measure the time. Here is the section of code I am measuring:
concentration = - 0.26137
+ 0.89325*concentration
+ 0.00899554*concentration*concentration
- 0.0001734*concentration*concentration*concentration;
Here is the disassembly using Ver 3.1.1:
90 concentration = - 0.26137
1dea: 403C AC08 MOV.W #0xac08,R12
1dee: 403D 3F64 MOV.W #0x3f64,R13
1df2: 411E 0004 MOV.W 0x0004(SP),R14
1df6: 411F 0006 MOV.W 0x0006(SP),R15
1dfa: 12B0 5174 CALL #__fs_mpy
1dfe: 403E D24A MOV.W #0xd24a,R14
1e02: 403F BE85 MOV.W #0xbe85,R15
1e06: 12B0 3DF6 CALL #_fs_add
1e0a: 4C09 MOV.W R12,R9
1e0c: 4D0A MOV.W R13,R10
1e0e: 403C 6208 MOV.W #0x6208,R12
1e12: 403D 3C13 MOV.W #0x3c13,R13
1e16: 411E 0004 MOV.W 0x0004(SP),R14
1e1a: 411F 0006 MOV.W 0x0006(SP),R15
1e1e: 12B0 5174 CALL #__fs_mpy
1e22: 411E 0004 MOV.W 0x0004(SP),R14
1e26: 411F 0006 MOV.W 0x0006(SP),R15
1e2a: 12B0 5174 CALL #__fs_mpy
1e2e: 4C0E MOV.W R12,R14
1e30: 4D0F MOV.W R13,R15
1e32: 490C MOV.W R9,R12
1e34: 4A0D MOV.W R10,R13
1e36: 12B0 3DF6 CALL #_fs_add
1e3a: 4C09 MOV.W R12,R9
1e3c: 4D0A MOV.W R13,R10
1e3e: 403C D2B5 MOV.W #0xd2b5,R12
1e42: 403D 3935 MOV.W #0x3935,R13
1e46: 411E 0004 MOV.W 0x0004(SP),R14
1e4a: 411F 0006 MOV.W 0x0006(SP),R15
1e4e: 12B0 5174 CALL #__fs_mpy
1e52: 411E 0004 MOV.W 0x0004(SP),R14
1e56: 411F 0006 MOV.W 0x0006(SP),R15
1e5a: 12B0 5174 CALL #__fs_mpy
1e5e: 411E 0004 MOV.W 0x0004(SP),R14
1e62: 411F 0006 MOV.W 0x0006(SP),R15
1e66: 12B0 5174 CALL #__fs_mpy
1e6a: 4C0E MOV.W R12,R14
1e6c: 4D0F MOV.W R13,R15
1e6e: 490C MOV.W R9,R12
1e70: 4A0D MOV.W R10,R13
1e72: 12B0 3DF0 CALL #__fs_sub
1e76: 4C81 0004 MOV.W R12,0x0004(SP)
1e7a: 4D81 0006 MOV.W R13,0x0006(SP)
Here is the same section using ver 21.6:
08c: 411C 0008 MOV.W 0x0008(SP),R12
2090: 411D 000A MOV.W 0x000a(SP),R13
2094: 12B0 7ABC CALL #__mspabi_cvtfd
2098: 4C08 MOV.W R12,R8
209a: 4D09 MOV.W R13,R9
209c: 4E0A MOV.W R14,R10
209e: 4F0B MOV.W R15,R11
20a0: 403C DD2F MOV.W #0xdd2f,R12
20a4: 403D 0624 MOV.W #0x0624,R13
20a8: 403E 9581 MOV.W #0x9581,R14
20ac: 403F 3FEC MOV.W #0x3fec,R15
20b0: 12B0 4180 CALL #__mspabi_mpyd
20b4: 4C08 MOV.W R12,R8
20b6: 4D09 MOV.W R13,R9
20b8: 4E0A MOV.W R14,R10
20ba: 4F0B MOV.W R15,R11
20bc: 403C F40A MOV.W #0xf40a,R12
20c0: 403D 3C89 MOV.W #0x3c89,R13
20c4: 403E BA49 MOV.W #0xba49,R14
20c8: 403F BFD0 MOV.W #0xbfd0,R15
20cc: 12B0 1100 CALL #__mspabi_addd
20d0: 4C81 000C MOV.W R12,0x000c(SP)
20d4: 4D81 000E MOV.W R13,0x000e(SP)
20d8: 4E04 MOV.W R14,R4
20da: 4F06 MOV.W R15,R6
20dc: 411C 0008 MOV.W 0x0008(SP),R12
20e0: 411D 000A MOV.W 0x000a(SP),R13
20e4: 12B0 7ABC CALL #__mspabi_cvtfd
20e8: 4C08 MOV.W R12,R8
20ea: 4D09 MOV.W R13,R9
20ec: 4E0A MOV.W R14,R10
20ee: 4F0B MOV.W R15,R11
20f0: 403C FE32 MOV.W #0xfe32,R12
20f4: 403D F0E0 MOV.W #0xf0e0,R13
20f8: 403E 6C40 MOV.W #0x6c40,R14
20fc: 403F 3F82 MOV.W #0x3f82,R15
2100: 12B0 4180 CALL #__mspabi_mpyd
2104: 4C08 MOV.W R12,R8
2106: 4D09 MOV.W R13,R9
2108: 4E0A MOV.W R14,R10
210a: 4F05 MOV.W R15,R5
210c: 411C 0008 MOV.W 0x0008(SP),R12
2110: 411D 000A MOV.W 0x000a(SP),R13
2114: 12B0 7ABC CALL #__mspabi_cvtfd
2118: 450B MOV.W R5,R11
211a: 12B0 4180 CALL #__mspabi_mpyd
211e: 4118 000C MOV.W 0x000c(SP),R8
2122: 4119 000E MOV.W 0x000e(SP),R9
2126: 440A MOV.W R4,R10
2128: 460B MOV.W R6,R11
212a: 12B0 1100 CALL #__mspabi_addd
212e: 4C81 000C MOV.W R12,0x000c(SP)
2132: 4D81 000E MOV.W R13,0x000e(SP)
2136: 4E04 MOV.W R14,R4
2138: 4F05 MOV.W R15,R5
213a: 411C 0008 MOV.W 0x0008(SP),R12
213e: 411D 000A MOV.W 0x000a(SP),R13
2142: 12B0 7ABC CALL #__mspabi_cvtfd
2146: 4C08 MOV.W R12,R8
2148: 4D09 MOV.W R13,R9
214a: 4E0A MOV.W R14,R10
214c: 4F0B MOV.W R15,R11
214e: 403C 4169 MOV.W #0x4169,R12
2152: 403D A883 MOV.W #0xa883,R13
2156: 403E BA56 MOV.W #0xba56,R14
215a: 403F 3F26 MOV.W #0x3f26,R15
215e: 12B0 4180 CALL #__mspabi_mpyd
2162: 4C08 MOV.W R12,R8
2164: 4D09 MOV.W R13,R9
2166: 4E0A MOV.W R14,R10
2168: 4F06 MOV.W R15,R6
216a: 411C 0008 MOV.W 0x0008(SP),R12
216e: 411D 000A MOV.W 0x000a(SP),R13
2172: 12B0 7ABC CALL #__mspabi_cvtfd
2176: 460B MOV.W R6,R11
2178: 12B0 4180 CALL #__mspabi_mpyd
217c: 4C08 MOV.W R12,R8
217e: 4D09 MOV.W R13,R9
2180: 4E0A MOV.W R14,R10
2182: 4F06 MOV.W R15,R6
2184: 411C 0008 MOV.W 0x0008(SP),R12
2188: 411D 000A MOV.W 0x000a(SP),R13
218c: 12B0 7ABC CALL #__mspabi_cvtfd
2190: 460B MOV.W R6,R11
2192: 12B0 4180 CALL #__mspabi_mpyd
2196: 4118 000C MOV.W 0x000c(SP),R8
219a: 4119 000E MOV.W 0x000e(SP),R9
219e: 440A MOV.W R4,R10
21a0: 450B MOV.W R5,R11
21a2: 12B0 844E CALL #__mspabi_subd
21a6: 12B0 6EE6 CALL #__mspabi_cvtdf
21aa: 4C81 0008 MOV.W R12,0x0008(SP)
21ae: 4D81 000A MOV.W R13,0x000a(SP)
As you can see there is a significant increase.
Thanks,
Marty
Hi Marty,
What are your optimization settings for both projects? This should be viewable under the project properties.
Also can you check your build options under the MSP430 Compiler tab for both projects?
There appears to be some additional handling/checking going on behind the scenes here based on your shared disassembly.
Best Regards,
Brandon Fisher
Brandon,
The first two are for version 3.3.1 and the second two are for 21.6.1.
Thanks,
Marty
Hi Marty,
It looks like the first two images are the same, but I see that the use_hw_mpy flag is set to none in your last image, but not present in the first two. Can you try to remove this flag and see if it changes the compiler generated code?
I wouldn't expect this to be too relevant for floating point math, but it seems like a compiler/project difference we shouldn't ignore given the nature of your problem.
Best Regards,
Brandon Fisher
Brandon,
I just removed the use_hw_mpy flag statement and it did not effect the disassembly code at all. I even check the calculation time and it was the same. By the way I forgot to mention the times I am seeing for the ver3.3.1 compiler it is 2.85mS and for the ver21.6 compiler it is 33.45mS,
Regards,
Marty
Hi Marty,
Even with the difference in operations shown in disassembly, a 10x difference like that looks like this is has to be due to real changes in the way the float math operations are handled in the compiler. I think its unlikely to change in any way, as float operation execution time isn't a big priority for simpler embedded devices like this without an FPU. You could continue to use V3, but in the 18 or so compiler version updates that have occurred since v3, there have been numerous bug fixes and workarounds.
You might consider switching to an IQMATH based implementation of this code. If execution time is critical, you could also try increasing your optimization level to try and get the program as a whole running faster.
Best Regards,
Brandon Fisher
Brandon,
Thanks for all your input. I looked at the IQMATH page and it doesn't list the MSP430FG479 as being supported. Am I correct?
Thanks,
Marty
Hi Marty,
Good catch, I'm checking to make sure this is the case, but if so you would have to do some manual handling to avoid doing float math here.
Best Regards,
Brandon Fisher
**Attention** This is a public forum