交叉开发环境配置

交叉开发

1、交叉环境

​ 编译,就是把一种语言(如C语言) 翻译成 另一种语言(如机器语言)
​ 之前我们的编译环境 和 运行环境是相同的。

交叉编译:
也是编译,也是把一种语言翻译成另一种语言
但是,在嵌入领域中, 很多时候程序的运行环境 不适合 去编写和编译程序。
所以,我们把常规的 编写 编译 执行 的这几个步骤分开:
在PC机上编写程序
在PC机上编译程序
最后通过一些特殊的工具,把生成的目标代码(如可执行文件)传输到目标设备(如GEC6818开发板)上去执行。

​ 简单的说,交叉编译 就是在一种环境下 去编译 另一种环境的程序。

2、交叉编译器

​ 一般来说,交叉编译器由开发板厂商提供,也当然也可以自己去网上下载,如:
​ http://releases.linaro.org/components/toolchain
​ https://www.evryarm.com

安装交叉编译器:
*1、下载
从官网下载
从云盘下载
从飞秋下载…
gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi.tar.xz
可以使用指令uname -a查看系统版本:
结果显示中包含 x86_64,就是64位的系统,简称x64
结果显示中包含 i686,就是32位的系统,简称x86

下载完成后,把压缩包放到Ubuntu系统中去(共享目录也行)

2、解压
把下载的压缩包解压到一个合适的目录(不能解压到共享目录!),如/usr/local/ 目录
具体过程:
1、进入压缩包所在的目录,并能查看到它
cd /mnt/hgfs/Tools/交叉开发
ls
2、解压
sudo tar xvf gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi.tar.xz -C /usr/local/
解压完成后,会在/usr/local目录下生成一个 gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi 目录
自动生成的目录略微过长,使用不便,所以,改成一个短一点的名字,如 arm-linux
改名指令:
sudo mv gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi arm-linux

​ 3、给交叉编译器创建软链接
​ 进入交叉编译工具链所在目录
​ cd /usr/local/arm-linux/bin
​ 把创建软链接的脚本拷贝到当前目录
​ sudo cp /mnt/hgfs/Tools/交叉开发/myln-x64.sh ./
​ 执行脚本
​ sudo ./myln-x64.sh
​ 4、配置环境变量
​ 为了能够在任意目录下都能使用交叉编译器,我们需要把交叉编译器所在的路径添加到环境变量PATH中去
​ 临时添加指令:
​ PATH=/usr/local/arm-linux/bin:$PATH
​ 请确保该指令是正确的!(=两边不能有空格,分配符是英文的冒号,PATH必须大写)

​ 如果需要永久生效,需要把上述指令写入系统的启动配置文件中,并把PATH导出为环境变量
​ 可以写入这些文件的最后面(已有内容不要修改,只是在后面追加),使得配置永久生效:
​ /etc/profile 对所有的普通用户有效,只要登录系统,系统会自动读取该文件中的配置信息
​ ~/.bashrc 对当前用户用效,只要登录系统,自动读取。
​ 具体指令:
​ 打开配置文本:
​ sudo vim /etc/profile
​ 按快捷键shift+g(把光标定位到文件的最后一行)
​ 按i键,进入插入模式,在最后一行的后面,写入配置指令
​ 配置指令:
​ export PATH=/usr/local/arm-linux/bin:$PATH
​ 写入完成后,保存退出(按esc键,再:wq),重启系统。

​ 5、测试是否配置成功
​ 打开终端,输入指令, 查看交叉编译器的版本信息:
​ arm-linux-gcc -v

3、熟悉使用开发板

​ 开发板名称: GEC6818
​ 标准配置:
​ 底板
​ LCD液晶屏
​ 电源适配器
​ 串口线
​ USB-Serial线

最简单基本的使用:
接上电源,接好串口线,开机
开机能看到登录界面 或 能看到粤嵌的LOGO图标

PC机与开发板的连接,需要一些专门的软件,用于操作开发板上的系统,如:
SecureCRT (我们选择这个)
Xshell
putty

在第一次使用USB-Serial线连接开发板时,可能需要安装这根线的驱动!
如何确认呢?
1、打开设备管理器
如果一切正常应该能看到 端口选项(USB-SERIAL CH340(COMX))
如果接好线,也没有看到这个选项,看下有没有 《其它设备》这个选项,如果有,那么可能需要安装驱动(推荐使用驱动精灵安装)
如果上面两个选项都没,那么请先关闭虚拟机,拔掉USB转串口线,重新接入。
如果还不行,请检查线是否接好
如果还不行,换一根确定是好的线再试一试。

2、打开SecureCRT
菜单-> 快速连接
协议:serial
端口:请查看设备管理器
波特率:115200
数据位:8 (默认就是,不要修改)
奇偶校验: None(默认就是,不要修改)
停止位:1(默认就是,不要修改)
流控:都不要(去掉中间的那默认的勾)

​ 设置完成后,点击连接按钮即可。

​ 如果是先接线,再启动开发板,那么在SecureCRT界面,会看到系统的启动信息,启动时间6秒左右。
​ 启动成功后,按下回车,或输入其它的指令,以确认一切正常。

3、第一次操作开发板
创建自己的工作目录(类似PC端的家目录)
mkdir /home/china -p
以后每次开机,请先进入你的工作目录。
以后尽量不要去随意修改(如创建/删除)工作目录之外的文件。

4、通过串口传输文件到开发板
rx(默认就有)
常规使用步骤:
1、rx 文件名
2、回车
3、菜单->传输->发送Xmodem
4、在弹出的文件对话框中选择你需要传送的文件,即可
5、稍等几秒钟,就能看到数据的传输过程
6、如果要传输的文件是可执行文件,那么在执行之前需要添加可执行文件权限,指令如下:
chmod +x 文件名
7、按常规方式执行程序即可。
rz(需要自己配置)
1、进行自己的工作目录
cd /home/china
2、rx arm-rz.tar.xz
3、发送完成后,解压
tar xvf arm-rz.tar.xz
4、进入解压生成的arm-rz目录
5、执行该目录下的脚本
7、使用rz时,原则上,输入rz后,直接回车就能弹出文件对话框
如果要发送的文件在开发板上已经存在了,那么
要么把已存在的文件删除
要么rz -y
5、从开发板传输文件到PC
sz 文件名

6、使用tftp网络服务把文件从Ubuntu中传输到开发板
tftp是一个简单文件传输协议,是一个基于Client/Server的网络应用程序
我们这里是把ubuntu18.04做为服务器,开发板是做为客户端的。
客户端只需要网络畅通就行,而服务端需要做一些安装配置
a.服务端的安装配置:
1、先创建一个tftp服务目录,如:
mkdir -p /home/china/tftpboot
chmod 777 tftpboot
2、下载安装
sudo apt install tftpd-hpa
3、配置
打开配置文件:
sudo vi /etc/default/tftpd-hpa
修改该文件中的配置为:

/etc/default/tftpd-hpa

​ TFTP_USERNAME=“tftp”
​ TFTP_DIRECTORY="/home/china/tftpboot" # 设置自己的服务目录
​ TFTP_ADDRESS=“0.0.0.0:69” # 设置IP地址,为本机的任意IP
​ TFTP_OPTIONS="-l -c -s" # 设置上传/下载的权限
​ 配置完成后,保存退出即可。

​ 4、重启tftp服务
​ sudo /etc/init.d/tftpd-hpa restart
​ 注:
​ 可以对tftp进行如下操作:
​ start 启动
​ restart 重启
​ stop 停止
​ status 查看状态

​ b.客户端配置
​ 客户端需要配置IP地址,配置IP有手动和自动之分
​ 使用指令 udhcpc 来自动获取IP地址,获取成功后,可使用ifconfig查看
​ 还可以使用 ping 网关IP ,来确认网络畅通

​ 使用tftp服务:
​ 1、把需要发送的文件 放到 tftp的服务目录,也就是 /home/china/tftpboot
​ 2、查看服务端的IP地址,也就是ubuntu的IP,使用指令ifconfig
​ 3、切换到SecureCRT, 进入工作目录
​ 4、执行下载指令:
​ tftp -g -r 文件名 服务端的IP
​ 例:
​ tftp -gr shui.mp3 192.168.2.157

​ 注:
​ 在使用tftp的过程中,可能会碰到一些常见的错误,如
​ 错误1: tftp: server error: (1) File not found
​ 解决方案:查看文件名是否正确,查看服务目录是否有你需要下载的文件

​ 错误2:tftp: timeout
​ 解决方案:检查服务端IP是否正确,检查网络是否畅通(ping 服务端IP), 网线有没有接好等

​ 错误3:tftp: sendto: Network is unreachable
​ 解决方案:请正确配置开发板的IP地址(在局域网内,推荐使用udhcpc)

4、动态库和静态库

  1. 库 library
    库 是一种二进制的封装形式,简单的说,库中封装了一堆的目标文件(.o)
    当库封装好之后,就可以在其他(文件/程序)地方去使用它,但是用户是无法看到它的内部实现的。
    库的这种做法有利于 代码模块化,只要函数接口设计合理,改变库的内部实现,不会影响用户级别的代码使用。

根据库的封装和链接格式,可以把库 分成 静态库 和 共享库(动态库)。

  1. 静态库
    静态库的特点:
    当把目标文件封装成静态库之后,如果有其它程序需要用到库中的功能,编译器会把相关代码直接拷贝到你的程序中去
    当程序编译完成后,运行时不再依赖静态库
    但是如果静态库更新了,你的程序必须再次编译
    创建静态库:
    1、编写源代码
    vi sum.h
    vi sum.c
    2、把源代码编译成目标文件
    gcc sum.c -c
    3、把目标文件封装成库
    ar -rc lib库名.a 目标文件
    例:
    ar -rc libmath.a sum.o
    说明:
    库的前级建议以 lib开头,静态库以.a结尾
    -rc中r 表示插入目标文件到静态库中去,c表示创建指定的静态库。

使用静态库:
用户在编译使用了库的代码时,需要指定头文件和库文件所在路径 及 库的 名字,格式如下:
gcc 源文件/目标文件 -I 头文件所在路径 -L 库文件所在路径 -l库名
编译完成后,程序运行不再需要这个静态库。

  1. 共享库(动态库)
    动态库的特点:
    当把目标文件封装成共享库之后,如果有其它程序需要用到库中的功能,编译器不会去拷贝相关的代码,而仅仅是做一个标记
    当程序执行时,根据这个标记去查找相关的代码,也就是说,程序执行时依赖于共享库。
    所谓依赖于某个库,指这个库必须存在,且编译器知道它的路径。
    当共享库更新后,只要接口不变,用户程序一般不需要做任何改变。

  2. 创建共享库:
    1、编写源代码
    vi sum.h
    vi sum.c
    2、把源代码编译成目标文件
    gcc sum.c -c -fPIC
    3、把目标文件封装成库
    gcc -shared -fPIC -o lib共享库名.so 目标文件
    例:
    gcc -shared -fPIC -o libmath.so sum.o sub.o
    注:
    -shared 指要创建一个共享库
    -fPIC 表示要生成与位置无关的代码
    -o 要创建的库的名字,一般约定共享库的名字格式为:
    lib库名.so

  3. 使用共享库:
    用户在编译使用了库的代码时,需要指定头文件和库文件所在路径 及 库的 名字,格式如下:
    gcc 源文件/目标文件 -I 头文件所在路径 -L 库文件所在路径 -l库名
    编译完成后,程序运行还需要这个共享库。
    用以下方式指定运行时库的路径:
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:共享库所在路径

5、make

  1. 为什么需要make
    在我们的实际开发中,如果仅使用gcc来编译程序,效率较低:
    程序往往由多个模块(.h/.c)组成,源文件个数越来越多,那么GCC命令行就会越来越长,而且编译规则 还会增加命令行的复杂度。
    在编码工作中,调试时间往往大于编码时间,在调试的时候,每次可能 只会修改部分源文件,但是使用GCC命令行编译程序时,那些没有修改过的源文件也会被编译,会大大的影响编译效率。
    所以,我们需要一个工具能够自动检查文件的更新情况、自动进行编译。
    这个工具就叫做make
    make是由GNU项目提供的一个命令行的项目管理工具。

    make是一个工具,它能自动检查文件的更新情况,并能自动进行编译,那么它是怎么知道我们的项目中有哪些文件的呢?以及这些文件应该怎么编译的?

  2. Makefile
    make工具有一个专门的配置文件,我们只需要把项目相关的信息写入这个配置文件,make会自动的去读取这个配置文件,并根据配置文件中的规则 进行工作。
    这个配置文件,就叫做makefile

Makefile怎么写?
Makefile可理解为一门小型的编程语言,它有变量、流程控制、函数等,可以很复杂。
但不管怎么复杂,它的核心规则 是一样的:
需要生成的目标文件(target)
生成目标文件所需要的依赖文件(dependency)
生成目标文件的编译规则(command)

以上三个核心规则以如下形式进行组织:
target: dependency
command

说明:
编译规则command前必须加一个tab键
一个Makefile文件中目标可以有多个,可分两类:
真正的目标:
指需要生成一个文件的这种目标,如 可执行文件等
make自动执行第一个目标,所以一般我们把真正的目标写在最前面
如果需要执行其它目标,那么必须在make时明确说明
make
make 目标名
伪目标:
指不需要生成某个文件的目标,只是想执行某个操作
最常用的伪目标: clean 和 install
伪目标必须在make时明确指出,而且通常出现在真正的目标的后面
make clean # 一般用于清除中间及结果文件
make install # 一般用于拷贝/移动结果文件到指定的目录

  1. makefile中的变量
    makefile中的变量可分成多种,如自定义变量、内置变量、自动变量等
    makefile中的变量是没有类型的,或者说只有字符串类型
    定义一个变量,只需要起一个名字,然后给它一个值即可。

引用变量时,不能直接使用变量名,而需要在变量名前加一个$符号,如果变量名由多个字符组成,还需要用括号把变量名括起来。
例:

  1. 直接赋值
    变量名 := 值

  2. 递归赋值
    变量名 = 值
    A = $B
    B = hello

  3. 追加赋值
    变量名 += 值
    A = hello
    A += world

  4. 条件赋值
    变量名 ?= 值
    如果变量没有定义过,则定义,否则 什么都不做。
    A = hello
    A ?= world

内置变量:
CC 表示C语言编译器,默认值为 cc
CXX 表示C++编译器,默认为g++

自动变量:
@ 在编译规则中表示目标的名字
< 表示第一个依赖文件的名字
^ 表示所有的依赖文件的名字

  1. makefile中的函数
    makefile中有很多内置函数,可供用户直接使用。
    调用规则:
    $(函数名 参数列表)

函数wildcard:
调用方式: $(wildcard PATTERN)
功能: 获取匹配模式为PATTERN的文件名
返回:匹配模式为PATTERN的文件名
例:
SRC := $(wildcard *.c)
如果当前目录下有a.c, b.c等,那么变量SRC的值就是 a.c b.c

函数patsubst:
调用方式: $(patsubst PATTERN, REPLACE, TEXT)
功能: 按照PATTERN指定的模式从TEXT搜索子字符串,并将它们替换成REPLACE
返回: 返回替换之后的新字符串
例:
DEPENDENCY := $(patsubst %.c, %.o, $(SRC))
如果SRC的值为a.c b.c 那么,DEPENDENCY的值为a.o b.o

6、实践

  1. 下载源码
    官网
    云盘
    飞秋

    下载完成后,把源码包拷贝到linux系统

  2. 解压
    进入源码压缩包所在目录(如我的共享目录)
    cd /mnt/hgfs/20197/20200702-0704-交叉开发/
    解压到指定目录(指定目录必须存在)
    tar xvf libjpeg-turbo-1.5.1.tar.gz -C /home/china/opensrclib/
    进入解压后生成的源码目录
    cd /home/china/opensrclib/libjpeg-turbo-1.5.1

  3. 配置(如果一切正常,会生成Makefile)
    ./configure --prefix=/home/china/opensrclib/libjpeg-arm --host=arm-linux

说明:
–prefix: 指定安装目录,该目录可以不存在,安装时会自动创建
–host: 目标平台

  1. 编译
    make

  2. 安装(把生成的结果,分类存放到prefix指定的目录中去,正常情况会生成四个目录:bin/ include/ lib/ share/)
    make install

  3. 打包移植
    我们需要把生成的那个lib目录中所有的文件移植到开发板上去
    进入安装目录:
    cd /home/china/opensrclib/libjpeg-arm
    压缩打包:
    tar Jcvf jpeglib.tar.xz lib/
    把生成的压缩包,传输(如rx/rz/tftp等)到开发板的工作目录下

  4. 配置开发板上库的路径
    进入开发板的工作目录,解压上一步传输过来的压缩包
    cd /home/china
    tar xvf jpeglib.tar.xz
    解压生成一个lib目录,该lib目录的绝对路径为: /home/china/lib/
    把lib的绝对路径添加到环境变量LD_LIBRARY_PATH中去

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/china/lib/

确保上述指令正确后,可以把该指令写入/etc/profile文件的末尾,以使其永久生效!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值