第2章:Linux基础与嵌入式开发环境
说实话,很多做嵌入式Linux网关开发的朋友,最后卡住的往往不是MQTT协议本身,而是Linux环境不熟。我见过太多人,代码写得挺好,一上板子就抓瞎——文件传不上去、编译不过、调试不了。所以这一章,咱们先把地基打牢。
2.1 Linux常用命令回顾
嵌入式Linux网关,说白了就是个跑Linux的小电脑。你想想看,没有图形界面,全靠命令行。我个人的习惯是,先把下面这几类命令练到肌肉记忆。
2.1.1 文件与目录操作
| 命令 | 用途 | 我常用的参数 |
|---|---|---|
ls |
列出目录内容 | -la 看隐藏文件,-lh 人性化大小 |
cd |
切换目录 | cd - 回到上一个目录 |
cp |
复制文件/目录 | -r 递归复制目录 |
mv |
移动/重命名 | 注意跨文件系统时是复制+删除 |
rm |
删除 | -rf 慎用!我吃过亏 |
find |
查找文件 | -name "*.c" 按名字找 |
rm -rf / 少打了个点。嗯,从那以后我养成了习惯——每次敲 rm 之前,先 ls 确认一下路径。
2.1.2 进程与系统监控
网关设备跑起来之后,你最关心的就是:CPU占了多少?内存够不够?哪个进程在吃资源?
top/htop:实时看进程,按P按CPU排序,按M按内存排序ps aux:快照式查看所有进程,配合grep找特定进程free -h:看内存使用,注意available才是真正可用的df -h:看磁盘空间,嵌入式设备Flash通常很小netstat -tlnp:看端口监听,MQTT broker默认1883端口
watch -n 1 'netstat -tlnp' 每秒刷新一次,调试网络服务时特别好用。
2.1.3 网络调试三件套
做网关开发,网络调试是家常便饭。这三个命令我几乎每天用:
- ping:先确认网络通不通。注意嵌入式设备ping大包可能会卡死
- ifconfig / ip addr:看IP地址、MAC地址。我更喜欢
ip命令,信息更全 - tcpdump:抓包神器。比如抓MQTT报文:
tcpdump -i eth0 port 1883 -X
2.2 Vim编辑器使用
在嵌入式Linux上,没有VS Code,没有Sublime。你只能靠Vim或者Nano。我个人强烈建议学Vim——虽然入门曲线陡,但熟练之后效率极高。
2.2.1 三种模式
Vim的核心就三个模式,搞懂这个你就入门了:
| 模式 | 进入方式 | 能做什么 |
|---|---|---|
| 普通模式 | 启动Vim默认进入 | 移动光标、复制粘贴、删除 |
| 插入模式 | 按 i |
输入文字 |
| 命令模式 | 按 : |
保存退出、搜索替换 |
i 进插入,按 Esc 回普通,按 : 输命令。
2.2.2 我常用的Vim操作
刚开始别贪多,先记住这几个就够用了:
gg:跳到文件开头G:跳到文件末尾dd:删除当前行yy:复制当前行,p粘贴/keyword:搜索关键字,按n下一个:wq:保存退出:q!:不保存强制退出
Ctrl+S 想保存——结果终端卡死了!因为 Ctrl+S 是终端锁屏。按 Ctrl+Q 解锁。这个坑我踩过三次才记住。
2.3 Makefile基础
嵌入式Linux网关的代码,通常要在PC上交叉编译,然后传到板子上跑。Makefile就是管理编译过程的脚本。说白了,它告诉编译器:先编译哪个文件,链接哪些库,生成什么目标。
2.3.1 一个最简单的Makefile
# 最简单的Makefile
all: hello
hello: hello.c
gcc -o hello hello.c
clean:
rm -f hello
这个例子虽然简单,但包含了Makefile的核心三要素:目标(target)、依赖(prerequisites)、命令(recipe)。
2.3.2 嵌入式交叉编译的Makefile
在实际项目中,我们不会用PC的gcc,而是用交叉编译器。比如给ARM架构的网关编译:
# 交叉编译Makefile示例
CROSS_COMPILE = arm-linux-gnueabihf-
CC = $(CROSS_COMPILE)gcc
CFLAGS = -Wall -O2 -I./include
LDFLAGS = -L./lib -lpaho-mqtt3c
TARGET = mqtt_gateway
SRCS = main.c mqtt_client.c sensor.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(LDFLAGS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean
$@ 表示目标文件,$^ 表示所有依赖,$< 表示第一个依赖。这三个自动变量我几乎每个Makefile都会用。
2.4 SSH与SCP远程操作
网关设备通常没有显示器键盘,你只能通过网络远程操作。SSH和SCP就是你的双手。
2.4.1 SSH远程登录
基本用法:
ssh root@192.168.1.100
第一次连接会提示确认指纹,输入 yes 就行。我建议配置SSH密钥登录,省得每次输密码:
# 在PC上生成密钥
ssh-keygen -t rsa -b 4096
# 把公钥传到板子上
ssh-copy-id root@192.168.1.100
2.4.2 SCP文件传输
从PC传文件到板子:
scp mqtt_gateway root@192.168.1.100:/home/
从板子拉文件到PC:
scp root@192.168.1.100:/var/log/syslog ./
传整个目录加 -r:
scp -r config/ root@192.168.1.100:/etc/mqtt/
scp 到 /tmp(内存文件系统),确认没问题再拷到Flash里。
2.5 NFS网络文件系统挂载
开发阶段最痛苦的是什么?每次改一行代码,就要重新编译、scp上传、重启程序。用NFS可以解决这个问题——把PC上的目录直接挂载到板子上,板子运行的就是PC上的文件。
2.5.1 搭建NFS服务器(PC端)
以Ubuntu为例:
# 安装NFS服务器
sudo apt install nfs-kernel-server
# 创建共享目录
mkdir ~/nfs_root
# 编辑配置文件
sudo vim /etc/exports
# 添加一行(假设板子IP是192.168.1.100)
/home/username/nfs_root 192.168.1.100(rw,sync,no_subtree_check,no_root_squash)
# 重启服务
sudo systemctl restart nfs-kernel-server
2.5.2 板子上挂载NFS
# 创建挂载点
mkdir /mnt/nfs
# 挂载(假设PC IP是192.168.1.10)
mount -t nfs -o nolock 192.168.1.10:/home/username/nfs_root /mnt/nfs
# 验证
ls /mnt/nfs
-o nolock 是因为很多嵌入式板子的NFS客户端不支持文件锁。不加这个参数,挂载会失败。
2.5.3 开发工作流
有了NFS,开发流程变成这样:
- 在PC上写代码、编译
- 把编译好的文件放到
~/nfs_root目录 - 在板子上直接运行
/mnt/nfs/your_program - 改代码 → 重新编译 → 直接运行,不用再传文件
效率提升不是一点半点。我当年做一个网关项目,前期没用NFS,每天光传文件就浪费半小时。后来配好NFS,一天能多调好几个bug。
2.6 本章知识体系
下面这张图把本章的核心知识点串起来了:
这五个技能点,就像盖房子的五根柱子。Linux命令是地基,Vim是砌墙的瓦刀,Makefile是施工图纸,SSH/SCP是运输车,NFS是脚手架。缺了哪根,干活都不顺手。
嗯,这一章的内容就到这里。把这些练熟了,后面讲MQTT协议集成的时候,你就能把精力放在协议本身,而不是被环境问题绊住脚。