LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

使用Python分析ELF文件优化Flash和Sram空间的案例

1. 背景

Zephyr项目Flash和Ram空间比较紧张,有着非常强烈的优化需求。

优化的前提是量化标的,那么如何量化Flash和Ram的使用量呢?

在量化之后,首先要对量化结果进行分析,然后采取措施进行空间优化。

2. 基于ELF信息和linker.cmd分析Flash/Ram使用量

linker.cmd文件中规定了不同section在Flash还是在Ram中,还是兼而有之。

这是一个很有用的信息,基于此我们只需要去罗列每个section的symbol,然后统计大小;就可以知道section的信息;进而知道都有那些symbol在(Flash, Ram)中,都与多大。

 

分析ELF文件可以获得Sections和Symbols的详细信息。

Sections信息可以将,Sections的Index和Name对应起来。

Symbols信息可以将Symbol的Name、Size、Index和Sections的Index对应起来。

这样子就可以对ELF文件形成ELF-->Sections-->Symbols的树形结构关系。

分析脚本在:elf_analyze_pro.ipynb

输出结果是每个sections中symbol大小降序排列的csv文件,和显示最高top_counts个大小列表。

 

 

 

3. 分析Flash/Ram使用情况

3.1 总体使用情况分析

从Flash/Ram总大小使用情况,可以看出Ram空间告急,Flash空间也不乐观。

由于每个Section按降序排列了所有符号表,所以从最大入手效果最明显。

 

同时不同Section都有自己的特性,是A.仅在Ram中,还是B.仅在Flash中,还是C.两者都占用。

优化的首要目标是C情况,如果能将其从Ram中移出,仅在Flash中使用,那最好不过了。不过肯定会降低速度。

其次优化A情况,静态变量改成动态分配。针对变量分配浪费情况:不需要的结构体成员、变量类型紧凑等等。

最后是B情况,去掉冗余Log信息,将inline类型函数改成普通函数等等。

3.2 逐section、symbol分析

输出详细信息到Excel中,便于逐个排除。

3.3 查看symbol细节汇编和C混合

 提供查看某一符号详细信息:

#################################### iface_cb ####################################
0ffc299c <iface_cb>:
{
ffc299c:    b510          push    {r4, lr}
router = net_if_ipv6_router_find_default(iface, NULL);
ffc299e:    2100          movs    r1, #0
ffc29a0:    f7fa fb4e     bl    ffbd040 <net_if_ipv6_router_find_default>
}
ffc29a4:    bd10          pop    {r4, pc}

0ffc29a6 <net_shell_cmd_mem>:

 

4. 优化记录

4.1 通过const修饰变量,将变量从datas转移到rodata

由于Section datas既占用了Flash又占用了Sram,存在一些变量可以修改成const类型,即只读变量。

就可以将此Symbol转移到rodata区域,使用的时候从Flash读取。

4.2 通过k_malloc从mem pool中动态申请内存

申请静态大变量,简单省事不易错,但是浪费了有限的Ram空间。

如果可以通过k_malloc从Mem pool中申请,将有助于提高Sram的利用率。

4.3 删除冗余结构体成员

比如struct uart_driver_api中很多成员,没有实现,也不会使用到。将其中部分成员注释掉,有助于降低结构体实例大小。

4.4 使用尽量小的数据类型

一个标志位这种情况就没有必要使用int32这样的类型了。

4.5 inline类型函数的废弃

在CPU速度较慢但是ROM空间较大的系统中,使用inline有助于利用空间换时间。

但是在空间非常紧张的系统中,这就变成了缺点。将inline修饰符去掉,该成普通函数,将节省空间,虽然会增加函数调用开销。

4.6 控制Log使用量

Log存在分级,所以不需要的Log就不需要编译。

在量产的时候,关闭Log,节省的空间非常可观。

 4.7 控制宏函数的使用

和inline类型函数相似,宏函数也是用空间换时间。这在空间紧张的系统反而是个劣势。

 

5. 结语

当然优化的路没有尽头,边走边记录吧。

 

6 补充

 1.《C语言程序代码优化11种使用方法

 

posted on 2017-10-30 17:21  ArnoldLu  阅读(2203)  评论(0编辑  收藏  举报

导航