GD32F130FXP6学习笔记十三:mdk优化掉不调用的函数和防止没有显式调用的函数被优化掉

一、优化掉没有调用的函数,减少程序空间

我做了下测试,在开一级优化下,我写了一个函数,但是没有调用,查看map文件发现

它仍然占用程序空间,所以我怀疑不是优化级别的事情。于是百度了下,发现要勾选C/C++的

One ELF Section per Function。什么是意思呢?就是每个文件的函数单独出一个连接文件,

这样连接的时候,那些没有调用的函数就被移除掉了。


查看编译后的map文件:



看到了没有?移除了。


二、mdk怎么实现IAR的__root效果

__root是指被修饰的变量或者函数在用户程序里面没有显式调用情况下,也不会被优化掉。

像一些系统配置和函数指针调用,就需要__root属性。

那么mdk怎么实现呢?查看了下编译器手册,并没有__root关键字,看了下连接器手册,有

--keep关键字。

官方说明:

--keep=section_id

--keep=section_id

This option specifies input sections that must not be removed by unused section elimination.

Show/hideSyntax

--keep=section_id

Where section_id is one of the following:

symbol

Specifies that an input section defining symbol is to be retained during unused section elimination. If multiple 

For example, you might use --keep=int_handler.

To keep all sections that define a symbol ending in _handler, use--keep=*_handler.

definitions of symbol exist,armlink generates an error message.

object(section)

Specifies that section fromobject is to be retained during unused section elimination. If a single instance ofsection is

For example, to keep the vect section from the vectors.o object use: --keep=vectors.o(vect)

To keep all sections from the vectors.o object where the first three characters of the name of the sections arevec

use:--keep=vectors.o(vec*)

 generated, you can omit section, for example,file.o(). Otherwise, you must specify section.

object

Specifies that the single input section from object is to be retained during unused section elimination. If you use this 

For example, you might use --keep=dspdata.o.

To keep the single input section from each of the objects that has a name starting withdsp, use --keep=dsp*.o.

short form and there is more than one input section in object, the linker generates an error message.

All forms of the section_id argument can contain the* and ? wild characters. Matching is case-insensitive, even on hosts

 with case-sensitive file naming. For example:

  • --keep foo.o(Premier*) causes the entire match forPremier* to be case-insensitive

  • --keep foo.o(Premier) causes a case-sensitive match for the string Premier.

Use *.o to match all object files. Use * to match all object files and libraries.

You can specify multiple --keep options on the command line.

Show/hideMatching a symbol that has the same name as an object

If you name a symbol with the same name as an object, then --keep=symbol_id searches for a symbol that matchessymbol_id:

  • If a symbol is found, it matches the symbol.

  • If no symbol is found, it matches the object.

You can force --keep to match an object with --keep=symbol_id(). Therefore, to keep both the symbol and the object, 

specify --keep foo.o --keep foo.o().

Show/hideSee also

Concepts

Using the Linker:

出处:

使用mdk编程,假如有一个有用的函数你定义了但是没有显式的调用,mdk在默认方式下,将会把这

个函数从整个程序总删除掉,以节省ROM.

比如,你在ROM的0x00002000处定位了一个函数,假设为void test(void),然后使用函数指针来调用它:

void (*UserProgram)();          //函数指针

UserProgram = (void (*)()) (0x00002000);//定位到指定的入口地址0x00002000

(*UserProgram)();//调用test()函数

这样做的本意是调用test()函数,但编译器并不知情,它仍会按照默认的指令将test函数给整个优化掉,因为它

觉得test()函数根本没有被调用,这个时候,虽然(*UserProgram)();仍会执行,但内容与初衷已经大相径庭.

能否让编译器不自动优化test这个函数?

当然有,就是使用链接器命令:--keep=section_id   此选项指定删除未使用节时不能删除的输入节。

其中 section_id 是以下项之一:
symbol 指定在删除未使用节时保留定义 symbol 的输入节。 如果 symbol 存在多个定义,则 armlink 

将生成一则错误消息。
           例如,您可能使用 --keep=int_handler。若要保留定义以 _handler 结尾的符号的所有节,请

使用--keep=*_handler。object(section)指定在删除未使用节时保留 object 中的 section。 例如,

若要保留vectors.o 对象的 vect 节,请使用: --      keep=vectors.o(vect)若要保留 vectors.o 对象

中节名称的前三个字母是 vec 的所有节,请使用:--keep=vectors.o(vec*)由于我的程序test()函数是

单独放在一个文件里(entry.c)的,所以我在linker标签栏下的Misc controls编辑框中输入--keep=entry.o。



编译后的文件:



  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码的一些问题: 1. 变量命名不规范,不易理解; 2. 函数内部存在大量的重复运算,降低了代码的效率; 3. 函数过于冗长,不利于维护和扩展。 为了优化这段代码,可以采取以下措施: 1. 合理命名变量,使其易于理解; 2. 将重复计算的部分提前计算,并存储在中间变量中,避免重复运算; 3. 将函数进行拆分,提高代码的可读性和可维护性。 修改后的代码如下: ```matlab function dydt = dynamic_ode(t, y) % dydt: 一阶导数 % 提取状态量 xp = y(1); zp = y(2); xg = y(3); zg = y(4); delta = y(5); dxp = y(6); dzp = y(7); dxg = y(8); dzg = y(9); ddelta = y(10); % 定义常量 global mn alphan B Tp Tg mp mg Jp Jg bh e0 er miu OMEGA rp rg omegan jth % 计算中间变量 t = t / omegan; lp = @(t) (1 + 0.5 * cos(OMEGA * t)); ita = @(t) (0.5 * cos(OMEGA * t)); kh = @(t) (B * Tp * lp(t) * miu * ita(t) * cos(alphan) / Jp); khp = @(t) (B * Tp * miu * ita(t) * cos(alphan) / Jp); kzg = @(fzg) (B * Tg * fzg * sin(alphan) * cos(alphan) / Jg); kzp = @(fzp) (B * Tp * fzp * sin(alphan) * cos(alphan) / Jp); kxg = @(fxg) (B * Tg * fxg / Jg); kxp = @(fxp) (B * Tp * fxp / Jp); khg = @(fdelta) (B * Tg * fdelta * sin(alphan) / Jg); kzg = @(fzg) (B * Tg * fzg * sin(alphan) * cos(alphan) / Jg); fxp = fh(xp, bxp); fzp = fh(zp, bzp); fxg = fh(xg, bxg); fzg = fh(zg, bzg); fdelta = fh(delta, bh); deltan = delta * bh; ddeltan = ddelta * bh; % 计算载荷 fp1 = me * rp * Tp * cos(alphan) / Jp; fp2 = me * rp * lp(t) * miu * ita(t) * deltan * (cos(alphan))^2 / Jp; fg1 = me * rg * Tg * cos(alphan) / Jg; fg2 = me * rg^2 * miu * ita(t) * deltan * sin(alphan) * cos(alphan) / Jg; % 计算无量纲载荷 fp1_dimless = fp1 / (me * bh * omegan^2); fp2_dimless = fp2 / (me * bh * omegan^2); fg1_dimless = fg1 / (me * bh * omegan^2); fg2_dimless = fg2 / (me * bh * omegan^2); fe = er * OMEGA^2 / bh * cos(OMEGA * t); % 动力学方程 ddxp = -(sin(alphan) + cos(alphan) * ita(t) * miu) * khp(t) * deltan - kxp(fxp) - 2 * (sin(alphan) + cos(alphan) * ita(t) * miu) * jth * ddelta - 2 * jtxp * dxp; ddzp = -(cos(alphan) + sin(alphan) * ita(t) * miu) * khp(t) * deltan - kzp(fzp) - 2 * (cos(alphan) + sin(alphan) * ita(t) * miu) * jth * ddelta - 2 * jtzp * dzp; ddxg = (sin(alphan) + cos(alphan) * ita(t) * miu) * khg(fdelta) - kxg(fxg) + 2 * (sin(alphan) + cos(alphan) * ita(t) * miu) * jth * ddelta - 2 * jtxg * dxg; ddzg = (cos(alphan) + sin(alphan) * ita(t) * miu) * khg(fdelta) - kzg(fzg) + 2 * (cos(alphan) + sin(alphan) * ita(t) * miu) * jth * ddelta - 2 * jtzg * dzg; dddelta = fp1_dimless + fp2_dimless + fg1_dimless + fg2_dimless - fe + sin(alphan) * ddxp - sin(alphan) * ddxg + cos(alphan) * ddzp - cos(alphan) * ddzg - (cos(alphan))^2 * jth * ddelta - (cos(alphan))^2 * kh(t) * deltan; % 汇总 dydt = [dxp; dzp; dxg; dzg; ddelta; ddxp; ddzp; ddxg; ddzg; dddelta]; end function f = fh(x, b) % 间隙函数取值 if abs(x) < b f = 0; else f = sign(x) * (abs(x) - b); end end ``` 优化后的代码,变量名称更加规范易懂,函数的结构和逻辑更加清晰,重复计算的部分提前计算,并存储在中间变量中。这样做可以提高代码的效率,降低计算复杂度,同时也更便于代码的维护和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值