作为一个没搞过嵌入式的软件工程师,拿着这块板子折腾了两天。这里我们将介绍如何使用Nano打印出Hello world。
一、准备环境与软件
因为公司只给配了一台128+300的小容量本子,这里我将在Windows环境下烧录系统、编写程序,完成后把源文件放到Ubuntu16虚拟机里面编译。这里我将使用SD卡在Windows环境下烧录系统。
我们需要以下软件:
- SD Card Formatter,用来给SD卡格式化。
- Win32DiskImager,用来烧录镜像。
- Xshell & Xftp,用来传输文件,可以使用其他的Shell工具。在连接Nano时,我们使用串口连接。
- arm-linux-musleabi,交叉编译工具链。
二、烧录系统
我们下载好镜像,在“\Lichee Nano\镜像\Nano_pub_V4\image\”中找到需要的镜像:
这里根据自己的存储环境、屏幕分辨率选择。Licheepi Nano套餐里面的屏幕是800 * 480的,所以这里使用“Nano_tf_800480.dd”。
Nano套餐里面的附带的SD卡已经烧录了镜像,它烧录好应该是这样的:
如果SD卡并非官方提供的,那么先用SD Card Formatter格式化,之后再用Win32DiskImager写入镜像,如下:
三、连接到Nano
下面我们使用串口转USB,针脚连接如下:
核心板:
- E1(U0TX)
- E2(U0RX)
- 5V
- GND
串口转USB:
- RX1
- TX1
- 5V
- GND
下面通过USB连接到电脑,这里已经接了5V电源,所以不需要额外供电。打开Xshell,新建一个串口连接:
接下来设置端口:
接下来连接:默认用户名:root;默认密码:licheepi。
四、配置编译环境
Nano的内核编译使用arm-linux-gnueabi,但是应用程序的编译需要使用arm-linux-musleabi。以下是一个简单说明,原文章连接:
要注意,编译内核时使用的交叉编译工具链并不一定适用于编译应用程序,licheepi nano的根文件系统为使用buildroot构建,根文件系统内的系统动态链接库由buildroot下载的交叉编译工具链生成,这个工具链位于buildroot/output/host下,要使用这个交叉编译工具链来编译应用程序。使用编译内核的交叉编译工具链编译应用程序的话,由于编译时动态链接的运行库和开发板根文件系统内的动态链接库版本可能不匹配,会导致程序运行时,找不到对应的动态链接文件而运行失败。
对于licheepi nano而言,编译内核时的交叉工具链为arm-linux-gnueabi-gcc,而buildroot在构建根文件系统时,默认往里面放的arm-linux-musleabi-gcc的动态链接库,所以编译应用程序时使用buildroot下载的arm-linux-musleabi-gcc。
这里我在Ubuntu16虚拟机中编译,这里需要用到musl的工具链。这里是下载连接:arm-linux-musleabi-cross.tgz、armv7l-linux-musleabihf-cross.tgz。
4.1 虚拟机开启ssh-server
首先给虚拟机安装openssh-server,以运行本机可以通过ssh连接虚拟机。
sudo apt-get install openssh-server
4.2 解压arm-linux-musleabi
Xshell的文件传输方式如下:
之后我们将文件解压,我选择将文件存放到“/usr/local/”下
接下来我们配置环境变量,编辑“/etc/profile”:
export PATH=___PATH___:$PATH
# 使得profile生效
source profile
# 查看PATH是否已添加成功
echo &PATH
五、编写程序
我们编写一个简单的Hello World。
#include <iostream>
int main()
{
std::cout << "Hello world" << std::endl;
return 0;
}
使用arm-linux-musleabi编译:
arm-linux-musleabi-g++ main.cpp -o main_exe
但是注意,这里的库在Nano上可能没有,使用如下命令查看所需的库:
arm-linux-musleabi-readelf -d main_exe
# Display
Dynamic section at offset 0xef8 contains 29 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so]
0x0000000c (INIT) 0x5f0
0x0000000d (FINI) 0x968
0x00000019 (INIT_ARRAY) 0x10eec
0x0000001b (INIT_ARRAYSZ) 8 (bytes)
0x0000001a (FINI_ARRAY) 0x10ef4
0x0000001c (FINI_ARRAYSZ) 4 (bytes)
0x00000004 (HASH) 0x14c
0x6ffffef5 (GNU_HASH) 0x1ac
0x00000005 (STRTAB) 0x300
0x00000006 (SYMTAB) 0x1d0
0x0000000a (STRSZ) 448 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x11000
0x00000002 (PLTRELSZ) 64 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x5b0
0x00000011 (REL) 0x538
0x00000012 (RELSZ) 120 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffb (FLAGS_1) Flags: PIE
0x6ffffffe (VERNEED) 0x4e8
0x6fffffff (VERNEEDNUM) 2
0x6ffffff0 (VERSYM) 0x4c0
0x6ffffffa (RELCOUNT) 7
0x00000000 (NULL) 0x0
我们到Nano的“/usr/lib/”下面可以发现,它差了几个库,我们可以将这几个库复制过去,也可以使用-static把库和源文件一起打包:
arm-linux-musleabi-g++ -static main.cpp -o main_exe
接下来将文件main_exe传输到Nano中,查看执行效果:
到这里,本节内容就结束了,下一节中我们将学习如何使用lvgl(littlevGL)库编写GUI。