4、移植前的准备工作:获取源码、搭建交叉编译环境、准备目标硬件板卡
说实话,很多人一上来就急着改代码、调参数,结果编译都过不了,板子也跑不起来。我见过不少同事,花了两周时间移植,最后发现是工具链版本不对——这种坑,咱们完全可以提前避开。
这一章,我就带你走一遍移植前的“三件套”:源码怎么拿、环境怎么搭、板子怎么准备。这三步走稳了,后面移植就是水到渠成的事。
4.1 获取TLS协议栈源码
目前嵌入式领域主流的TLS协议栈就那么几个。我个人习惯用 mbedTLS(现在叫PolarSSL的升级版),因为它对资源受限设备非常友好。当然,如果你需要完整的X.509证书链验证,WolfSSL 也是个不错的选择。
4.1.1 源码下载渠道
| 协议栈 | 官方仓库 | 推荐版本 | 说明 |
|---|---|---|---|
| mbedTLS | github.com/ARMmbed/mbedtls | 2.28.x LTS | 长期支持版,稳定 |
| WolfSSL | github.com/wolfSSL/wolfssl | 5.6.x | 商业支持好,性能强 |
| OpenSSL(轻量版) | github.com/openssl/openssl | 1.1.1 | 功能全,但体积大 |
4.1.2 获取源码的具体操作
以 mbedTLS 为例,我一般这样操作:
# 克隆仓库
git clone --branch v2.28.7 https://github.com/ARMmbed/mbedtls.git
# 进入目录
cd mbedtls
# 查看版本信息
git tag -l 'v2.28*'
嗯,这里要注意:不要直接拉 master 分支。master 分支可能包含实验性代码,稳定性没保障。我吃过这个亏——有一次用 master 分支编译,结果某个内部函数签名变了,导致整个应用层都得跟着改,那叫一个折腾。
4.2 搭建交叉编译环境
交叉编译环境,说白了就是在PC上生成目标板能运行的二进制文件。你想想看,你的开发电脑是x86架构,但目标板可能是ARM、RISC-V或者MIPS,没有交叉编译器,代码根本跑不起来。
4.2.1 选择交叉编译工具链
工具链的选择取决于你的目标硬件。我整理了一个对照表:
| 目标架构 | 推荐工具链 | 下载方式 |
|---|---|---|
| ARM Cortex-M | arm-none-eabi-gcc | ARM官网或apt安装 |
| ARM Cortex-A | aarch64-linux-gnu-gcc | Linaro或发行版源 |
| RISC-V 64 | riscv64-unknown-elf-gcc | SiFive官网 |
| MIPS | mips-linux-gnu-gcc | Buildroot或OpenWrt |
4.2.2 配置环境变量
工具链装好后,记得把路径加到环境变量里。我习惯这样配:
# 编辑 ~/.bashrc 或 ~/.zshrc
export PATH=$PATH:/opt/gcc-arm-none-eabi-9-2020-q2-update/bin
export CROSS_COMPILE=arm-none-eabi-
export CC=${CROSS_COMPILE}gcc
export AR=${CROSS_COMPILE}ar
export LD=${CROSS_COMPILE}ld
配完之后,记得 source ~/.bashrc 让它生效。然后跑一下 arm-none-eabi-gcc --version,看到版本信息就说明环境搭好了。
4.2.3 验证工具链
写一个简单的测试程序,交叉编译看看:
// test.c
#include <stdio.h>
int main() {
printf("Hello, TLS World!\n");
return 0;
}
// 编译
arm-none-eabi-gcc -o test.elf test.c
// 查看文件类型
file test.elf
// 输出应该类似:ELF 32-bit LSB executable, ARM, version 1 (SYSV)
如果 file 命令显示的是ARM架构,那就说明交叉编译环境没问题了。
4.3 准备目标硬件板卡
硬件准备这块,很多人觉得不就是把板子通电嘛。其实没那么简单——你得确保板子的网络接口、存储、调试接口都处于可用状态。
4.3.1 硬件清单检查
我每次移植前都会对照这个清单检查一遍:
- 网络接口:以太网PHY是否正常?WiFi模块能否初始化?
- 存储:Flash/RAM容量是否满足TLS协议栈需求?mbedTLS最小配置需要约45KB Flash和8KB RAM。
- 调试接口:SWD/JTAG能否正常连接?串口打印是否可用?
- 时钟:系统时钟是否稳定?RTC是否可用(TLS需要时间戳)?
一个容易被忽略的点:TLS握手需要随机数生成器。很多MCU的硬件随机数发生器(TRNG)默认是关闭的,或者需要配置时钟才能用。我建议你在移植前先写一个简单的测试程序,确认 rand() 或者硬件TRNG能正常产生随机数。
4.3.2 搭建基础工程框架
硬件板卡准备好之后,我通常会先搭建一个“最小工程框架”。这个框架包含:
- 板级支持包(BSP):时钟、GPIO、UART初始化
- 网络驱动:以太网MAC+PHY初始化,能ping通
- 调试输出:通过串口打印日志
- 内存管理:malloc/free或者自定义内存池
说白了,就是先让板子“活起来”,能跑一个简单的循环打印。然后再把TLS协议栈加进来。
4.3.3 验证网络连通性
这一步很关键。我见过有人移植完TLS,发现握手失败,查了半天结果是网线没插好。所以,在移植TLS之前,先确认网络层是通的:
// 伪代码:验证网络连通性
void network_test() {
// 1. 初始化以太网
eth_init();
// 2. 获取IP地址(DHCP或静态)
ip_addr_t ip = get_ip_address();
printf("IP: %s\n", ipaddr_ntoa(&ip));
// 3. Ping网关
if (ping("192.168.1.1") == SUCCESS) {
printf("Network is OK!\n");
} else {
printf("Network failed, check cable!\n");
}
}
如果ping不通,先别急着移植TLS。检查PHY芯片的寄存器、检查网口指示灯、检查MAC层的DMA配置——这些基础问题不解决,TLS移植就是空中楼阁。
4.4 本章知识体系总览
下面这张图,把移植前的准备工作串起来了。你可以把它当作一个检查清单:
好了,准备工作就绪。源码拿到了,交叉编译环境跑通了,板子也能正常通信了。接下来,我们就可以正式进入TLS协议栈的移植环节了。