开发环境:

  • Ubuntu_18.04 VMware版
  • 开发板K4B T113-S3
  • Windows10
  • VMware 17

一、环境搭建

  • VMware 17
  • Ubuntu_18.04.6_VM 【密码:ubuntu】(下载地址)
    • passwd root 【修改登录密码】
    • 打开Software&Updates软件–>Ubuntu Software选项–>Dowload from:–>Other…–>China–>选择阿里或清华 【设置国内镜像下载源】
    • sudo apt-get update 【更新软件源列表】
    • sudo apt-get upgrade 【更新已安装的软件包】
    • sudo apt-get install open-vm-tools-desktop -y 【安装vm-tools】
    • sudo reboot
    • 配置vim常用设置
    • sudo vim /etc/vim/vimrc
    • " 显示行号
      set number
      " 高亮打开
      syntax on
      " 打开文件检测
      filetype on
      " 设置 tab 键的宽度为 4 个空格
      set tabstop=4
      " 设置当输入 tab 时,实际插入的空格数为 4
      set shiftwidth=4
      " 将 tab 转换为空格
      set expandtab
      " (可选)设置自动缩进时使用空格而不是 tab
      set softtabstop=4
      " 设置自动缩进
      set autoindent
      " 设置使用 c/c++ 语言的自动缩进方式
      set cindent
      
    • 安装vscode
    • sudo apt install snapd
    • sudo snap install code --classic

注意:SDK编译文档和相关资源联系BSP厂商提供,本文档所用开发板参考厂商提供的 t113-s3编译使用文档


二、功能实现

1.开发板【buildroot】

1.1 NFS环境搭建

服务端【Ubuntu18.04】

sudo apt-get install nfs-kernel-server
sudo mkdir -p /home/nfs
sudo vim /etc/exports 
#末尾添加共享路径和权限
/home/nfs *(rw,sync,no_root_squash)
cd sudo /etc/init.d/nfs-kernel-server restart
成功提示:[ ok ] Restarting nfs-kernel-server (via systemctl): nfs-kernel-server.service.
失败提示:[....] Restarting nfs-kernel-server (via systemctl): nfs-kernel-server.serviceJob for nfs-server.service canceled.
 failed! 可能是路径设置有问题,检查一下
 
 cat /etc/exports | grep nfs  #查看nfs版本,Linux驱动配置需要用到

客户端【开发板】

mkdir /mnt/nfs
mount -t nfs -o nolock 192.168.234.126:/home/nfs /mnt/nfs

buildroot编译NFS:

./build.sh menuconfig
<*> NFS clinet support

./build.sh buildroot_menuconfig
buildroot配置选项中选中nfs-utils和rpcbind

1.2 Wi-Fi连接

# vi /etc/wpa_supplicant.conf
# cat /etc/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
update_config=1

network={
        ssid="YYC"
        psk="12345678"
        key_mgmt=WPA-PSK
}
# wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -B
【如果执行失败,查看是否有wpa_supplicant进程,有就停止:
    ps aux|grep wpa_supplicant
    killall wpa_supplicant】
    
# udhcpc -i wlan0

2.Ubuntu虚拟机

2.1 配置交叉编译环境

  • 目标:在Ubuntu 主机上交叉编译一个应用程序,在Buildroot构建的系统开发板上运行

  • 步骤一:获取Buildroot编译后提供的交叉编译工具链【/home/ubuntu/t113-linux/out/toolchain/…】

  • 步骤二:设置交叉编译环境变量

  • vim ~/.bashrc   #当前用户环境变量配置,添加如下配置
    export ARCH=arm
    export PATH=/home/ubuntu/t113-linux/out/toolchain/gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabihf/bin:$PATH
    export CROSS_COMPILE=arm-linux-gnueabihf-
    source ~/.bashrc     #立即生效,不需要重启系统
    
  • 步骤三:使用 Buildroot 的 sysroot 环境编译【buildroot/…/sysroot】

2.2 Makefile模板,C/C++混编

#项目结构
#project--->include--->*.h/*.hpp
#       --->src--->bin--->myapp
#              --->build--->*.o
#              --->*.c/*.cpp
# 项目基本信息
PROJECT   := myapp
BUILD_DIR := build
BIN_DIR   := bin
SYSROOT   := /home/ubuntu/t113-linux/out/t113/evb1_auto/buildroot/buildroot/host/arm-buildroot-linux-gnueabihf/sysroot
SRC_DIR   := ../src
INC_DIRS  := ../include $(SYSROOT)/usr/include
LIB_DIRS  := $(SYSROOT)/usr/lib
LIBS      := sqlite3 z

# 编译器配置
CC       := $(CROSS_COMPILE)gcc
CXX      := $(CROSS_COMPILE)g++
CFLAGS   := -Wall -Wextra -std=c11 -g
CXXFLAGS := -Wall -Wextra -std=c++17 -g
#--sysroot 和 --rpath-link 显式传给链接器,彻底避免把 Ubuntu 18.04 的 x86_64 库拉进来
LDFLAGS  := --sysroot=$(SYSROOT) -Wl,-rpath-link=$(SYSROOT)/usr/lib $(addprefix -L,$(LIB_DIRS)) $(addprefix -l,$(LIBS))
INCLUDES := $(addprefix -I,$(INC_DIRS))

# 自动发现源文件
C_SRCS   := $(wildcard $(SRC_DIR)/*.c)
CPP_SRCS := $(wildcard $(SRC_DIR)/*.cpp)
OBJS     := $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(C_SRCS)) \
            $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(CPP_SRCS))

# 主目标:构建可执行文件
all: dirs $(BIN_DIR)/$(PROJECT)

# 创建必要目录
dirs:
	@mkdir -p $(BUILD_DIR) $(BIN_DIR)

# C编译规则
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

# C++编译规则
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
	$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@

# 链接规则(使用C++链接器)
$(BIN_DIR)/$(PROJECT): $(OBJS)
	$(CXX) $^ -o $@ $(LDFLAGS)

# 清理
clean:
	rm -rf $(BUILD_DIR) $(BIN_DIR)

# 安装(如需)
install: $(BIN_DIR)/$(PROJECT)
	cp $< /usr/local/bin

.PHONY: all clean dirs install

2.3 代码备份

#安装git工具
sudo apt install git
git --version

#配置信息,可以通过git config --list命令查看当前配置
git config --global user.name "Your Name"
git config --global user.email "youremail@example.com"

#第一次初始化创建本地仓库
git init
git add .
git commit -m "commit message"

#配置远程仓库
git remote add origin <remote-repository-URL>
#上传代码,空仓库可以直接使用--force,强制推送
git push -u origin master --force

后续更新代码只需执行
git add .
git commit -m "更新说明"
git push origin master

免密git push【gitee管理】

#每次push都需要输入账号和密码,使用ssh协议解决
ssh-keygen -t ed25519 -C "your_email@example.com 可以随便填"
cat ~/.ssh/id_ed25519.pub
#复制,登录 Gitee → 右上角头像 → 设置 → SSH公钥 → 添加公钥,粘贴刚才复制的公钥,保存。
ssh -T git@gitee.com
#输入yes,看到 "Hi xxx, You've successfully authenticated" 即成功
#修改远程地址为SSH
git remote set-url origin git@gitee.com:yun-yichen/t113code.git

一键上传脚本

vim update.sh
#添加如下内容到update.sh
#!/bin/bash
git pull origin master
git add -A
git commit -m "更新 $(date +%Y%m%d-%H%M%S)"
git push origin master


#可执行权限
chmod +x update.sh
#以后更新代码直接运行即可
./update.sh

三、问题总结

1. 编译成功并且烧录成功,但系统无法启动

烧录系统后无法启动,提示OP-TEE version错误,执行下面指令重新编译烧录
cd t113-linux
git reset --hard # 撤销所有本地修改
./build.sh lunch
./build.sh
./build.sh pack

2. 在Ubuntu 上构建开发板程序编译环境,glibc版本问题

在Ubuntu18 04上使用buildroot/.../sysroot环境编译开发板程序,遇到glibc版本不匹配
usr/lib/libsqlite3.so: undefined reference to `fcntl64@GLIBC 2.28'
collect2: error:ld returned lexit status

开发板运行/lib/libc.so.6查看到GLIBC版本是2.28  ----buildroot 201902
Ubuntu运行lld --version 查看到GLIBC版本是2.27  ----Ubuntu 18 04
以为是版本不同导致的,找了很多办法,发现两个系统都不好改,没解决。
查了一晚上发现glibc版本是编译工具链里面的
简单验证了一下交叉工具链的glibc版本是2.4
arm-linux-gnueabihf-gcc test.c -o test
strings test | grep GLIBC_
GLIBC_2.4
abort@@GLIBC_2.4
__libc_start_main@@GLIBC_2.4
更加确定了目前使用的交叉工具链没问题,继续确定问题
再执行arm-linux-gnueabihf-readelf -d ./bin/myapp | grep -E 'RPATH|RUNPATH'
如果为空说明没有设置 rpath/runpath,链接器会去默认系统目录找库,这就会把Ubuntu的x86_64拉进来,必然报错。

解决办法:
必须用 Buildroot 生成的交叉工具链来编译程序和库,才能确保 glibc 版本与开发板一致。
Makefile文件添加如下内容
SYSROOT   := /home/ubuntu/t113-linux/.../sysroot
#--sysroot 和 --rpath-link 显式传给链接器,彻底避免把 Ubuntu 18.04 的 x86_64 库拉进来
LDFLAGS  := --sysroot=$(SYSROOT) -Wl,-rpath-link=$(SYSROOT)/usr/lib

3. 开发板运行c++程序版本问题

#遇到开发板c++版本有问题,解决办法更新文件
root@kickpi:/mnt/nfs# ./myapp
./myapp: /lib/libstdc++.so.6: no version information available (required by ./myapp)
root@kickpi:/mnt/nfs# ls
hello           libstdc++.so.6  myapp
root@kickpi:/mnt/nfs# cp libstdc++.so.6 /lib/#
#文件在交叉编译工具目录
/home/ubuntu/t113-linux/.../arm-linux-gnueabihf/lib

四、结束语

本文记录了从零入手一个开发板的所有操作过程,最终实现使用虚拟机Ubuntu交叉编译开发板的程序,通过NFS下载到开发板上运行,代码备份到gitee仓库。通过上述配置,可以进入程序编写阶段,开启嵌入式软件编程之路。后续进阶可以考虑裁剪优化u-boot、Linux内核驱动、buildroot根文件系统。

更多推荐