第2章:Linux基础与嵌入式开发入门
做嵌入式Linux开发,说白了就是跟Linux系统打交道。我见过不少新手,一上来就急着写代码,结果连文件都传不到板子上,折腾半天。这一章,我把最常用的几个技能点串起来,都是我在项目里每天都要用的东西。
2.1 Linux常用命令回顾
嵌入式开发不像桌面开发,你大部分时间面对的是命令行。嗯,这里没有鼠标,只有键盘。
2.1.1 文件操作三板斧
| 命令 | 作用 | 我常用的参数 |
|---|---|---|
ls |
列出目录内容 | -l 详细列表,-a 显示隐藏文件 |
cd |
切换目录 | cd - 回到上一个目录 |
cp |
复制文件/目录 | -r 递归复制目录 |
mv |
移动或重命名 | 源和目标在同一目录就是重命名 |
rm |
删除 | -rf 强制递归删除(慎用!) |
rm -rf / 时手抖多打了个空格……从那以后,我每次敲 rm -rf 都会先看一眼当前目录。
2.1.2 查看文件内容
cat:适合小文件,直接打印到终端more/less:分页查看,less支持上下翻页和搜索head/tail:只看头尾几行,tail -f实时跟踪日志
我个人习惯用 less 看代码,用 tail -f 看调试输出。你想想看,嵌入式板子跑起来后,串口日志哗哗地刷,tail -f 就是你的眼睛。
2.1.3 进程与资源查看
ps aux:查看所有进程top/htop:动态查看CPU和内存占用free -h:查看内存使用情况df -h:查看磁盘空间
top 可能没有,但 ps 和 free 基本都有。如果发现进程CPU占用异常,先怀疑是不是死循环了。
2.2 Vim编辑器使用
Vim是嵌入式开发者的标配。别想着在板子上装VS Code,不现实。我刚开始用Vim时也觉得反人类,但用顺手后,效率是真的高。
2.2.1 三种模式
| 模式 | 进入方式 | 作用 |
|---|---|---|
| 普通模式 | 启动Vim默认进入 | 移动光标、复制粘贴、删除 |
| 插入模式 | 按 i |
输入文本 |
| 命令模式 | 按 : |
保存退出、搜索替换 |
2.2.2 救命操作
:wq保存并退出:q!不保存强制退出(当你改乱了的时候)dd删除当前行yy复制当前行,p粘贴/关键词搜索,按n跳到下一个
i 进入编辑、Esc 退出、:wq 保存退出这三步,你就能活下来。
2.3 Makefile基础
嵌入式项目不可能一个文件搞定。你想想看,几十个源文件,手动编译得累死。Makefile就是告诉编译器:先编译谁,后链接谁。
2.3.1 最简单的Makefile
# 目标: 依赖
hello: hello.c
gcc -o hello hello.c
clean:
rm -f hello
执行 make 就会编译,make clean 清理。我在项目中遇到过新手把 clean 写成 clean: 漏了冒号,结果make报错半天找不到原因。
2.3.2 变量与自动推导
CC = arm-linux-gnueabihf-gcc
CFLAGS = -Wall -O2
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
app: main.o uart.o mqtt.o
$(CC) $^ -o $@
$@表示目标文件名$<表示第一个依赖文件$^表示所有依赖文件
CC 换成你的交叉编译器路径。我习惯把编译器路径定义在Makefile顶部,换平台时只改一行。
2.4 SSH与NFS网络文件系统挂载
嵌入式开发中,板子通常没有显示器键盘。你怎么操作它?靠网络。
2.4.1 SSH远程登录
SSH就是给你的板子开一个远程终端。板子连上网络后,你在电脑上执行:
ssh root@192.168.1.100
输入密码,你就进入了板子的命令行。我在项目中经常同时开三个SSH窗口:一个看日志,一个改代码,一个监控系统状态。
2.4.2 NFS挂载
NFS可以把电脑上的一个目录,挂载到板子上。这样你在电脑上改代码,板子上直接就能运行,不用每次都用U盘拷。
电脑端(NFS服务器)配置:
# 编辑 /etc/exports
/home/user/project 192.168.1.0/24(rw,sync,no_subtree_check)
# 重启NFS服务
sudo systemctl restart nfs-kernel-server
板子端(NFS客户端)挂载:
mount -t nfs -o nolock 192.168.1.10:/home/user/project /mnt
-o nolock,结果文件锁导致程序崩溃。嵌入式板子的NFS客户端通常不支持锁,加上 nolock 能避免很多坑。
2.5 嵌入式Linux系统启动流程
理解启动流程,你才知道板子从通电到跑起你的程序,中间经历了什么。出了问题也知道去哪查。
2.5.1 各阶段详解
- BootROM:芯片上电后,内部固件先跑。它初始化最基本的硬件(时钟、片内SRAM),然后去固定的位置(通常是SPI Flash或SD卡)找Bootloader。
- Bootloader(u-boot):这是嵌入式开发者的第一道关卡。u-boot初始化DDR、串口、网卡等外设,然后从Flash或网络加载内核到内存,最后跳转到内核入口。
- Linux Kernel:内核解压后,初始化所有硬件驱动,挂载根文件系统。如果内核崩溃,通常会在串口打印
Kernel panic。 - 根文件系统:内核挂载rootfs后,执行
/sbin/init程序。init进程是用户空间的第一个进程,PID为1。 - 用户应用程序:init根据配置文件(如
/etc/inittab或systemd的service文件)启动你的MQTT网关程序。
2.5.2 常用启动参数
在u-boot中,你可以设置内核启动参数。我常用的几个:
setenv bootargs 'console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootfstype=ext4'
saveenv
boot
console=ttyS0,115200:指定串口终端,波特率115200root=/dev/mmcblk0p2:根文件系统在SD卡第二个分区rw:以读写方式挂载
root=/dev/nfs nfsroot=192.168.1.10:/nfsroot ip=dhcp。
嗯,这一章的内容就这些。命令、编辑器、Makefile、网络挂载、启动流程,都是你后面做MQTT网关项目时每天都要打交道的东西。别急,先练熟这几个基础操作,后面写代码才顺手。