首页 > 系统相关 >使用nm分析eCos应用的内存使用情况

使用nm分析eCos应用的内存使用情况

时间:2022-11-21 10:06:12浏览次数:38  
标签:nm 符号 app elf 内存 eCos size


eCos是开源免版税的抢占式实时操作系统。其最大亮点是可配置,与其配套的图形化配置工具提供组件管理、选项配置、自动化单元测试等。

嵌入式系统的内存资源是非常有限的,如果配置不当可导致eCos应用程序因为存储空间不足而链接失败。解决这个问题的办法可以是增加更多的内存或者是减少软件对内存资源的使用,通常是后一种办法。既然要减少内存使用量,那么首先要找出都是哪些变量吃光了内存,就是说要对映像符号进行分析,找出最占内存的变量,看看能否避免使用该变量或减少该变量的占用容量。GNU工具链中的nm就是做这个事情用的,按照用户手册的说法,nm是用来解析映像符号的,包括符号使用容量和所在的文件。

查找最占内存变量

$ nm --print-size --line-numbers --size-sort app.elf | grep " [dDbB] "
......
10004154 00000800 b var_data /cygdrive/f/ecos/hg/packages/net/lwip_tcpip/current/src/ecos/sys_arch.c:84
10002fb0 00000b00 b timer_table
10001f98 00001000 b main_stack
10004994 00001800 b stack_data /cygdrive/f/ecos/hg/packages/net/lwip_tcpip/current/src/ecos/sys_arch.c:95
2007c000 000018b8 b emac_ahb_ram /cygdrive/f/ecos/hg/packages/devs/eth/arm/lpc2xxx/current/src/if_lpc2xxx.c:357
20080388 0000283b b memp_memory /cygdrive/f/ecos/hg/packages/net/lwip_tcpip/current/src/core/memp.c:146

--print-size:打印符号符号占用内存量;--line-numbers:打印符号所在的源文件名及行号;--size-sort:以符号占用内存量来排序;app.elf:eCos应用映像文件名。输出内容按列分别为:符号地址、符号占用内存量、符号类型、所在文件及行号。grep的作用是过滤不需要的符号,我们这里仅需要存储在RAM中的变量,将常量和函数等过滤掉,注意grep参数的引号和方括号之间有空格。输出结果按照变量内容占用量排序输出,最后输出的是占用量最大的变量。从上面的输出可以看出memp_memory占用的内存最多,通过文件名可以判断这是lwIP内存池,修改lwIP配置减少连接数和缓存数目等可以减少该变量的内存占用量。

链接失败时的办法

如果容量超限,压根就不能编译完成,也就谈不上映像文件了,这时候可以修改target.ld文件,修改内存容量,内存容量可以修改成比目标机实际容量更大的值,修改target.ld的目的是可以正确地生成映像文件然后使用nm来分析内存使用情况并进行调整,而不是下载到目标机运行,如果target.ld设定的内存容量比目标机实际内存容量大,即使下载到目标机也不能正常运行。根据nm输出结果及应用需求调整内存使用量,当映像使用的内存容量小于目标机实际内存容量后,恢复target.ld的内存容量设置。

使用size查看总内存量

nm打印出每个符号占用的内存量,而size打印映像的总内存量,可以使用size输出快速判断容量是否超限的问题,size还可以显示srec和ihex格式的映像容量。

$ size app.elf
text data bss dec hex filename
158712 1852 43503 204067 31d23 app.elf

使用哪个nm?

nm和size只是对ELF格式的映像文件符号和加载段进行分析,因此跟硬件架构没多大关系,使用nm或arm-eabi-nm的效果是一样的,如果不放心,那就用arm-eabi-nm吧,size同理。

nm常用参数

-C, --demangle 

逆向解析C++符号转换,编译C++源代码时,会将C++符号转换成符号汇编器要求的符号,如果不对C++符号进行逆向解析,那么看到的是汇编符号而不是C++源文件中的符号名。

使用该参数前,输出汇编符号,晦涩难懂

$ arm-eabi-nm app.elf
......
00006adc T _ZN10Cyg_Thread5delayEy
......

使用该参数后,输出C++符号,与源文件符号一致

$ arm-eabi-nm -C app.elf
......
00006adc T Cyg_Thread::delay(unsigned long long)
......

-l, --line-numbers

输出符号所在的文件名和行号。

使用该参数前

$ arm-eabi-nm app.elf
......
0001a0c4 T write

使用该参数后,行尾追加文件名和行号

$ arm-eabi-nm -l app.elf
......
0001a0c4 T write /cygdrive/f/ecos/hg/packages/io/fileio/current/src/io.cxx:169

-S, --print-size

输出符号占用内存量。

使用该参数前

$ arm-eabi-nm app.elf
......
0001a0c4 T write

使用该参数后,第2列数字为符号占用内存量

$ arm-eabi-nm -S app.elf
......
0001a0c4 00000034 T write

-n, --numeric-sort

输出结果按照符号地址排序。

使用该参数前

$ arm-eabi-nm app.elf
......
000202c8 T udp_sendto_if
00018ec0 t update_arp_entry
10004154 b var_data
1000497c b var_handle
10004954 b var_mempool
00009a60 T vfnprintf
0001a0c4 T write

使用该参数后,根据第1列数值排序

$ arm-eabi-nm -n app.elf
......
100070b0 A __heap1
10007fe0 A hal_startup_stack
2007c000 A __ahb_sram0_start
2007c000 b emac_ahb_ram
2007d8b8 A __ahb_sram0_end
20080000 A __ahb_sram1_start
20080000 b ram_heap
20080388 b memp_memory
20082bc3 A __ahb_sram1_end

--size-sort

按照内存使用量排序。

使用该参数前

$ arm-eabi-nm -S app.elf
......
10004154 00000800 b var_data
1000497c 00000004 b var_handle
10004954 00000028 b var_mempool
00009a60 000015f4 T vfnprintf
0001a0c4 00000034 T write

使用该参数后,根据第2列数值进行排序

 

$ arm-eabi-nm -S --size-sort app.elf
......
10001f98 00001000 b _ZL10main_stack
0001cf38 000011dc t tcp_receive
00009a60 000015f4 T vfnprintf
10004994 00001800 b stack_data
2007c000 000018b8 b emac_ahb_ram
20080388 0000283b b memp_memory

 

标签:nm,符号,app,elf,内存,eCos,size
From: https://blog.51cto.com/zoomdy/5872658

相关文章

  • eCos中断响应详解,基于Cortex-M架构
    本文阐述eCos在Cortex-M架构中的中断响应过程。eCos是开源免版税的抢占式实时操作系统。其最大亮点是可配置,与其配套的图形化配置工具提供组件管理、选项配置、自动化单元测......
  • eCos启动过程详解,基于Cortex-M架构
    eCos是开源免版税的抢占式实时操作系统。其最大亮点是可配置,与其配套的图形化配置工具提供组件管理、选项配置、自动化单元测试等。eCos核心组件包括硬件抽象层(HAL)、设备驱......
  • eCos Synthetic实践(二)——简单外设
     1. 简介SyntheticTarget同样包含多种硬件设备,当然它们都是虚拟的,其中一部分设备通过Linux系统调用就可以实现,不需要I/O辅助进程的参与,这类设备包括Disk、ADC、Flash、......
  • eCos Synthetic实践(一)——Hello World!
     1. 简介eCos提供了LinuxSyntheticTarget,通过SyntheticTarget可以将eCos应用作为一个普通进程在Linux系统内运行,这既提供了体验eCos的机会又不需要繁琐的硬件准备工作......
  • eCos需要Synthetic虚拟目标板的理由
     eCos提供了Synth虚拟目标板(SyntheticTarget),为什么要使用虚拟目标板呢? 1. 在没有硬件的条件下学习eCoseCos是非常优秀的嵌入式操作系统,如果希望学习eCos但是又没有开发......
  • 操作系统--内存管理--上
    用户希望的程序:分段放入;操作系统希望的程序:分页存储;单级分页存储会导致分页表的开销大,引出了多级分页和快表的概念:(类似于目录当中的--章--节--和--书签(记录最近访问)--);一......
  • 操作系统--内存管理--下
    内存换入 从缺页中断开始,找到一个物理内存的空页,将目标换进;内存换出(局部性规律--程序局部性原理--数据局部性)内存<-->门店磁盘<-->仓库当门店没有用户想要的货......
  • linux释放buff/cache缓存内存
    echo3>/proc/sys/vm/drop_caches------释放buff/cache缓存内存echo0是不释放缓存echo1是释放页缓存ehco2是释放dentries和inodes缓存echo3是释放1和2中说......
  • Redis系列11:内存淘汰策略
    Redis系列1:深刻理解高性能Redis的本质Redis系列2:数据持久化提高可用性Redis系列3:高可用之主从架构Redis系列4:高可用之Sentinel(哨兵模式)Redis系列5:深入分析Cluster集......
  • 2.6.3 变量内存单元地址
    变量存储在哪里变量内存单元地址代码实现#include<iostream>usingnamespacestd;intmain(){ intn; floatf; doubled=1.23;//0.0 charc='*'; cout......