1. Background
Zephyr Project Flash and RAM space is tight, with very strong optimization requirements.
The premise of optimization is to quantify the target, then how to quantify the amount of flash and RAM usage?
After quantification, the quantification results are analyzed first, then the measures are taken to optimize the space.
2. Flash/ram usage based on elf information and Linker.cmd analysis
The Linker.cmd file specifies whether different sections are in Flash or in RAM, or both.
This is a very useful information, based on which we only need to list each section of the symbol, and then the size of the statistics, you can know the section information, and then know that there are those symbol in (Flash, Ram), and how big.
The analysis of ELF files allows for detailed information on sections and symbols.
The sections information can correspond to the sections index and name.
The symbols information can correspond to the index of the symbol name, Size, index, and sections.
This way you can form a elf-->sections-->symbols tree-like relationship to the elf file.
Analysis script in: ELF_ANALYZE_PRO.IPYNB.
The output is a CSV file in descending order of symbol size in each sections, and displays a list of up to top_counts sizes.
3. Analysis of the use of Flash/ram
From the Flash/ram total size usage, you can see RAM space emergency, flash space is not optimistic.
Since each section arranges all the symbol tables in descending order, the maximum starting effect is most noticeable.
At the same time, different sections have their own characteristics, a. Only in RAM, or B. In flash only, or C. Both are occupied.
The primary goal of optimization is the C case, which is best if it can be removed from RAM and used only in Flash. But it will certainly slow down.
Secondly, to optimize a case, the static variable is changed into dynamic allocation. Allocating waste to variables: unwanted struct members, variable type compactness, and so on.
The last is the B case, the redundant log information is removed, the inline type function is changed to the normal function and so on.
4. Optimize record 4.1 to transfer variables from datas to rodata through const-Modified variables
Since section datas takes up both Flash and SRAM, there are variables that can be modified to be const types, which are read-only variables.
This symbol can be transferred to the Rodata area, which is read from Flash when used.
4.2 Dynamically request memory from the Mem pool via K_malloc
The application of static large variables, simple and easy to mistake, but wasted a limited amount of RAM space.
If you can apply from the mem pool via K_malloc, it will help improve the utilization of SRAM.
4.3 Deleting redundant struct members
For example, many members of struct UART_DRIVER_API are not implemented and will not be used. Commenting out some of these members helps reduce the size of the struct instance.
4.4 Variable over-provisioning case
A flag bit this situation is not necessary to use int32 such a type.
4.5 The abandonment of inline type functions
In systems with slower CPU speeds but larger ROM space, using inline helps to take advantage of space-time.
But in a system with very tight space, this becomes a disadvantage. Removing the inline modifier, which is a normal function, saves space, although it increases the cost of the function call.
4.6 Controlling log usage
Log has a rating, so unnecessary logs do not need to be compiled.
When it comes to mass production, the log is closed and the space saved is considerable.
5. Conclusion
Of course, there is no end to the optimized road, while walking and recording it.
Example of using Python to analyze elf files to optimize flash and SRAM space