赞
踩
自从接触Arduino以来,我们就被灌输了一个理念~
在.ino
文件中:
其他的全局变量、全局函数可以定义在setup函数、loop函数前面或是后面,即使是在setup函数、loop函数后面定义的,也不需要在开头做函数声明,不会导致编译出错可以正常调用。
直到一天突发奇想,loop函数一直在循环,那么我在loop函数中直接执行return,是不是就直接结束 “loop循环” 从而退出了自身进程?!!?
所以我简单改了Blink程序,添加return如下:
void setup()
{
pinMode(13,OUTPUT);
}
void loop()
{
digitalWrite(13,HIGH);
delay(1000);
digitalWrite(13,LOW);
delay(1000);
return;
delay(2000);
}
1)程序执行一遍LED亮灭,遇到 return
后板子退出进程,处于“裸跑”状态;
2)程序连 return
后面的语句一同执行,并且一直循环,无视 return
存在;
3)程序一直循环LED亮1秒灭1秒操作,不执行 return
后的操作;
结果证实第三种推导是正确的:程序一直循环执行亮1灭1的操作,return在程序中确实有退出loop函数的作用,但是loop函数又再次神奇的“运行”起来了。
由此推断loop函数不是一个自身循环的函数,应该是在某个地方一直被循环调用了,return都不能阻止这个程序的“循环”。
Arduino所用的编程语言是C\C++,正常来说应该能找到main.c文件已经main函数。通过在安装目录中的搜寻,确实找到了main.c的踪迹,路径是 Arduino\hardware\arduino\avr\cores\arduino
,是个cpp文件。
main.cpp内容也比较简单,如下:
#include <Arduino.h> // Declared weak in Arduino.h to allow user redefinitions. int atexit(void (* /*func*/ )()) { return 0; } // Weak empty variant initialization function. // May be redefined by variant files. void initVariant() __attribute__((weak)); void initVariant() { } void setupUSB() __attribute__((weak)); void setupUSB() { } int main(void) { init(); initVariant(); #if defined(USBCON) USBDevice.attach(); #endif setup(); for (;;) { loop(); if (serialEventRun) serialEventRun(); } return 0; }
在这里我们看到了熟悉的main函数,在main函数中,除了一些必要的初始化函数调用外,终于看到了setup函数及loop函数的踪影;setup函数在main函数中被调用一次,而不一样的是loop函数被放在for循环里面,这就能解释得通为何Arduino的运行机制中setup函数只运行一次,随后一直在运行loop了,而在loop函数中加入return之后,虽然是退出了当前的loop函数的执行,但是在for循环语句的作用下,又再次被循环调用;
因此,在loop函数中加入return的作用可以理解成相当于添加了continue的作用,在当前位置退出“loop循环”,直接直接开始下一次的“loop循环”,大概道理是一样的。
在for循环中,除了循环执行loop函数,还有一个串口事件的监控,因为跟loop函数同为一个循环体,所以会导致有时候的串口处理不够及时。
在下也有个猜想,搞清楚了Arduino的运行机制(实质上还是运行main函数),改了setup、loop的函数名以及在Arduino.h中的声明,或者自己新建函数在main函数中以同样的形式被调用,也许可以让自己的初始化函数、自己定义的循环函数运行起来。不过对于这套相对成熟的运行机制,这样的想法貌似没什么必要。
还有个彩蛋,在main.cpp所在的目录中,还能看到串口定义的相关文件,串口0 - 串口3的定义文件都在;甚至还是能看到wiring_analog文件和wiring_digital文件,我们熟悉的digitalRead、digitalWrite函数和analogRead、analogWrite、pinMode函数的定义都在这些文件中,算是另外的收获吧。
但是目前还没弄懂的是main.cpp是怎么能调用到setup函数和loop函数所在的.ino文件的,以及在.ino文件中定义的全局变量和全局函数,如果在setup和loop中没有被调用,是否会占用内存,有知道这些问题答案的读者可以在评论区说一说,互相学习,十分感谢。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。