当前位置:首页 > 汽车电子 > 汽车电子
[导读]OTA升级最怕两件事:屏上进度条在跑,实际刷写早断了;或者弹窗显示“升级中”,用户还能点进设置把升级取消。车机HMI不是自己去轮询ECU,也不是升级线程里直接lv_label_set_text(),而是订阅OTA控制组件的状态事件,屏幕只做渲染。


OTA升级最怕两件事:屏上进度条在跑,实际刷写早断了;或者弹窗显示“升级中”,用户还能点进设置把升级取消。车机HMI不是自己去轮询ECU,也不是升级线程里直接lv_label_set_text(),而是订阅OTA控制组件的状态事件,屏幕只做渲染。

一、状态机是唯一真相源

所有显示内容都从状态机出,别让UI自己推导“现在到哪一步”:

typedef enum {

   OTA_IDLE,

   OTA_QUERYING,

   OTA_DOWNLOADING,

   OTA_VERIFYING,

   OTA_INSTALLING,

   OTA_REBOOTING,

   OTA_FAILED,

   OTA_ROLLBACK,

   OTA_DONE

} ota_state_t;


typedef struct {

   ota_state_t state;

   uint8_t prog;          // 0~100

   uint32_t ecu_idx;      // 当前刷写ECU序号

   uint32_t ecu_total;

   int err_code;

   uint64_t ts_ms;

} ota_status_t;

座舱域控里的OTA Manager维护这份状态,HMI只subscribe事件组,收到event再刷界面。

二、HMI订阅,不主动轮询

SOME/IP或DDS事件组典型写法:

void hmi_subscribe_ota(void){

   someip_subscribe(EVENT_GROUP_OTA, EVT_OTA_STATUS, on_ota_status);

   someip_subscribe(EVENT_GROUP_OTA, EVT_OTA_PROGRESS, on_ota_progress);

}


void on_ota_status(const ota_status_t*s){

   switch(s->state){

   case OTA_DOWNLOADING: show_page(PAGE_DOWNLOAD); break;

   case OTA_INSTALLING:  show_page(PAGE_INSTALL); lock_ui(); break;

   case OTA_FAILED:      show_page(PAGE_FAIL); break;

   case OTA_ROLLBACK:    show_rollback_tip(); break;

   case OTA_DONE:        show_page(PAGE_DONE); unlock_ui(); break;

   }

}

进度条单独走EVT_OTA_PROGRESS,别把百分比塞进状态事件里刷屏总线。

三、进度来自ECU上报,不是UI计时

进度百分比必须由目标ECU或OTA Master真实上报,HMI不允许用定时器假跑:

void on_ota_progress(uint8_t p, uint32_t idx, uint32_t total){

   set_progress_bar(p);

   set_sub_text("ECU %u/%u", idx, total);

}

工程规矩:

下载进度按字节/分块算,安装进度按ECU序号算

20秒没收到进度上报→标记通信异常

进度只增不减,回退一律按异常

多ECU串行升级:主进度=已完ECU数/总数,子进度=当前ECU内部%

四、刷写阶段锁交互

进入Installing后屏幕可以显示“请勿断电”,但交互要锁:

void lock_ui(void){

   block_touch();

   disable_menu_entry("软件更新");

   disable_power_off_btn();

   keep_screen_on(1);

}

条件不满足别进安装:P挡、电量阈值、无活跃故障码、车速为0,前置检查失败回Idle并报原因。

五、异常与回滚提示

失败不是弹个“ERROR”完事,要分原因:

下载断链→“网络中断,已断点续传”

校验失败→“升级包不完整,已停止”

刷写超时→“ECU无响应”

新版本启动自检失败→切A/B老分区,提示“已回滚至上一版本”

void on_ota_failed(int code){

   unlock_ui();

   switch(code){

   case ERR_VERIFY:  show_tip("校验失败,升级终止"); break;

   case ERR_TIMEOUT: show_tip("ECU响应超时"); break;

   case ERR_ROLLBACK:show_tip("新版本异常,已回滚"); break;

   }

}

双分区机制下重启切回旧Bank,HMI别在重启瞬间写“升级成功”,等新版本提交确认后再结单。

六、落坑清单

升级线程直接改UI控件→线程跨界卡顿

HMI自己按时间估进度→实际刷写断了条还跑

Installing不锁菜单→用户点取消把ECU置中间态

进度事件不带ecu_idx→多ECU界面看不出卡哪

断电重启不读持久化状态→界面回到Idle谎报

失败统一显示“错误”→现场查不出原因

重启瞬间弹成功→回滚后界面打脸

20s无进度不上报异常→卡死不回收

下载阶段允许熄火→包写一半变砖

手机APP和车机各问各的→两端进度不一致

七、落地顺序

OTA Manager维护状态机,进度由ECU上报

HMI只订阅状态事件+进度事件,不轮询

下载/安装/重启分三套页面模板

Installing锁触摸、禁关机、禁进设置

进度条按ECU序号+内部百分比两段拼

通信超时、校验失败、回滚各有独立文案

双分区切换后等提交确认再显示成功

车机HMI与手机APP同绑一个状态源

OTA显示联动的本质是“屏幕不拥有状态,只拥有渲染”:升级逻辑在OTA Manager,进度来自ECU上报,HMI通过事件订阅把状态翻译成页面。写UI的人千万别顺手在按键回调里调刷写接口,也别用定时器冒充进度——前者会把ECU拖进未知态,后者会让用户以为升级正常其实早断了。真出问题时,屏上那行提示能不能说清“断网/校验/回滚”哪一类,往往决定售后十分钟还是十小时。



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