新闻| 论坛| 博客| 在线研讨会
分享一个OTA升级相关的应用实践!(2)
鱼鹰谈单片机| 2023-04-23 19:26:09 阅读:277 发布文章

各升级情况的统一处理如:

左右滑动查看全部代码>>>

staticota_update_case_e s_ota_update_case = UPDATE_SELECTED_NULL;// 升级情况
staticota_update_case_e s_not_yet_update_case = UPDATE_SELECTED_NULL;// 还未升级的情况

// 启动固件安装
voidstart_firmware_install(void)
{
app_install_result_tinstall_board2_result = {0};
app_install_result_tinstall_board3_result = {0};

memset(&s_install_info,0,sizeof(app_install_info_t));
send_install_info_to_app(&s_install_info);
memset(&install_board2_result,0,sizeof(app_install_result_t));
memset(&install_board3_result,0,sizeof(app_install_result_t));
send_board2_install_result_to_app(&install_board2_result);
send_board3_install_result_to_app(&install_board3_result);

s_ota_update_case = get_ota_update_case();
s_install_info.install_case = s_ota_update_case;

switch(s_ota_update_case)
{
// 固件包相同,不升级
caseUPDATE_NON_DEV:
{
LOG_D("UPDATE_INSTALL_SUCCESS --- UPDATE_NON_DEV");

s_install_info.total_install_status = UPDATE_INSTALL_SUCCESS;
send_install_info_to_app(&s_install_info);
storage_write_file(APP_OTA_INSTALL_RESULT_FILE, &s_install_info.total_install_status,sizeof(install_status_e));
break;
}
// 只升级board1设备
caseUPDATE_BOARD1_DEV:
{
LOG_D("UPDATE_BOARD1_DEV");
// 保存新的md5值
md5sum_tcalc_board1_img_md5 = {0};
read_ota_md5_list_from_file(&s_flash_ota_file_md5_list,sizeof(s_flash_ota_file_md5_list));
calc_file_md5(OTA_BOARD1_DEV_IMG_FILE, &calc_board1_img_md5);
memcpy(s_flash_ota_file_md5_list[OTA_IMG_INDEX_BOARD1_DEV].md5, &calc_board1_img_md5,sizeof(md5sum_t));
write_ota_md5_list_to_file(&s_flash_ota_file_md5_list,sizeof(s_flash_ota_file_md5_list));

start_board1_ota_install();
break;
}
// 只升级board2设备
caseUPDATE_BOARD2_DEV:
{
LOG_D("UPDATE_BOARD2_DEV");
start_board2_ota_install();
s_not_yet_update_case = UPDATE_BOARD2_DEV;
break;
}
// 只升级board3设备
caseUPDATE_BOARD3_DEV:
{
LOG_D("UPDATE_BOARD3_DEV");
start_board3_ota_install();
s_not_yet_update_case = UPDATE_BOARD3_DEV;
break;
}
// 升级board1与board2设备
caseUPDATE_BOARD1_AND_BOARD2_DEV:
{
LOG_D("UPDATE_BOARD1_AND_BOARD2_DEV");
start_board2_ota_install();
s_not_yet_update_case = UPDATE_BOARD1_AND_BOARD2_DEV;
break;
}
// 升级board1与board3设备
caseUPDATE_BOARD1_AND_BOARD3_DEV:
{
LOG_D("UPDATE_BOARD1_AND_BOARD3_DEV");
start_board3_ota_install();
s_not_yet_update_case = UPDATE_BOARD1_AND_BOARD3_DEV;
break;
}
// 升级board2设备与board3设备
caseUPDATE_BOARD2_AND_BOARD3_DEV:
{
LOG_D("UPDATE_BOARD2_AND_BOARD3_DEV");
start_board2_ota_install();
start_board3_ota_install();
s_not_yet_update_case = UPDATE_BOARD2_AND_BOARD3_DEV;
break;
}
// 升级所有设备
caseUPDATE_ALL_DEV:
{
LOG_D("UPDATE_ALL_DEV");
start_board2_ota_install();
start_board3_ota_install();
s_not_yet_update_case = UPDATE_ALL_DEV;
break;
}
default:
break;
}
}
4、安装进度只有一个,如何处理三块板子的安装进度?

手机APP上并不会去区分各个板子的安装进度,即安装进度只有一个。因为用户并不会关注设备里有几块板子的固件在安装。所以这个安装进度需要表明以上各种情况的安装。

需要明确的是:

  • 安装进度总是以board2、board3中的较大固件为主。

  • 安装某个板子异常则表明这个安装过程算是失败。为了防止这类情况:假如需要升级board1与board2,正好本次更新是增加了之间的一些协议数据,如果单单升级成功其中一块,另一块没升级成功,这种情况下也要去使用的话,就有可能会出现问题,协议数据对不上,轻则某些数据错误,程序中防错机制设计得不好的话重则可能程序会崩溃。

  • 虽然board2与board3的安装进度不直接显示在手机APP上,但无论是给手机APP做逻辑使用还是供我们调试实用,都有必要创建他们各自的属性数据。比如会往云端上报各种情况的board2与board3的安装信息属性数据,如:

typedefstructapp_install_result
{

uint8_tinstall_status;// 安装状态
uint8_tinstall_progress;// 安装进度
}app_install_result_t;

app_install_result_tinstall_board2_result = {0};
app_install_result_tinstall_board3_result = {0};
send_board2_install_result_to_app(&install_board2_result);
send_board3_install_result_to_app(&install_board3_result);
5、安装结束的检测?

安装过程包含如下几种情况,挨个进行处理即可:

图片

对应代码如(注:以下为了方便说明全都写在一块,实际中可以进行拆分):

// 检测是否升级结束
voidcheck_whether_update_end(void)
{
app_install_result_tinstall_board2_result = {0};
app_install_result_tinstall_board3_result = {0};

// 包含board1的升级情况(board1+board2、board1+board3、board1+board2+board3)。board1最后安装
if(UPDATE_BOARD1_AND_BOARD2_DEV == s_ota_update_case ||
UPDATE_BOARD1_AND_BOARD3_DEV == s_ota_update_case ||
UPDATE_ALL_DEV == s_ota_update_case)
{
// 正常安装且剩下board1没安装了,开始安装board1
if(UPDATE_BOARD1_DEV == s_not_yet_update_case)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 记录新的版本号
// 2. 保存新的md5值至本地文件
// 3.重启之前上报安装成功给手机APP
// 4.重启进行安装board1
}
// 升级安装失败
else
{
// 只升级board1与board2的情况
if(UPDATE_BOARD1_AND_BOARD2_DEV == s_ota_update_case && UPDATE_BOARD1_AND_BOARD2_DEV == s_not_yet_update_case)
{
if(UPDATE_STATUS_BOARD2_DATA_ACK_ERR == s_board2_update_status)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board2安装失败
// 2. board2安装失败 -> 上报总的安装失败
}
}
// 只升级board1与board3的情况
elseif(UPDATE_BOARD1_AND_BOARD3_DEV == s_ota_update_case && UPDATE_BOARD1_AND_BOARD3_DEV == s_not_yet_update_case)
{
if(UPDATE_STATUS_BOARD3_DATA_ACK_ERR == s_board3_update_status)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board3安装失败
// 2. board3安装失败 -> 上报总的安装失败
}
}
// 升级全部设备
else
{
// board2安装失败,board3安装成功
if(UPDATE_STATUS_BOARD2_DATA_ACK_ERR == s_board2_update_status &&
UPDATE_STATUS_BOARD3_DATA_FINISH_ACK_OK == s_board3_update_status)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board2安装失败
// 2. 上报board3安装成功
// 3. board2安装失败 -> 上报总的安装失败
}

// board2安装成功,board3安装失败
if(UPDATE_STATUS_BOARD2_DATA_FINISH_ACK_OK == s_board2_update_status && UPDATE_STATUS_BOARD3_DATA_ACK_ERR == s_board3_update_status)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board2安装成功
// 2. 上报board3安装失败
// 3. board3安装失败 -> 上报总的安装失败
}

// board2与board3都安装失败
if(UPDATE_STATUS_BOARD2_DATA_ACK_ERR == s_board2_update_status && UPDATE_STATUS_BOARD3_DATA_ACK_ERR == s_board3_update_status)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board2安装失败
// 2. 上报board3安装失败
// 3. board2、board3安装失败 -> 上报总的安装失败
}
}
}
}

// 只升级board2及board3的情况。如果数据都已经传输数据完成,则上报安装完成
if(UPDATE_BOARD2_AND_BOARD3_DEV == s_ota_update_case)
{
// 升级安装成功
if(UPDATE_NON_DEV == s_not_yet_update_case)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board2安装成功
// 2. 上报board3安装成功
// 3. board2、board3安装成功 -> 上报总的安装成功
}
// 升级安装失败
else
{
// board2安装失败,board3安装成功
if(UPDATE_STATUS_BOARD2_DATA_ACK_ERR == s_board2_update_status && UPDATE_STATUS_BOARD3_DATA_FINISH_ACK_OK == s_board3_update_status)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board2安装失败
// 2. 上报board3安装成功
// 3. board2安装失败 -> 上报总的安装失败
}

// board2安装成功,board3安装失败
if(UPDATE_STATUS_BOARD2_DATA_FINISH_ACK_OK == s_board2_update_status && UPDATE_STATUS_BOARD3_DATA_ACK_ERR == s_board3_update_status)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board2安装成功
// 2. 上报board3安装失败
// 3. board3安装失败 -> 上报总的安装失败
}

// board2与board3都安装失败
if(UPDATE_STATUS_BOARD2_DATA_ACK_ERR == s_board2_update_status && UPDATE_STATUS_BOARD3_DATA_ACK_ERR == s_board3_update_status)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board2安装失败
// 2. 上报board3安装失败
// 3. board2、board3安装失败 -> 上报总的安装失败
}
}
}

// 只升级board2的情况
if(UPDATE_BOARD2_DEV == s_ota_update_case)
{
if(UPDATE_NON_DEV == s_not_yet_update_case)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board2安装成功
// 2. board2安装成功 -> 上报总的安装成功
}
else
{
if(UPDATE_STATUS_BOARD2_DATA_ACK_ERR == s_board2_update_status)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board2安装失败
// 2. board2安装失败 -> 上报总的安装失败
}
}
}

// 只升级board3的情况
if(UPDATE_BOARD3_DEV == s_ota_update_case)
{
if(UPDATE_NON_DEV == s_not_yet_update_case)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board3安装成功
// 2. board3安装成功 -> 上报总的安装成功
}
else
{
if(UPDATE_STATUS_BOARD3_DATA_ACK_ERR == s_board3_update_status)
{
s_ota_update_case = UPDATE_SELECTED_NULL;
s_not_yet_update_case = UPDATE_SELECTED_NULL;
// 1. 上报board3安装失败
// 2. board3安装失败 -> 上报总的安装失败
}
}
}
}

前面我们的升级情况进行加法的组合,比如:

升级所有设备 = BOARD1 + BOARD2 + BOARD3 =1+2+4

那么,我们每安装完一个设备,可以减掉对应的值,这样可以区分当前的安装处于哪个阶段。

以上就是本次的分享,大家还有什么其它思路吗?


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客