Arduino - 关于内存
来源:互联网 发布:英语语言变迁 知乎 编辑:程序博客网 时间:2024/04/20 06:16
转自:
http://www.geek-workshop.com/forum.php?mod=redirect&goto=findpost&ptid=10816&pid=113693
Arduino 328p 用的芯片 属于 哈弗结构,他把存储区分为 三个部分:1. FLASH 程序存储区, 2. RAM 动态 内存,3. ROM 区 。他不同于 诺依曼 结构的 程序存储区 和 RAM 内存是在一起的。由于 程序存储区 和 RAM 内存 是分开的,于是就有了 32K 的 FLASH 程序存储区 和 2K 的 RAM 动态内存,当然还有 ROM .32K 的 FLASH 程序存储区 是存放 你的 经过 编译的 程序本体。 2K 的 RAM 动态内存 是存放 程序运行时 需要的 临时 变量。由于 Arduino 本初的 想发是 给那些 非 计算机专业的 设计者们 使用的,所以他使用了人们习惯的思维方式来编程。于是他发明了很多自己专用的 指令(确切的说应该是 函数,或 宏替换 ),这样,就带来了 代码 不精练的 问题。当然 宏替换 没有问题。这不等于不 高效 和不 简练,因为 Arduino IDE 是 基于 C / C++ 的 编译器, C / C++ 在 编译时 还是做了很多 代码优化工作。我们看 几个 例子: Arduino IDE 版本 1.6.61. 编译一个 空 程序 void setup() { // put your setup code here, to run once:}void loop() { // put your main code here, to run repeatedly:}Arduino IDE 版本 1.6.6 显示的 编译结果:项目使用了 450 字节,占用了 (1%) 程序存储空间。最大为 30,720 字节。全局变量使用了9字节,(0%)的动态内存,余留2,039字节局部变量。最大为2,048字节。这个程序 什么也没有做,他也要占用 这么多 空间。 那是因为 他要 初始化 各个端口 和 很多 寄存器,还要 运行 上面那段 看起来像是 空代码 的代码。不信吗?看看 Arduino IDE 他 隐藏 包含的 main.cppint main(void) // 这是一段 c 程序{ init(); initVariant();#if defined(USBCON) USBDevice.attach();#endif setup(); for (;;) { loop(); if (serialEventRun) serialEventRun(); } return 0;}这就是 我们看得到 Arduino IDE 编程器的 初始 界面 ,别看他是 空的,但是 上面的代码是要 运行的。记住 这段 空代码 使用的 空间,我们再做 下面的 实验,给个 Arduino 自带的 经典代码,点亮 一颗 LED 灯。void setup() { pinMode(13, OUTPUT); // 将 D13 端口 设置为 输出, 因为 他上面 连着 一颗 LED 灯。}void loop() { digitalWrite(13, HIGH); // 将 D13 设为 高电平, 点亮 LED 灯。 delay(1000); // 延时 1秒 digitalWrite(13, LOW); // 将 D13 设为 低电平, 关闭 LED 灯。 delay(1000); // 再 延时 1秒}编译他:项目使用了 1,030 字节,占用了 (3%) 程序存储空间。最大为 30,720 字节。全局变量使用了9字节,(0%)的动态内存,余留2,039字节局部变量。最大为2,048字节。这个程序 占用的空间是 1030 - 450 = 580 字节。 (本次编译 使用空间 1030 字节 - 空程序 使用空间 450 字节。)变量 占用的 RAM 空间 还是 9 字节,这是因为 上面的 4 个 看起来像变量数据 (13, OUTPUT ,HIGH,LOW )其实都是 宏 替换,占用的是 FLASH 程序存储区。为了叙述方便,我们只改动 一条 语句。void setup() { // pinMode(13, OUTPUT); // 注释掉 这一句,不让他 参与 编译}void loop() { digitalWrite(13, HIGH); // 将 D13 设为 高电平, 点亮 LED 灯。 delay(1000); // 延时 1秒 digitalWrite(13, LOW); // 将 D13 设为 低电平, 关闭 LED 灯。 delay(1000); // 再 延时 1秒}再次 编译 他,看看 FLASH 程序存储区 占用情况。项目使用了 900 字节,占用了 (2%) 程序存储空间。最大为 30,720 字节。全局变量使用了9字节,(0%)的动态内存,余留2,039字节局部变量。最大为2,048字节。他比 上次 编译 节省了 1030 - 900 = 130 字节,而且他是 能工作的 ,只是 LED 灯 很暗 ,在很暗的地方可以看清他。为什么 他还能亮呢? 因为 编译器在什么程序也不编译的时候,他还是要初始化 各个 端口的,这时 PB 端口 都被 初始化成 输入状态,AVR 的 芯片 在 端口为 输入状态时,给他写入 高电平,就启动了 上拉 电阻,电压从 正电源 通过 上拉电阻传递给了 LED ,尽管 电流非常小,但是他还是亮了。这也是 空程序 也要占用空间的原因。那么 pinMode(13, OUTPUT); 语句为什么要占用 130 字节的空间呢,因为 Arduino 指令 格式 是 16 比特,也就是 2 字节,参数 13 要用 2 字节,OUTPUT 要用 2 字节,调用 pinMode( ) 函数 要用 4 字节,剩下的 是 函数 pinMode( ) 本身 要占用的 空间,由于 IDE 版本 不一样, 函数 本身 要占用的 空间 也不一样,大家可以 试试。这个程序 不能正常 干活,我们换条指令 让他 正常 干活。看下面的程序:void setup() { // pinMode(13, OUTPUT); // 注释掉 这一句, 改为 下面 一句 bitSet(DDRB,5); // 设置 PB 端口的 DDR 输出寄存器 第 5 位 为输出状态,(就是 D13 端口)}void loop() { digitalWrite(13, HIGH); // 将 D13 设为 高电平, 点亮 LED 灯。 delay(1000); // 延时 1秒 digitalWrite(13, LOW); // 将 D13 设为 低电平, 关闭 LED 灯。 delay(1000); // 再 延时 1秒}编译一下,奇迹出现了,项目使用了 902 字节,占用了 (2%) 程序存储空间。最大为 30,720 字节。全局变量使用了9字节,(0%)的动态内存,余留2,039字节局部变量。最大为2,048字节。 bitSet(DDRB,5); 语句 只用了 2 字节 空间,而且和 pinMode(13, OUTPUT); 语句 干的事 同样的 活。这就是 Arduino ,他用 自己的 语言 方便了 我们,使我们能 很快 入门,但又使我们的程序 冗长,并且执行效率也不高。爱他,因为我们 很笨,恨他,因为我们嫌他 很笨。1. 代码的 种类 要尽可能的少,因为 每条 相同的函数 本身只占 一个空间,而每次 调用他 只占 很少的 空间,不信你可以多加几条 pinMode( , ); 语句,看看他占用的空间是不是成倍增加。2. 最宝贵的是 RAM 空间,要尽量的 少用 全局 变量,因为 局部 变量 每次使用完后,他会释放 内存空间给其他变量使用。3. 相同功能,不同发布者,占用的空间不一样,比如:驱动 OLED 屏的库文件。 u8g 占用的空间最少, SSD1306 次之,Adafruit_SSD1306-master 占用空间最多。
0 0
- Arduino - 关于内存
- 关于Arduino
- 关于Arduino与STM32
- 关于arduino的各种网站
- 关于Arduino的 FreqCount Library
- Arduino
- arduino
- Arduino
- arduino
- arduino
- arduino
- Arduino
- Arduino
- Arduino
- Arduino
- Arduino
- Arduino
- Arduino
- Prim算法生成最小生成树
- C#读取xml文件
- http协议介绍(servlet)
- Hibernate——org.hibernate.StaleStateException: Batch update returned unexpected row count from update
- 最大熵模型中的数学推导
- Arduino - 关于内存
- Canvas基础知识总结之一
- IIS7/8 HTTP Error 500.19 错误 0x80070021
- Java中的责任链模式
- sympy官方文档网站无法打开问题解决
- BAT巨头的开源项目
- Awesome R
- ViewPager只初始化当前页,不会提前初始化下一页的设置
- LeetCode-15-3Sum(证明/KSum)-Medium