Arduino IDE的编译执行过程解读

来源:互联网 发布:淘宝店铺装修视频 编辑:程序博客网 时间:2024/04/27 02:52

Arduino IDE的编译执行过程解读

原创 2016年03月10日 21:17:22
  • http://blog.csdn.net/u011000290/article/details/50850171


  • avr-gcc

    1997年ATMEL公司的A先生和V先生推出了全新配置的8位精简指令集微处理器(RISC-Reduced Instrction Sot CPU),起名为AVR。AVR是一种指令内核的统称,内部又分为ATtiny、AT90S、ATmega三大系列,分别对应AVR的低、中、高档产品。对于开发者而言,关注更多的是AVR单片机的开发方式,而AVR单片机最初在设计的时候的目的就是为了迎合采用高级编程语言来开发这一需求。AVR单片机高级语言开发工具有很多,其中WINAVR是个免费的AVR开发程序集,它以著名的自由软件GCC 为C/C++编译器。GCC可以编译多种语言,比如说C、C++、Objective-C、Fortran、Java和Ada等。AVR也得到了GCC的支持,它也是GCC 支持的唯一一种8 位处理器。

    Ref

    回到问题上来,Arduino作为一款很火的开源硬件,其编程环境Arduino IDE是processing IDE开发的,简单易用,关键是,这个IDE也是开源的。Arduino语言基于wiring语言开发的,也是对 AVR-GCC库的二次封装,所以Arduino的编程实现非常简单,即使没有单片机基础也可以去做Arduino开发。但是,在这些简单的编程语言背后的执行过程又是什么样的呢?

    可以到github上去找Arduino的源码,再结合Arduino的官网发布的信息,自己去分析,下面给出几个有用的链接:

    Arduino Builder

    https://github.com/arduino/arduino-builder

    Arduino IDE源码

    https://github.com/arduino/Arduino/

    Arduino Build Process

    https://www.arduino.cc/en/Hacking/BuildProcess

    其实本身也可以直接利用avr-gcc为Arduino编写程序,因为Arduino本身就是对avr-gcc的二次封装,只需要一个终端、文本编辑器和avr-gcc的工具链就可以了。

    编译执行原理解读

    当你在写自己的Arduino库文件的时候,会发现Arduino确实很奇葩,自己写好的.h和.cpp文件用#include<…>的形式直接引用的时候,Arduino IDE会认为这个文件不存在而报错。而且在一个项目中可以建立多个Sketch文件,不用#include<…>就可以直接合并到一块。

    不扯了,那么在Arduino IDE中,究竟是如何编译执行的呢?其实,官网上有一篇很好的说明文档,Arduino Build Process

    https://www.arduino.cc/en/Hacking/BuildProcess

    从刚开始在Arduino IDE上书写的类C语言代码,再到最终可以在Arduino开发板子上运行的程序,其实,大概经过了下面几个步骤:

    首先,Arduino IDE对代码进行转换,确保生成正确的C/C++代码(两种常用的编程语言);

    再通过avr-gcc编译器将上一步生成的代码编译成机器能识别的指令,或者可以称之为目标文件;

    然后,通过链接器将上一步生成的目标文件与标准的Arduino库文件(比如说,digitalWrite()等)共同链接,生成一个.hex文件,这个hex文件中的指定内容将被写入到Arduino开发板上的单片机的闪存中。

    最后,再将hex文件上传到Arduino的板子上,比如说用USB或者串口,通过板子上已经有的bootloader传输到Arduino板,当然也可以通过其他的工具直接烧写。

    文件预处理

    对于在Arduino IDE中写好的源码,即sketch文件,以.ino为后缀,在把这个文件传给avr-gcc编译器之前,Arduino IDE会对这个sketch文件进行一系列预处理。在一开头加入#include "WProgram.h"(0023版本)或者 #include"Arduino.h"(1.0版本),Arduino.h的源码见附录,主要包含Arduino标准核心库所需的所有声明;Arduino IDE再遍历所有的.ino 文件中定义的函数,为它们创建函数原型,这些声明将被插在最前面的的注释、预处理语句(#include或#define)之后,其它语句(包括类型定义)之前。若在函数中使用了自定义类型,则需要将该类型的定义单独放入一个头文件中。然后将所有 .ino 文件拼接起来,最终当前目标板的main.cxx文件中的所有内容,追加在主sketch文件之后。

    此外,Arduino IDE支持多种目标板与多种芯片、CPU频率、bootloader等,这些都是在板配置文件中进行定义,配置文件中包含name、mcu、单片机的时钟频率、链接时的核心库等信息。

    编译及链接

    Arduino IDE使用avr-gcc来编译程序文件。

    首先,程序文件所在目录、目标板目录(/hardware/cores/<CORE>)和avr的include目录(/hardware/tools/avr/avr/include/),以及主程序文件引用的头文件所在的函数库目录(/hardware/libraries)会被加入到一个引用目录列表。

    从Arduino IDE的源码中就可以知道:Arduino/app/src/processing/app/目录下的Sketch.java文件中,有下面这么一段代码: