搜索
bottom↓
回复: 96

STM32 简单两步给ST的库瘦身

  [复制链接]

出0入0汤圆

发表于 2012-6-28 15:10:26 | 显示全部楼层 |阅读模式
本帖最后由 Etual 于 2012-6-29 10:08 编辑

使用了ST的库,感觉体积有点大,点亮个 LED 使用了  2.5K flash 了。

一个简单的瘦身办法,也就是,将不使用的函数剔除,不连接进去最终的烧写文件,有用的函数连接进去,没用的函数不要。

只需要2步

设置项目属性
1,在 Linker 页的 Misc contrrols 那里添加  --remove
作用是将不使用的输入段(input sections)移除。

--remove 这个参数是Keil 默认已经开启的,所以加不加都一样 , Etual  2012-6-29 修改

2,单加上面那个是没有效果的,因为一个文件作为一个输入段的话就没效果了。
所以下面的操作是将每个函数作为一个输入段,这就可以优化了。方法是
在 C/C++ 页勾选 “One ELF Section per Function”  就可以了
优化我一般选 -02

重新编译,原来 2.5K 的程序,现在变成 1.2K 了 ......

今天摸索出来的办法,不知道有没有人发过

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出20入70汤圆

发表于 2012-6-28 15:12:59 | 显示全部楼层
顶LZ,回去试试!

出0入0汤圆

发表于 2012-6-28 15:17:13 | 显示全部楼层
确定靠谱??????

出0入0汤圆

 楼主| 发表于 2012-6-28 15:20:00 | 显示全部楼层
会有啥问题?有问题就是keil的编译器出问题了(应该是ARM的编译器)

出0入0汤圆

发表于 2012-6-28 15:20:54 | 显示全部楼层
密友什么效果呢 ,  我原来的工程里是选了ELF 那个什么的,,,,添加了 --REMOVE 后,貌似幕有变化.

出0入0汤圆

发表于 2012-6-28 15:21:02 | 显示全部楼层
第二个选型这个靠谱的,第一个没用过

出0入4汤圆

发表于 2012-6-28 15:21:19 | 显示全部楼层
iar下也是这么设置吗

出0入0汤圆

发表于 2012-6-28 15:27:15 | 显示全部楼层
IAR自动链接有用的部分,不用这么费劲

出0入0汤圆

 楼主| 发表于 2012-6-28 15:29:17 | 显示全部楼层
主要目的是剔除不用的函数,对于自己写的代码,基本没啥优化效果 .....
因为ST的库需要考虑很多芯片,所以有多余的代码,主要目的是搞掉这部分代码而已。

出0入0汤圆

发表于 2012-6-28 15:37:48 | 显示全部楼层
用IAR的飘过

出0入0汤圆

发表于 2012-6-28 15:41:38 | 显示全部楼层
楼主可以看看,只执行第二步是不是也可以实现你优化后的效果?

出0入0汤圆

发表于 2012-6-28 15:42:23 | 显示全部楼层
我有一个项目,优先必须是0,优化我一般选 -02  程序会崩溃。

出0入0汤圆

发表于 2012-6-28 16:22:39 来自手机 | 显示全部楼层
关注…

关于st程度优化减肥

出0入0汤圆

发表于 2012-6-28 16:25:34 来自手机 | 显示全部楼层
关注…

关于st程度优化减肥

出0入0汤圆

发表于 2012-6-28 17:18:34 | 显示全部楼层
这个不错。。

出0入0汤圆

发表于 2012-6-28 19:49:33 | 显示全部楼层
我用IAR,而且一般不用库。
我想,那些库都有源代码吗? 用哪些函数就抄上哪些源码不行吗? 也许这费点时间,但程序就能和库无关了啊

出0入0汤圆

发表于 2012-6-29 00:39:05 | 显示全部楼层
好的编译器,应该不会把没有用到的代码链接进去。

出0入0汤圆

发表于 2012-6-29 08:19:40 | 显示全部楼层
只有加上头文件,用到相关函数才会把代码链接进去吧??

出0入18汤圆

发表于 2012-6-29 08:28:57 | 显示全部楼层
很好很强悍!  备用!

出0入0汤圆

发表于 2012-6-29 08:46:19 | 显示全部楼层
最主要的应该还是第二部的作用

出0入0汤圆

发表于 2012-6-29 09:02:16 | 显示全部楼层
ST的程序从来没写溢出过

出0入0汤圆

发表于 2012-6-29 09:31:14 | 显示全部楼层
哈哈·谢楼主·这方法好·代码减小差不多一半了,正常运行。

出0入0汤圆

发表于 2012-6-29 09:57:10 | 显示全部楼层
最近做了个基于STM32的项目,原来代码没有任何的编译器优化,正好拿来实际测试下~
没有任何优化:code 16640(刚过16K一点点,为了这一点点就要换成32K的,不值得,必须优化!)
仅勾选<One ELF Section per Function>:code 11680
勾选<One ELF Section per Function> + 优化-02:code 9472
勾选<One ELF Section per Function> + 优化-03:code 9392
仅优化-02:code 13372
仅优化-03:code 13296

通过以上测试发现,仅仅是提高优化级别,效果不是很明显,或者说不令人满意,勾选<One ELF Section per Function> 后,效果非常好,应该是应用ST官方库进行开发来减少代码的优选考虑,不错,学习了,呵呵

出0入0汤圆

 楼主| 发表于 2012-6-29 10:09:39 | 显示全部楼层
确实,只需要第二步就OK了,多谢楼上各位的提醒,已经修改。

出0入0汤圆

发表于 2012-6-29 17:06:09 | 显示全部楼层

出0入0汤圆

发表于 2012-6-29 18:57:03 | 显示全部楼层
如果不加 One ELF Section per Function  
那么编译时 是以.c为单位的 就是这个.c文件里 哪怕只用了一个函数...整个.c里的所有函数都会被编译...

如果加了 One ELF Section per Function
那么编译时 是以函数为单位的...用一个函数就编译一个...不用的绝对不编译...

良好的程序写法的情况下...够不够选这个差别很小...

出0入0汤圆

发表于 2012-6-29 22:17:58 | 显示全部楼层
用iar就不存在这个问题,不用的函数,即使编译了也不会链接进去的

出0入0汤圆

发表于 2012-6-30 00:40:53 | 显示全部楼层
GCC的链接器好像是把源文件里的都连接进去了,所以整个文件很大
不用的库文件还是给它去掉

出0入0汤圆

发表于 2012-6-30 08:07:40 | 显示全部楼层
谢谢楼主,学习了

出0入0汤圆

发表于 2012-7-1 02:02:50 | 显示全部楼层
NICE 有用

出0入0汤圆

发表于 2012-7-1 02:36:59 | 显示全部楼层
这个得顶,有机会试试

出0入442汤圆

发表于 2012-9-16 10:35:51 | 显示全部楼层
dadatou 发表于 2012-6-28 15:42
我有一个项目,优先必须是0,优化我一般选 -02  程序会崩溃。

你的程序应该是内存问题。仔细检查每一个内存申请和释放。
头像被屏蔽

出0入0汤圆

发表于 2012-9-16 10:41:47 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入8汤圆

发表于 2012-9-16 11:11:34 | 显示全部楼层
本帖最后由 kebaojun305 于 2012-9-16 11:17 编辑

还可以再优化   库里占空间的是参数检测  把参数检测的宏定义屏蔽  就基本上和你使用寄存器操作一样的大小了。  同样适用  STM8S的库  ,比如如下的一个库函数中的参数检测
  1. /* Check the parameters */
  2.   assert_param(IS_ADC_ALL_PERIPH(ADCx));
  3.   assert_param(IS_ADC_MODE(ADC_InitStruct->ADC_Mode));
  4.   assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ScanConvMode));
  5.   assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode));
  6.   assert_param(IS_ADC_EXT_TRIG(ADC_InitStruct->ADC_ExternalTrigConv));   
  7.   assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign));
  8.   assert_param(IS_ADC_REGULAR_LENGTH(ADC_InitStruct->ADC_NbrOfChannel));
复制代码
在库的配置头文件(XX_conf.h)中可以屏蔽到这个检测(第3行  实际上注释已经写的很清楚了。
  1. /* Uncomment the line below to expanse the "assert_param" macro in the
  2.    Standard Peripheral Library drivers code */
  3. /* #define USE_FULL_ASSERT    1 */

  4. /* Exported macro ------------------------------------------------------------*/
  5. #ifdef  USE_FULL_ASSERT

  6. /**
  7.   * @brief  The assert_param macro is used for function's parameters check.
  8.   * @param  expr: If expr is false, it calls assert_failed function
  9.   *   which reports the name of the source file and the source
  10.   *   line number of the call that failed.
  11.   *   If expr is true, it returns no value.
  12.   * @retval None
  13.   */
  14.   #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
  15. /* Exported functions ------------------------------------------------------- */
  16.   void assert_failed(uint8_t* file, uint32_t line);
  17. #else
  18.   #define assert_param(expr) ((void)0)
  19. #endif /* USE_FULL_ASSERT */
复制代码

出0入0汤圆

发表于 2012-9-16 19:48:02 | 显示全部楼层
好的
正狠20K的RAM不够仿真用呢,好MARK一下才行

出0入0汤圆

发表于 2012-9-16 20:13:08 | 显示全部楼层
直接使用寄存器,肯定更节省……

出0入0汤圆

发表于 2012-9-16 21:01:41 | 显示全部楼层
学习了,确实有用!

出0入0汤圆

发表于 2013-2-5 23:08:49 | 显示全部楼层
确实少了1半啊!

出0入0汤圆

发表于 2013-2-6 14:23:07 | 显示全部楼层
这个方法帮助很大!

出0入0汤圆

发表于 2013-2-6 14:49:18 来自手机 | 显示全部楼层
方法可行

出0入0汤圆

发表于 2013-2-6 15:39:27 | 显示全部楼层
好方法!。。。。

出0入46汤圆

发表于 2013-2-6 15:44:58 | 显示全部楼层
试了一下,第一项没效果,第二项作用很大!

出0入0汤圆

发表于 2013-2-6 16:04:26 | 显示全部楼层
顶                                             

出0入0汤圆

发表于 2013-2-6 16:19:03 | 显示全部楼层
非常有用,编译出来的文件小了5K

出0入0汤圆

发表于 2013-2-6 16:44:55 | 显示全部楼层
henry 发表于 2012-6-29 09:57
最近做了个基于STM32的项目,原来代码没有任何的编译器优化,正好拿来实际测试下~
没有任何优化:code 1664 ...

NO -- One ELF Section per Function
default                Program Size: Code=36492                RO-data=4892                RW-data=140                ZI-data=6012  
Level 0                Program Size: Code=49780                RO-data=13724                RW-data=140                ZI-data=7292
Level 1                Program Size: Code=38972                RO-data=4892                RW-data=140                ZI-data=6012
Level 2                Program Size: Code=36492                RO-data=4892                RW-data=140                ZI-data=6012
Level 3                Program Size: Code=36556                RO-data=4892                RW-data=140                ZI-data=6012

YES --One ELF Section per Function
default                Program Size: Code=27796                RO-data=4900                RW-data=120                ZI-data=6016
Level 0                Program Size: Code=38368                RO-data=13728                RW-data=120                ZI-data=7296
Level 1                Program Size: Code=29576                RO-data=4896                RW-data=120                ZI-data=6016
Level 2                Program Size: Code=27796                RO-data=4900                RW-data=120                ZI-data=6016
Level 3                Program Size: Code=27832                RO-data=4896                RW-data=120                ZI-data=6016

Level 3 的結果反而比 Level 2 還要差
所以應該還是要看代碼來決定Level

default 似乎是等同於 Level 2, 結果一樣
在 Compiler control string 裡的訊息也是一樣的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-2-6 17:14:56 | 显示全部楼层
不错,学习了

出0入0汤圆

发表于 2013-6-6 13:13:24 | 显示全部楼层
菜鸟级别的顶一下 现在对编程还没研究的这么深入

出0入0汤圆

发表于 2013-6-6 13:22:26 | 显示全部楼层
果断去试试看啊

出0入0汤圆

发表于 2013-6-6 14:22:47 | 显示全部楼层
mark               

出0入0汤圆

发表于 2014-2-23 12:04:22 | 显示全部楼层
kebaojun305 发表于 2012-9-16 11:11
还可以再优化   库里占空间的是参数检测  把参数检测的宏定义屏蔽  就基本上和你使用寄存器操作一样的大小 ...

看样子默认是已经屏蔽了的哦,

出0入0汤圆

发表于 2014-2-23 12:16:06 | 显示全部楼层
果断马克了

出0入0汤圆

发表于 2014-2-23 12:18:00 | 显示全部楼层
kebaojun305 发表于 2012-9-16 11:11
还可以再优化   库里占空间的是参数检测  把参数检测的宏定义屏蔽  就基本上和你使用寄存器操作一样的大小 ...

哦,这段代码已经把/*#define USE_FULL_ASSERT    1 */注释掉了,也即是说 参数检查定义的函数是

#define assert_param(expr) ((void)0)

而不是

#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))

由于上面那个参数检查函数比下面这个简单(小),所以代码会小?
(上面那个参数检查函数好像没起作用吧,也就是说取消了参数检查,左移代码可以变小?)

所以这点已经是默认优化了的?

出0入0汤圆

发表于 2014-2-24 14:16:44 | 显示全部楼层
试了一下,确实减少了。但多了好多警告。

出0入0汤圆

发表于 2014-2-24 14:17:44 | 显示全部楼层

出0入0汤圆

发表于 2014-2-25 12:25:58 | 显示全部楼层
mark,thanks

出0入0汤圆

发表于 2014-2-25 13:08:58 | 显示全部楼层
有机会试试看

出0入0汤圆

发表于 2014-2-25 13:16:06 | 显示全部楼层
果然很有用唉~~

出0入0汤圆

发表于 2014-2-25 15:27:00 | 显示全部楼层
mark                              

出0入0汤圆

发表于 2014-2-25 16:47:37 | 显示全部楼层
One ELF Section per Function   优化效果很好   
如果不选中这个那么一个文件就生产一个ELF文件,再在链接时一块生成可执行文件,如果One elf section  per function 则在链接阶段只链接调用的函数生产可执行文件。
Generate one ELF section for each function in source file. Output sections are named with the same name as the function that generates the section. Allows to optimize code or to locate each function on individual memory addresses.

出0入0汤圆

发表于 2014-2-25 18:00:38 | 显示全部楼层
学习了~

出0入4汤圆

发表于 2014-2-25 19:28:19 | 显示全部楼层
占座学习

出0入0汤圆

发表于 2014-2-25 22:22:12 | 显示全部楼层
学习了,确实有用

出0入0汤圆

发表于 2014-2-26 17:10:23 | 显示全部楼层
好资料,标记

出0入0汤圆

发表于 2014-2-26 17:22:16 | 显示全部楼层
mark,标记下

出0入0汤圆

发表于 2014-3-7 23:08:14 | 显示全部楼层
•Use the --split_sections  compiler option to generate  one ELF section for each function
in the source file.
This option results in a small increase in code size for some functions because it reduces
the potential for sharing addresses, data, and string literals between functions. However,
this can help to reduce the final image size overall by enabling the linker to remove unused
functions when you specify armlink --remove .

出0入0汤圆

发表于 2014-3-7 23:22:46 | 显示全部楼层
IAR从来不用关心这些……

在你的工程里随便写几百个函数都没问题,只要没用到,IAR会自动优化掉的

出10入10汤圆

发表于 2014-3-8 10:18:55 | 显示全部楼层
很有用!!!

出0入0汤圆

发表于 2014-3-8 10:36:38 | 显示全部楼层
支持继续研究

出0入0汤圆

发表于 2014-3-8 21:19:28 | 显示全部楼层
膜拜下大牛们对于细节扣得深

出0入0汤圆

发表于 2014-3-12 09:45:09 | 显示全部楼层
经过这样我优化减了一半,不过担心的是会不会过渡优化呀。会不会有意想不到的情况发生

出100入101汤圆

发表于 2014-3-14 15:26:49 | 显示全部楼层
优化效果还是很明显,少了20K。

出0入0汤圆

发表于 2014-3-17 14:28:03 | 显示全部楼层
mark                             

出0入0汤圆

发表于 2014-3-17 16:05:21 | 显示全部楼层
回去试试!

出0入0汤圆

发表于 2014-3-18 10:04:16 | 显示全部楼层
这个可以试试

出0入0汤圆

发表于 2014-3-18 14:21:04 | 显示全部楼层
学习,谢谢!!!

出0入0汤圆

发表于 2014-3-18 21:12:52 | 显示全部楼层
这个不错的。

出0入0汤圆

发表于 2014-3-18 22:15:40 | 显示全部楼层
实验一下,bin文件小了几乎一倍!!

出0入0汤圆

发表于 2014-3-18 23:43:15 | 显示全部楼层
                            少了一半

出0入0汤圆

发表于 2014-3-19 01:22:05 | 显示全部楼层
菜鸟mark一下~

出0入0汤圆

发表于 2014-3-19 23:39:14 | 显示全部楼层
精品贴,学习了

出0入0汤圆

发表于 2015-9-22 13:56:13 | 显示全部楼层
晚枫 发表于 2014-2-24 14:16
试了一下,确实减少了。但多了好多警告。

是的。警告变多了

出0入0汤圆

发表于 2016-7-6 14:15:04 | 显示全部楼层
赞楼主,正好有个需求想降低代码量。找了很多资料,你这个可以比平常降低一半!

出0入0汤圆

发表于 2016-7-7 08:30:44 | 显示全部楼层
wye11083 发表于 2012-9-16 10:35
你的程序应该是内存问题。仔细检查每一个内存申请和释放。

不一定,我遇到的是死液晶,可能跟FSMC时序有关

出0入0汤圆

发表于 2016-8-4 17:25:17 | 显示全部楼层
试过,貌似是反的,选了大,不选小。

出0入0汤圆

发表于 2016-8-4 20:47:51 | 显示全部楼层
我先保存一下,收藏之。。。还没有试过呢。。。

出0入0汤圆

发表于 2016-8-4 21:31:24 | 显示全部楼层
不错。学习了。

出0入0汤圆

发表于 2016-8-5 08:17:56 | 显示全部楼层
不缺这么点flash吧

出0入0汤圆

发表于 2016-8-5 08:29:23 | 显示全部楼层
这个有用,谢谢楼主分享!

出0入12汤圆

发表于 2016-8-5 08:31:00 | 显示全部楼层
如果用 gcc 可以尝试 lto,比这个优化强很多。

出0入0汤圆

发表于 2016-8-5 09:26:43 | 显示全部楼层
的确是个好东西
我这就直接放三张图

没有优化的:

优化-O0,

优化-O2

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-8-5 09:36:46 | 显示全部楼层
谢谢分享!

出0入4汤圆

发表于 2016-8-6 07:45:24 来自手机 | 显示全部楼层
mark, stm32代码瘦身。

出0入0汤圆

发表于 2016-8-8 14:57:03 | 显示全部楼层
木君之上 发表于 2014-2-23 12:18
哦,这段代码已经把/*#define USE_FULL_ASSERT    1 */注释掉了,也即是说 参数检查定义的函数是

#defi ...

对的,看起来就是这样子,学习了~

出0入0汤圆

发表于 2019-2-11 21:53:23 | 显示全部楼层
mark                        

出0入0汤圆

发表于 2019-2-15 23:32:40 | 显示全部楼层
不錯~~~~~~~~~~~~~~~~~~

出0入0汤圆

发表于 2019-2-16 06:34:36 来自手机 | 显示全部楼层
谢谢分享。。。。

出0入0汤圆

发表于 2019-2-16 10:02:39 | 显示全部楼层
MARK: KEIL 编译瘦身
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 06:40

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表