当前位置:首页 > 汽车电子 > 汽车电子
[导读]T-BOX不是“收到CAN就发MQTT”这么简单。车辆进隧道、过地库、基站切换都会断链,裸发必然丢数据。稳定上报的核心是四层:4G链路可恢复、采集与发送解耦、弱网本地缓存、上线按序补传。


T-BOX不是“收到CAN就发MQTT”这么简单。车辆进隧道、过地库、基站切换都会断链,裸发必然丢数据。稳定上报的核心是四层:4G链路可恢复、采集与发送解耦、弱网本地缓存、上线按序补传。

一、4G模组联网:先查状态再发数据

Linux下4G模组通常出ttyUSB做AT口,PPP或ECM模式出网卡。上报前别直接socket,先探网络附着:

send_at("AT+CPIN?");     // SIM就绪

send_at("AT+CSQ");       // 信号强度

send_at("AT+CGATT?");    // PDP附着,返回1才继续

老方案走PPP:AT+CGDCONT=1,"IP","CMNET" → ATD*99# → pppd起ppp0。

资源够的域控直接用ECM/QMI网卡模式(usb0/wwan0),少一层PPP封装、延迟更低。

应用层只认网卡名,不关心底层是PPP还是ECM。

联网状态用Netlink监听IFF_UP+默认路由变化,别靠定时ping外网——ping本身也吃流量。

二、采集与上报解耦:环形队列

CAN数据别在接收中断里直接发。正确是采集中断只拷缓冲,独立上报任务从队列取:

typedef struct { uint32_t seq; uint64_t ts; uint8_t payload[64]; } telem_frame_t;

ringbuf_t g_tx_q;          // 内存环形队列

void can_rx_isr(frame_t*f){

   telem_frame_t fr={ .seq=g_seq++, .ts=now_ms() };

   pack_vehicle_data(f,&fr.payload);

   ring_push(&g_tx_q,&fr);          // 只拷贝,不阻塞

}

周期聚合很关键:500k CAN一秒上千帧,全量上报既占带宽也没意义。车速/电量/位置按1~10s周期取,事件类(碰撞、DTC、解闭锁)走变化触发。

三、MQTT弱网参数

车载场景别用QoS2,握手重、 broker压力大;遥测用QoS0或QoS1,告警/控制回执用QoS1即可。

mqtt_opts.keepalive = 60;           // 弱网可缩到30

mqtt_opts.clean_session = 0;        // 离线消息不丢

mqtt_opts.qos = 1;

mqtt_set_lwt(client,"dev/{vin}/status","offline",1);

心跳按蜂窝网络调,别全车统一秒级心跳;重连加指数退避+随机抖动,避免基站恢复瞬间所有车同时重连把核心网打爆。

发送伪代码:

void report_task(void){

   telem_frame_t fr;

   while(ring_pop(&g_tx_q,&fr)){

       if(net_ready() && mqtt_publish(TOPIC,&fr,QOS1))

           ack_seq(fr.seq);

       else

           ring_push_front(&g_tx_q,&fr);   // 回队首,下次重发

           break;

   }

}

四、断点缓存:内存队列出列,Flash兜底

网络断了还在继续跑,内存队列会爆。策略分两级:

短时抖动(几秒):内存ring缓冲

长断网(隧道/地库):落SPI NOR或eMMC文件队列

int push_cloud(telem_frame_t*fr){

   if(mqtt_publish(TOPIC,fr,QOS1)==OK){

       mark_ack(fr->seq); return 0;

   }

   if(net_down())

       flash_queue_append(fr);     // 持久化

   return -1;

}

Flash写按块追加,带seq+时间戳;存满按时间覆盖老数据,别无限增长。

关键帧(最近30秒黑匣子数据)单独锁存区,事故触发后优先保。

五、恢复补传与去重

网络恢复后别把实时数据卡住等补传,间隙穿插发:

void on_net_recovered(void){

   flash_seek_head();

   telem_frame_t fr;

   while(flash_queue_pop(&fr)){

       if(seq_already_ack(fr.seq)) continue;   // 云端可能已收到

       if(mqtt_publish(TOPIC,&fr,QOS1)!=OK) break;

       flash_queue_drop_one();

   }

}

云端按vin+seq去重,QoS1重复投递不产生脏数据。

补传频率1Hz左右,别上来就全量灌,避免把当前实时链路也挤掉。

六、车规落坑

只看socket可写≠云端收到,必须等PUBACK

clean_session=1断线重连丢离线消息

不落盘缓存,长隧道数据全丢

补传不分优先级,历史数据压过实时告警

时钟不准,补传数据服务端对不上时间轴

AT口和数传口共用串口,发AT卡住上报线程

心跳太频,偏远地区反而更易掉线

Flash无磨损策略,车规eMMC写穿

按“AT探网→采集入队→MQTT QoS1发→失败落Flash→恢复按seq补传→云端去重”落地,T-BOX在4G弱网下能做到数据不丢、重连自恢复、事故段可溯源。稳定上报不是带宽问题,是断链状态机和本地缓存设计问题——链路层只管连通,可靠性得在应用层自己补。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭