我打算使用Arduino programmable board。那些具有相当有限的闪存,范围在16到128 kB之间,用于存储编译的C或C ++代码。
有没有办法估算它代表的(标准)代码的数量?
我认为这很模糊,但我只是在寻找一个数量级。
答案 0 :(得分:6)
size
命令的输出是一个很好的起点,但不会提供您需要的所有信息。
$ avr-size program.elf
text data bss dec hex filename
图像的大小通常比文本和数据部分的总和略大。 bss部分基本上是压缩的,因为它全是0。可能还有其他相关部分未按大小列出。
如果您的构建系统设置为我以前用于AVR微控制器的构建系统,那么您最终会得到* .elf文件以及* .bin文件,并且可能是* .hex文件。 * .bin文件是存储在处理器程序闪存中的实际图像,因此您可以检查其大小,以确定程序在编辑时的增长方式。 * .bin文件是使用objdump命令从* .elf文件中提取的,还有一些我现在还记不住的标志。
如果您想知道如何猜测您的C或C ++代码在编译时会产生多少,那么这将更加困难。当我尝试使用uint64_t而不是uint32_t时,我已经观察到函数中有10倍的爆炸,而我所做的只是递增它(这是我认为的代码的5倍左右)。这主要与gcc的avr优化不是最好的有关,但代码大小的较小变化可能会从看似无辜的代码中蔓延。
这可能会因使用C ++而放大,而C ++往往会隐藏更多变成代码的东西而不是C语言。 C ++隐藏的主要内容是析构函数调用和许多指针解除引用,它与对象中的this
指针以及许多对象对其虚函数表和类静态变量的秘密指针有关。
在AVR上,所有这些指针内容都可能真正加起来,因为指针是寄存器的两倍,并且需要加载多个指令。此外,AVR只有几个可用作指针的寄存器对,这导致大量移动进出这些寄存器。
AVR小程序的一些提示:
尽可能使用uint8_t
和int8_t
代替int
。如果您希望代码可移植,也可以使用uint_fast8_t
和int_fast8_t
。这可能导致许多操作只占用一半的代码,因为int
是两个字节。
非常了解字符串和结构常量和文字以及它们的存储方式和位置。
如果您不害怕,请阅读AVR组装手册。您可以了解指令的类型,并从中了解轻松映射到这些指令的C代码类型。使用那种C代码。
答案 1 :(得分:3)
你真的不能说那里。未编译代码的长度与编译代码的长度几乎没有关系。例如:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
std::vector<std::string> strings;
strings.push_back("Hello");
strings.push_back("World");
std::sort(strings.begin(), strings.end());
std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(std::cout, ""));
}
VS
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
std::vector<std::string> strings;
strings.push_back("Hello");
strings.push_back("World");
for ( int idx = 0; idx < strings.size(); idx++ )
std::cout << strings[idx];
}
两者都是完全相同的行数,并产生相同的输出,但第一个例子涉及std :: sort的实例化,这可能比这里的其余代码多一个数量级的代码。
如果您绝对需要计算程序中使用的字节数,请使用汇编程序。
答案 2 :(得分:2)
下载arduino IDE并“验证”一些现有代码,或查看示例草图。它将告诉您代码的字节数,这将让您了解您可以在给定设备中放入多少字节。随机选取几个示例,web server示例为5816字节,LCD hello world为2616.两者都使用外部库。
答案 3 :(得分:2)
尝试创建应用的简化版本,首先关注最有价值的功能,然后开始添加'很好(和很酷)的东西'。验证代码时,请密切关注Arduino IDE中显示的字节使用情况。
作为一个粗略的指示,我的第一个应用程序(由推动按钮控制的LED闪光灯)需要1092个字节。 32k大约是1K。 C ++代码的足迹很小!
最让我担心的是RAM数量有限(1 Kb)。如果CPU堆栈占用了一些,那么创建任何数据结构都没有多少余地。
我只有48小时的Arduino,所以有效地使用它还有很多东西;-)但是使用起来很有趣:)。
答案 4 :(得分:1)
对于一个相当复杂的软件来说,这是相当多的,但如果你想让它具有很多不同的功能,你就会开始闯入极限。此外,如果你想存储相当多的静态字符串和数据,它可以很快地吃掉它。但是32 KB对于嵌入式应用来说是一个不错的数量。它往往是你首先遇到问题的RAM!
此外,嵌入式系统的C ++编译器通常比C编译器差很多。 也就是说,它们远不如普通桌面操作系统的C ++编译器(在为目标平台生成高效的机器代码方面)。
答案 5 :(得分:0)
在Linux系统中,您可以使用静态编译的示例程序进行一些实验。 E.g。
$ size `which busybox `
text data bss dec hex filename
1830468 4448 25650 1860566 1c63d6 /bin/busybox
大小以字节为单位。此输出独立于可执行文件格式,因为文件格式内不同部分的大小。文本部分包含机器代码和const stufff。数据部分包含用于静态初始化变量的数据。 bss大小是未初始化数据的大小 - 当然,未初始化的数据不需要存储在可执行文件中。)
好吧,busybox包含很多功能(比如所有常见的shell命令,shell等)。
如果您使用 gcc -static 链接自己的示例,请记住,您使用的libc可能会大大增加程序大小,并且使用嵌入式libc可能会更节省空间。
要测试您是否可以查看diet-libc或uclibc并与之相关联。实际上,busybox通常与uclibc链接。
请注意,您通过这种方式获得的尺寸只能一个数量级。例如,您的工作站可能使用另一种CPU架构而不是arduino板,并且不同架构的机器代码可能或多或少地大小不同(因为操作数大小,可用指令,操作码编码等等)。
继续粗略的数量级推理,busybox大致包含309 tools(包括ftp守护程序等等),即busybox工具的平均代码大小约为5k。