新的菜单代码浪费内存——每个菜单字符串在二进制中都是 2 次 #343

推推 grbl 3年前 (2023-02-05) 301次浏览
关闭
MaikStohn 打开了这个问题 2012 年 12 月 15 日 · 5 条评论
关闭

新的菜单代码浪费内存——每个菜单字符串在二进制中都是 2 次#343

MaikStohn 打开了这个问题 2012 年 12 月 15 日 · 5 条评论

评论

新的菜单代码浪费内存——每个菜单字符串在二进制中都是 2 次 #343
贡献者

你好,

看起来字符串池不适用于 avr-gcc,因此新的 MENU_ITEM 宏将菜单项字符串扩展了 2 次(由于 else 语句?)。

也许做一个函数而不是宏更好(也会节省很多空间)

验证/检查输出的命令(例如在 arduino 临时构建目录中):

avr-objdump -s Marlin.cpp.hex

输出示例:

 ...
 12e0 0020643a 20002062 6961733a 20004e6f  . d: . bias: .No
 12f0 20436172 64004e6f 20436172 64004361   Card.No Card.Ca
 1300 7264204d 656e7500 43617264 204d656e  rd Menu.Card Men
 1310 75005374 6f702050 72696e74 0053746f  u.Stop Print.Sto
 1320 70205072 696e7400 52657375 6d652050  p Print.Resume P
 1330 72696e74 00526573 756d6520 5072696e  rint.Resume Prin
 1340 74005061 75736520 5072696e 74005061  t.Pause Print.Pa
 1350 75736520 5072696e 7400436f 6e74726f  use Print.Contro
 1360 6c00436f 6e74726f 6c005072 65706172  l.Control.Prepar
 1370 65005072 65706172 65005475 6e650054  e.Prepare.Tune.T
 1380 756e6500 57617463 68005761 74636800  une.Watch.Watch.
 ...
新的菜单代码浪费内存——每个菜单字符串在二进制中都是 2 次 #343
贡献者作者

我第一次尝试将所有字符串更改为正确的“const PROGMEM char*”变量节省了一些代码空间(apx.2Kb)但增加了 apx 的数据部分。100 字节…失败!看起来 gcc(即使使用 -Os)想要为每个变量添加一个指向数据内存的指针,无论它是否可以嵌入。这是一个糟糕的权衡!

下一个测试只是删除了 if 语句的一部分,它节省了大约 6Kb 的代码空间,数据保持不变(当然)。6Kb 不是 100% 真实的,因为它缺少一些用于选定处理的小代码。但至少可以节省 5Kb。

在检查了正常实现和选定实现的差异之后,看起来这可以很容易地放入一个函数中(只需再增加 1 个参数来保持选定状态)。大多数正常/选定的定义都由相同的通用函数处理。

迈克

新的菜单代码浪费内存——每个菜单字符串在二进制中都是 2 次 #343
贡献者

我在编写代码时确实仔细观察了数据部分,但我假设 avr-gcc 会进行字符串池化……我的假设是错误的。(注意,我宁愿浪费 10k 的闪存然后 100bytes 的 ram)

我会看看是否可以更改实现,以便更好地汇集字符串。

新的菜单代码浪费内存——每个菜单字符串在二进制中都是 2 次 #343
贡献者

我更改了代码,它节省了 500 字节。

新的菜单代码浪费内存——每个菜单字符串在二进制中都是 2 次 #343

修复了提交ErikZalm@ a95dcd7