3、软件系统架构:嵌入式Linux系统、应用层软件、通信协议栈、远程管理平台

说到售货机的软件系统,很多人第一反应就是「不就是个卖东西的机器嘛」。其实不然。一台轨道交通里的售货机,它的软件架构远比你想的复杂。我这些年调试过的机器,少说也有上千台了,踩过的坑能写满一本笔记本。今天咱们就聊聊这个软件架构的四个核心层次。

3.1 嵌入式Linux系统——机器的「骨架」

为什么选Linux?说白了,稳定。轨道交通环境里,机器一开就是几个月不关机。你想想看,要是用个普通单片机,内存泄漏、任务调度卡死,那运维人员得疯掉。

我个人习惯用Yocto来裁剪Linux内核。为什么?因为售货机不需要桌面环境,不需要图形驱动,甚至连USB协议栈都可以砍掉大半。我曾在项目里把内核从默认的8MB压缩到2.3MB,启动时间从45秒降到12秒。嗯,这里要注意:裁剪过头也不行。我记得有一次把串口驱动给误删了,结果整批机器无法远程调试,最后只能派人去现场插键盘操作,那叫一个狼狈。

核心要点:嵌入式Linux的选型要关注实时性、内存占用和启动速度。轨道交通场景建议使用Preempt-RT内核补丁,确保交易处理的实时响应。

文件系统我推荐用SquashFS。只读的,防篡改。你想想,地铁站里人来人往,万一有人通过USB口注入恶意程序呢?只读文件系统至少能保证系统文件不会被改。当然,日志和配置数据要放在可写的分区上,用JFFS2或者UBIFS都行。

3.2 应用层软件——机器的「大脑」

应用层软件,说白了就是控制售货机怎么卖货的程序。我见过很多团队用C++写,我个人更倾向用C配合Python脚本。为什么?C处理底层硬件控制,Python处理业务逻辑,分工明确。

应用层通常分这么几个模块:

  • 交易引擎:处理支付、找零、出货的完整流程。这是核心中的核心。
  • 状态监控:实时采集温度、湿度、门锁状态、货道存货量等数据。
  • UI交互:触摸屏上的界面程序,负责展示商品、引导用户操作。
  • 日志管理:记录每一笔交易、每一次故障,方便事后追溯。

我曾经遇到过一个经典问题:交易引擎在处理支付回调时,没有做超时保护。结果有一次网络延迟,支付平台5秒后才返回结果,机器以为支付失败,直接取消了订单。用户钱扣了,货没出。那一次赔了不少钱。后来我在交易引擎里加了个看门狗定时器,超过3秒没响应就自动重试,这才彻底解决。

我的经验:应用层软件一定要做状态机设计。把「待支付」、「支付中」、「出货中」、「完成」这些状态画清楚,每个状态的转换条件写明白。别偷懒,画图比写代码更重要。

3.3 通信协议栈——机器的「神经」

通信协议栈,这是最容易出问题的地方。轨道交通售货机要跟支付平台、远程管理平台、甚至地铁的票务系统打交道。协议五花八门,有HTTP、MQTT、WebSocket,还有自定义的二进制协议。

我建议统一用MQTT作为主通信协议。为什么?轻量、支持QoS、支持断线重连。你想想,地铁隧道里信号时好时坏,TCP连接动不动就断。MQTT的遗嘱消息和保留消息机制,能让你知道机器是正常离线还是异常掉线。

这里给个简单的MQTT通信示例:

// 伪代码:售货机心跳上报
void heartbeat_report() {
    char topic[64];
    sprintf(topic, "vending/%s/status", device_id);
    
    json_t *root = json_object();
    json_object_set_new(root, "temp", json_real(25.3));
    json_object_set_new(root, "door", json_string("closed"));
    json_object_set_new(root, "stock", json_integer(128));
    
    mqtt_publish(topic, json_dumps(root), QOS_1);
}

通信协议栈里还有个容易忽略的点:数据压缩。轨道交通的4G信号有时候带宽很低,尤其是高峰期。我习惯在应用层做一层Gzip压缩,心跳包从2KB压缩到400字节左右,一个月下来能省不少流量费。

注意:千万别用明文传输交易数据。我见过有厂商直接用HTTP GET传卡号和密码,那简直是给黑客送大礼。至少要用TLS加密,支付数据还要额外做签名校验。

3.4 远程管理平台——机器的「指挥中心」

远程管理平台,说白了就是你在办公室里就能管全城几百台机器。这个平台通常部署在云服务器上,用Web界面展示。

平台的核心功能包括:

功能模块 说明 我的建议
设备管理 注册、分组、固件升级 用OTA差分升级,别整包推送
实时监控 在线状态、故障告警 告警阈值要可配置,别写死
交易统计 销售额、热销商品、库存预警 数据要支持按小时/天/月聚合
远程运维 远程重启、日志下载、参数调整 操作要留审计日志,谁动了什么一清二楚

远程管理平台和售货机之间的通信,我建议采用「心跳+事件上报」的模式。机器每隔30秒发一次心跳,告诉平台「我还活着」。有异常事件(比如门被打开、温度过高)就立即上报。平台收到事件后,可以主动下发指令。

我曾经遇到过一个问题:某次平台升级后,心跳超时时间从90秒改成了60秒,结果有批老机器网络不稳定,经常被误判为离线。运维人员大半夜被叫起来去现场检查,结果发现机器好好的。从那以后,我坚持所有超时参数都要可配置,并且要兼容旧版本。

总结一下:软件架构这四个层次,缺一不可。嵌入式Linux提供稳定底座,应用层软件处理业务逻辑,通信协议栈保证数据畅通,远程管理平台实现集中管控。任何一个环节出问题,都会影响整台机器的运营。

嗯,今天就聊到这儿。下一章咱们会深入讲讲通信协议栈的具体实现,包括MQTT的QoS等级怎么选、心跳间隔怎么调、断线重连的策略怎么写。到时候我会拿几个真实案例出来,保证让你少走弯路。