When writing code, especially embedded code, the optimization method that can be thought of is generally to set the optimization level of the compiler. Or consider the scope of use of the variable when defining the variable, and then choose a more suitable data type based on the data range. However, this optimization method is relatively vague and there is no intuitive feeling. In order to make the optimization of the code more intuitive, today we will use the map file to optimize the code.
Let's first look at a simple example.
This is a very simple test code, which makes the LED light flash in the main program and adds 0.1 to the x variable each time. Does this code need to be optimized? Don't worry, open the map file generated in the project first and take a look.
The map file is in the List folder in the debug folder of the project directory. Use Notepad to open this file.
In the middle of the file, there is a section that shows the space occupied by each target file. Look down one by one to find a few locations that occupy a larger amount of space.
It can be found that the object file float.o occupies a large space compared to other files. So where does this float.o file come from? Seeing float, we can probably guess that this is a floating point related file. There is only one place in the program that uses floating point operations.
Can this line of code take up so much space? Then try changing the floating point operation to an integer operation.
Expand x by 10 times, then add 1 each time. Compile the code and reopen the map file to view it.
At this time, you will find that the float.o file in front of long.o has disappeared. This shows that the float.o file just now was generated by the floating-point operation in the code. Through the observation of the map file, we can draw a conclusion that floating-point operations occupy a lot of space in the microcontroller, so try to convert floating-point operations into integer operations. Otherwise, if the amount of floating-point operations is relatively large, the space of the microcontroller will soon be filled up.
Next, print out the value of the variable through the serial port.
Observe the printed value through the serial port assistant
The values printed by the serial port are also normal. Next, continue to check the map file.
In the map file, you can see that there are several more files before and after the long.o file, and they take up a lot of space.
Why is there a very large float.o file? This is because the printf function supports floating point printing. There are floating point numbers in the function, so a float.o file is generated. xprintffull_nomb.o is also generated when the printf function is called.
As can be seen, the printf function takes up a lot of space. Try to avoid using the printf function in the program. So what should we do when we want to print data? We can use the default output function of the microcontroller serial port to print characters, but there is a new problem. The serial port output is in character format. Now we want to print integers. How to convert integers into character format? We can use a custom function to convert numbers into strings first, and then output the strings through the serial port.
First, write a function that converts an integer to a string.
void int2str(int n, char *str)
{
char buf[10] = "";
int i = 0;
int len = 0;
int temp = n < 0 ? -n: n; // temp is the absolute value of n
if (str == NULL)
{
return;
}
while(temp)
{
buf[i++] = (temp % 10) + '0'; //Store each bit of temp into buf
temp = temp / 10;
}
len = n < 0 ? ++i: i; //If n is a negative number, one more bit is needed to store the negative sign
str[i] = 0; //The end is the terminator 0
while(1)
{
i--;
if (buf[len-i-1] ==0)
{
break;
}
str[i] = buf[len-i-1]; //Copy the characters in the buf array to the string
}
if (i == 0 )
{
str[i] = '-'; //If it is a negative number, add a minus sign
}
}
Next, write serial port related functions.
//Send a single character
void SendChar( unsigned char dat )
{
while( ( UART1_SR & 0x80 ) == 0x00 ); //Send data register empty
UART1_DR = date;
}
//Send string
void SendString( unsigned char* s )
{
while( 0 != *s )
{
SendChar( *s );
s++;
}
}
Modify the main function code below.
void main( void )
{
int x = 10;
char str[100] = {0};
__asm( "sim" ); //Disable interrupts
SysClkInit();
delay_init( 16 );
LED_GPIO_Init();
Uart1_IO_Init();
Uart1_Heat( 9600 );
__asm( "rim" ); // Enable interrupt
while( 1 )
{
LED = ~LED;
x += 1;
int2str(x,str);
SendString(str);
SendString("rn");
delay_ms( 1000 );
}
}
First, the variable x is converted to a string using the int2str function, then the string is printed out using the SendString function, and finally SendString is called again to print the carriage return and line feed characters. The printing effect is as follows:
Next, let's take a look at the space occupied by the map file.
From the map file, we can see that compared with directly using the printf function, using a custom function to implement the printing function saves a lot of space. By observing the target file size in the map file, we can intuitively see the specific difference between the optimized code and the unoptimized code during the program optimization process. In this way, we will have a clear plan in the process of debugging the code, and will not be like a headless fly bumping around.
Previous article:Using STM8 microcontroller + NTC thermistor to make a simple temperature inspection instrument
Next article:Check the code size in IAR software
Recommended ReadingLatest update time:2024-11-15 17:26
- Popular Resources
- Popular amplifiers
- STM8 C language programming (1) - basic program and startup code analysis
- Description of the BLDC back-EMF sampling method based on the STM8 official library
- STM32 MCU project example: Smart watch design based on TouchGFX (8) Associating the underlying driver with the UI
- uCOS-III Kernel Implementation and Application Development Practical Guide - Based on STM32 (Wildfire)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Design of greenhouse temperature and humidity monitoring and alarm system based on zigbee
- Keysight Material Dielectric Constant Test Method - Just Read the Content
- Sound pressure, sound intensity and sound power
- Proteus MSP430 MCU simulation example 8-2-bit digital tube countdown
- The TouchGFX Designer is a real pain
- How to implement analog serial communication with TI MSP430
- ffmpeg port on at91sam9261ek
- How to understand the automatic reload function of the timer
- Things to note when using peelable adhesive
- Last day! TI Live Broadcast with Prizes | Application of Precision ADC in Transmitters