前言
理论上编译是直接在使用的设备上连接各种库编译会很方便,但在树莓派上或许会遇到一些问题:
- VNC、SSH延迟可能特别大,尤其远程连入执行指令缓慢到你觉得你的板子可能在月球上
- 比在PC和服务器上更长的编译时间和编译过程中由于资源消耗造成的树莓派使用卡顿
- 直接在树莓派上编译需要连接显示器、键盘、Ethernet等外设,有可能由于位置原因、硬件接口被去除或者集成在其他系统里导致无法连接外设
- 树莓派无法联网,有时候只能烧入tf卡加载
- 部署版本中没有GUI等等
为了解决这些问题,可以考虑直接在一台Linux的PC或者服务器上编译好代码之后拷贝到嵌入式环境中使用。而由于嵌入式环境使用的指令集不一样,所以需要使用交叉编译工具链完成编译。
环境配置
在Mac环境编译可以参考这个教程。
而在Linux环境可以直接使用树莓派官方提供的工具做交叉编译:
- 设定一个文件目录用于交叉编译。
- 从github - raspberrypi tools工程上下载工具链。
- 拉下来后确认下工具链被完整下载到了
tools
文件夹中
依赖库下载
一般来说我们的代码都或多或少需要连接各种外部库,但是交叉编译也就意味着我们编译的ARM二进制代码不能取连接Intel指令集的库文件,所以我们需要得到树莓派环境专用的库。
获得这些库的方法有两个:
- 直接下载其他人按环境编译好的库,比如像
pthreads
这样的库或者标准库在上一步中下载的工具链中包含了。 - 自行先交叉编译库文件,再通过库文件交叉编译最终的可执行文件。在本示例中,我们将先交叉编译
wiringPi
库,这个库可以提供对树莓派GPIO引脚的操控。
为了编译wiringPi
库,我们先到wiringPi下载最新release版本的源文件。
CMake交叉编译工具链配置
重头戏到了,如同正常本机编译的流程,我们依旧使用CMake作为编译工具。但不一样的是,我们需要写一份配置工具链的文件供CMake调用。
针对树莓派工具链,可以参考下面的Toolchain-rpi.cmake
文件:
1 | # Define our host system |
主要是需要根据刚刚解压获得的官网上的环境,配置编译中所使用的C、C++编译器和sysroot环境地址,具体的地址可以参考上面三个地址根据实际情况配置。
配置完编译文件之后就可以使用调用该文件了
1 | cmake . -DCMAKE_TOOLCHAIN_FILE=toolchain-rpi.cmake |
编译wiringPi库
首先我们需要把CMakeLists.txt
文件放到wiringPi的工程文件目录下,下载下来的源代码在文件目录/wiringPi/wiringPi
。
1 | cmake_minimum_required(VERSION 3.0) |
建立build文件夹并编译:
1 | mkdir build |
编译demo代码
写一个demo简单测试下效果,demo代码如下:
1 |
|
代码实现了初始化引脚,并使0号引脚输出1Hz的方波。(wiringPi
中0号引脚
对应PIN Map中GPIO17
)。
cmake文件为:
1 | cmake_minimum_required (VERSION 3.0) |
编译依旧采用引用Toolchain-rpi.cmake
的方式编译:
1 | mkdir build |
测试
编译成功后,从wiringPi
库的编译输出中拷贝出libwiringpi.so
,从Demo工程的编译输出中拷贝出blink_example
,拷入树莓派中。
添加环境变量:
1 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/存放libwiringpi.so的地址 |
运行blink_example
即可,此时GPIO17即可输出方便,可通过示波器观察。
(我这里只有万用表)