1. IIoT网关开发环境搭建与最小可运行框架
任务目标
在 Linux 主机上搭建可交叉编译到 ARM 目标板的开发环境,并编写一个最小 IIoT 网关程序:启动后打印版本、设备 ID、监听端口等启动日志,然后进入主循环等待退出信号。程序需能在主机本地编译运行验证,也能用交叉工具链编译出 ARM 可执行文件。
环境与依赖
- 主机:Ubuntu/Debian 类 Linux,安装
build-essential、gcc、make。 - 交叉工具链:
gcc-arm-linux-gnueabihf(ARMv7 硬浮点,常见于工业网关/树莓派类板卡)。 - 目标板:运行 Linux 的 ARM 设备,具备串口或 SSH 用于部署。
sudo apt update
sudo apt install -y build-essential gcc-arm-linux-gnueabihf
最小框架代码
单文件 gateway.c,包含配置结构、启动日志、信号处理与主循环。用 #ifdef 区分主机与目标板编译,交叉编译时通过 -DTARGET_ARM 打开。
/* gateway.c - IIoT 网关最小可运行框架 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#define GW_VERSION "0.1.0"
typedef struct {
const char *device_id;
int listen_port;
int poll_interval_ms;
} gw_config_t;
static volatile sig_atomic_t g_running = 1;
static void on_signal(int sig) {
(void)sig;
g_running = 0;
}
static void print_banner(const gw_config_t *cfg) {
printf("========================================\n");
printf(" IIoT Gateway starting\n");
printf(" version : %s\n", GW_VERSION);
printf(" device_id : %s\n", cfg->device_id);
printf(" listen_port : %d\n", cfg->listen_port);
printf(" poll_interval: %d ms\n", cfg->poll_interval_ms);
#ifdef TARGET_ARM
printf(" build target : ARM (cross-compiled)\n");
#else
printf(" build target : HOST (native)\n");
#endif
printf("========================================\n");
}
int main(int argc, char **argv) {
gw_config_t cfg = {
.device_id = "gw-001",
.listen_port = 5020,
.poll_interval_ms = 1000,
};
/* 允许命令行覆盖设备 ID,便于多实例部署 */
if (argc > 1) cfg.device_id = argv[1];
signal(SIGINT, on_signal);
signal(SIGTERM, on_signal);
print_banner(&cfg);
printf("[gw] entering main loop, press Ctrl+C to stop\n");
while (g_running) {
/* 真实网关在此处轮询 Modbus/OPC UA 等设备并上报 */
printf("[gw] heartbeat device=%s port=%d\n",
cfg.device_id, cfg.listen_port);
usleep(cfg.poll_interval_ms * 1000);
}
printf("[gw] shutdown, bye\n");
return 0;
}
构建与运行
主机本地编译运行,验证逻辑正确:
gcc -Wall -O2 -o gateway_host gateway.c
./gateway_host gw-test
交叉编译到 ARM 目标板:
arm-linux-gnueabihf-gcc -Wall -O2 -DTARGET_ARM -o gateway_arm gateway.c
file gateway_arm # 应显示 ARM, EABI5, hard-float
部署到目标板(示例用 scp,实际可用串口/U 盘):
scp gateway_arm root@<board-ip>:/usr/local/bin/gateway
ssh root@<board-ip> '/usr/local/bin/gateway gw-001'
验证方法与通过条件
- 主机运行
./gateway_host gw-test,应看到 banner 中device_id=gw-test、build target : HOST,随后每秒打印一次 heartbeat。 - 按 Ctrl+C 后应打印
[gw] shutdown, bye并正常退出(退出码 0)。 file gateway_arm输出包含ARM与hard-float,说明交叉编译成功。- 目标板上运行
gateway_arm,banner 中build target : ARM (cross-compiled),heartbeat 正常输出,Ctrl+C 可退出。
以上四条全部满足即视为本案例通过。
常见问题
- 交叉编译报
arm-linux-gnueabihf-gcc: not found:确认已安装gcc-arm-linux-gnueabihf,或按目标板 ABI 换成aarch64-linux-gnu-gcc。 - 目标板运行报
No such file or directory:多为动态链接器不匹配,可加-static重新编译。 - heartbeat 不打印:检查
usleep参数单位(微秒),以及 stdout 是否被重定向缓冲,可加setvbuf(stdout, NULL, _IONBF, 0)。