2. 嵌入式系统基础
说实话,嵌入式BSP开发的第一步,往往不是写代码,而是搭环境。我见过太多新手一上来就急着敲代码,结果卡在工具链报错上半天出不来。这一章,咱们就把这些基础工具一次性搞定。
本章核心目标:搭建一套可用的嵌入式开发环境,涵盖交叉编译、网络传输、串口调试和版本管理四个维度。这些工具会贯穿整个BSP开发周期。
2.1 交叉编译工具链安装
为什么需要交叉编译?说白了,你的开发机是x86架构,目标板是ARM架构。x86上编译的程序,ARM跑不了。反过来,ARM上跑的程序,你也得在x86上编译好再传过去。
我个人习惯用Linaro提供的工具链,稳定且社区支持好。以ARM Cortex-A系列为例,我们选择gcc-arm-linux-gnueabihf。
2.1.1 安装步骤
# 更新软件源
sudo apt update
# 安装交叉编译工具链
sudo apt install gcc-arm-linux-gnueabihf
# 验证安装
arm-linux-gnueabihf-gcc --version
安装完成后,你可以用which命令看看它装在哪了。我记得第一次装的时候,找了半天才发现它在/usr/bin/下。
2.1.2 测试编译
写一个简单的hello world,验证工具链是否正常工作。
// hello.c
#include <stdio.h>
int main() {
printf("Hello, BSP World!\n");
return 0;
}
# 编译
arm-linux-gnueabihf-gcc -o hello hello.c
# 查看生成的文件类型
file hello
你会看到输出类似:ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV)。这说明编译出来的确实是ARM架构的程序。
我曾经踩过的坑:一开始我直接用gcc编译,然后传到板子上跑,结果报错"Exec format error"。后来才意识到,本地gcc编译的是x86程序,ARM板子根本不认。所以,每次编译前先确认你用的是交叉编译器。
2.2 TFTP/NFS服务器配置
开发过程中,你需要频繁地把编译好的内核、设备树、应用程序传到板子上。用U盘拷?太慢了。用网线传?TFTP和NFS就是干这个的。
2.2.1 TFTP服务器
TFTP用于传输单个文件,比如内核镜像zImage或设备树.dtb。它简单、轻量,适合uboot阶段加载内核。
# 安装TFTP服务器
sudo apt install tftpd-hpa
# 配置TFTP目录
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
# 修改配置文件 /etc/default/tftpd-hpa
# 确保内容如下:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure"
# 重启服务
sudo systemctl restart tftpd-hpa
配置好后,把文件丢到/srv/tftp目录下,板子上电后就能通过uboot的tftp命令下载了。
2.2.2 NFS服务器
NFS用于挂载整个文件系统。调试阶段,你可以在主机上修改文件,板子上实时生效,省去反复烧写的麻烦。
# 安装NFS服务器
sudo apt install nfs-kernel-server
# 创建共享目录
sudo mkdir -p /srv/nfs/rootfs
# 修改配置文件 /etc/exports
# 添加一行:
/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
# 重启服务
sudo systemctl restart nfs-kernel-server
小技巧:NFS挂载时,板子上的内核命令行参数要加上root=/dev/nfs nfsroot=服务器IP:/srv/nfs/rootfs。我第一次配的时候忘了写IP,结果板子一直卡在挂载阶段,折腾了半小时才发现。
2.3 串口终端工具使用
串口是嵌入式开发中最基础的调试手段。板子没网口?没关系,串口总能用的。我个人最常用的是minicom和screen。
2.3.1 minicom配置
# 安装minicom
sudo apt install minicom
# 启动配置
sudo minicom -s
# 在配置菜单中设置:
# - 串口设备:/dev/ttyUSB0(根据实际情况调整)
# - 波特率:115200
# - 数据位:8
# - 停止位:1
# - 校验:无
# - 硬件流控:关闭
配置好后保存为默认配置,下次直接输入minicom就能连上。
2.3.2 使用screen
如果你不想装minicom,用screen也行,更轻量。
# 安装screen
sudo apt install screen
# 连接串口
sudo screen /dev/ttyUSB0 115200
# 退出:Ctrl+A 然后按 K,再按 Y 确认
注意:串口设备文件/dev/ttyUSB0的权限问题。如果你不是root用户,需要把自己加到dialout组里:sudo usermod -aG dialout $USER。然后重新登录生效。我刚开始用的时候,每次都要sudo,后来加了组才省事。
2.4 版本控制Git入门
做BSP开发,代码版本管理是必须的。你想想看,内核源码、设备树、驱动代码、配置文件,改来改去,没有Git根本理不清。Git的基本操作其实不多,掌握下面几个就够了。
2.4.1 初始化仓库
# 在项目目录下初始化
cd my_bsp_project
git init
# 配置用户信息(第一次使用)
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
2.4.2 日常操作流程
| 操作 | 命令 | 说明 |
|---|---|---|
| 查看状态 | git status |
查看哪些文件被修改了 |
| 添加文件 | git add 文件名 |
把修改加入暂存区 |
| 提交修改 | git commit -m "描述" |
把暂存区的内容提交到仓库 |
| 查看历史 | git log |
查看提交记录 |
| 分支操作 | git branch |
创建/查看/切换分支 |
2.4.3 实际场景示例
假设你正在调试一个GPIO驱动,改了好几次。用Git管理的话,你可以这样操作:
# 第一次修改
git add gpio_driver.c
git commit -m "feat: 添加GPIO输出功能"
# 发现bug,修复后
git add gpio_driver.c
git commit -m "fix: 修复GPIO输出电平反转问题"
# 查看修改历史
git log --oneline
我的习惯:每次提交前,先用git diff看看改了哪些内容,确认无误后再提交。这样能避免把调试用的临时代码也提交进去。
2.4.4 避坑指南
- 不要提交编译产物:比如
.o文件、可执行文件。用.gitignore文件把它们排除掉。 - 提交信息要写清楚:别写"fix bug"这种废话,要写"fix: 修复UART接收超时导致系统挂死"。
- 经常提交:改一个功能就提交一次,别攒一堆再提交。否则回退的时候你会后悔的。
小建议:刚开始用Git时,可以创建一个测试仓库随便玩。我当年就是在测试仓库里反复练习reset、rebase、cherry-pick,才慢慢熟练起来的。别怕搞坏,反正只是测试仓库。
好了,这一章的内容就这些。工具链、网络服务、串口、Git,这四个工具配齐了,你的BSP开发环境就算搭建完成了。接下来,就可以开始真正的BSP开发了。