Dear all,
I have an experience to develop C code for different microcontrollers and DSPs. However, this is first time to develop code for Arm Core microcontrollers. I am using STM32F334 and STM32F745 for different projects. Last couple of weeks, I have learnt to control peripherals and I hadn't calculated any mathematical expression. I started to write mathematical calculations and I realized they took a lot of time.
For example:
uint16_t Middle, Low, High;
--------------------
Middle = ((Low + High) * 0.5);
This code takes ~6.25us. Actually, it adds two unsigned integer and one floating point multiplication. It should be very fast because STM32F334 has FPU. I used this code for Texas Instrument TMS320F335. (Texas Complier understand 0.5 is floating and no need to declared again.) I searched on internet and I revised some sample codes and I realized that I should write (float)0.5 or 0.5f. Then I changed the code as like below:
Middle = ((Low + High) * 0.5f);
This new code takes 259ns. Which is ~24 times faster than previous code. (I have developed many codes for TMS320F28335 and they worked well. I thought it was in C and this is also in C languages and it should work.) One letter makes the execution time much faster. I also tried to understand if I need to declared integer number or casting floating point number into integer number but I observed no need to do it. For example:
Middle = (uint16_t) ((Low + High) * 0.5f); is exactly consumes same time with Middle = ((Low + High) * 0.5f);
or Middle = 34; takes same time with Middle = (uint16_t)34;...
Another example:
#define Offset 5.0f
#define Correction 1.002f
volatile float Voltage;
--------------------------
Voltage = ((ADC1->DR) - Offset)*Correction;
-------------------------
ADC1->DR is 32-bit unsigned integer and all others are floating numbers. I was not sure if I have to write the code as below:
Voltage = ((float)(ADC1->DR) - Offset)*Correction;
I tried and I didn't see any difference. So, time is very crucial in my code. I have to write an optimum code as much as I can. That is why I don't use HAL function and I wrote my own functions. I searched documents to learn how to define variables or how to handle different data type in one equation. I think it is about Arm Complier and I had a look to Arm complier user guide. However, I didn't find any enough explanations.
I would like to ask you if you have a document/sample codes and etc, could you please share me.
Last thing that: if Offset is greater than 31.0f, the execution time is more than if the offset is lower than 32.0f. What is the relation?
#define Offset 32.0f It is slower... 2^5 = 32? It took few hundreds nanosecond more than if Offset is 31.0f.
Thank you very much in advance.
Regards
Dear Andy
Yes it is single precision and it is enough for my application. TMS320F28335 is also single precision and it was enough for my all applications and I guess STM32F334 and F745 are also enough with single precision FPU unit. I don't need to define any variable as double.
I don't have an experience to use Arm Complier and I don't know how to define variable or how to use different variables with different definitions. I would like to find something to read and understand well how the complier behaves.
Until now, I read some documents but they didn't explain well or I didn't understand well... I found some code from CMSIS Lib and HAL library from ST, and I saw the usage adding 'f' as a suffix to define floating numbers. I added the suffix and than measured the execution time. So I realized that Arm Compilier doesn't like a definition like Offset = 0.5; it likes Offset = 0.5f; However Texas Instrument C complier accept that Offset = 0.5; as 32 floating point variable. So that why I confused. Anyway if you or any one in the community share me a document which explain how to define variables, and use them, it would be great.
Thank you very much indeed.
Regards,
How to define variable is a standard 'C' thing - see your 'C' textbook for that.
Again, 'C' treats floating-point constant as double unless otherwise specified.
For implementation-specific details of any compiler, you need to study the compiler documentation.
For Keil / ARM: http://www.keil.com/support/man_arm.htm
EDIT
For some reason, clicking that link doesn't work - but copying & pasting it does!
Andy Neil said:clicking that link doesn't work
See: https://community.arm.com/developer/tools-software/tools/f/keil-forum/45120/posting-links-to-keil-site-not-working
Sorry for my late answer. After the clues that you gave to me, I made extra searches and I got the point. Thank you for that. As conclusion, it is about initialization and as you said that "C' treats floating-point constant as double unless otherwise specified."
I found two web pages in addition of your explanations. They explain what I ask and what is the answer. I gave these links below for future needs of other community members.
1- https://stackoverflow.com/questions/32266864/make-c-floating-point-literals-float-rather-than-double
It is clear from the link above that gcc complier has a feature to accept all floating-point constant as single precision floating number instead of double. I guess Texas Instrument C compiler has a similar feature and I used this feature without knowing. That is why I was confused, because I used same definition with TI complier in C language and It works perfectly.
2- http://www.cplusplus.com/doc/tutorial/constants/
This link explains how to initialize variables properly.
Thank you again for your kind help.
In an unrelated search, I stumbled across this - which addresses the same issue:
https://mcuoneclipse.com/2019/03/29/be-aware-floating-point-operations-on-arm-cortex-m4f/