#include "ota.h" #include "../network_mgr/sx1268/peripherals/radio/radio.h" #include "../storage/AT24C128Opt.h" #if 0 typedef struct _ota_retransmit_resp {//重传响应, 同ota_continues_info_t } ota_retransmit_resp_t; #endif uint8_t ota_continuous_end_flag = 0; uint8_t updata_state = 0; uint16_t updata_state_save = 0; uint8_t cad_ch_activitydetected = 0; timeout_t ota_retransmit_delay; timeout_t ota_total_timer; uint8_t ota_total_timer_start = 0; device_fixed_info_t device_fixed_info; ota_pkg_info_t ota_info; updata_state_t updata_state_info; #define OTA_START_INFO_LEN sizeof(ota_start_info_t) #define OTA_CONTINUES_INFO_LEN sizeof(ota_continues_info_t) #define OTA_RETRNSMIT_INFO_LEN sizeof(ota_retransmit_req_t) #define OTA_UPDATE_PAYLAOA_LEN 128 typedef void (*timeout_cb)(void *p_tmr, void *p_arg); extern void lora_gw_ota_timeout(void *p_tmr, void *p_arg); extern volatile uint32_t TickCounter; void lora_timer_one_shot(system_network_t *p_sys_net, uint8_t timeout, timeout_cb cb) { OS_ERR err; OSTmrCreate(&ota_info.ota_tmr, "ota_timer", timeout, timeout, OS_OPT_TMR_ONE_SHOT, cb, p_sys_net, &err); OSTmrStart(&ota_info.ota_tmr, &err); } void lora_gw_ota_start(system_network_t *p_sys_net) { uint16_t crc = 0, p_crc = 0,len = 0; gateway_collect_com_t msg; ota_start_info_t *p_ota = (ota_start_info_t *)msg.taxinfo.info; p_ota->des_device_type = ota_info.des_device_type; p_ota->des_device_id = ota_info.des_device_id; p_ota->rcv_device_id = ota_info.rcv_device_id; p_ota->rcv_device_type = ota_info.rcv_device_type; p_ota->update_version = ota_info.update_version; p_ota->update_version = ota_info.update_version; p_ota->total_bytes = ota_info.total_bytes; p_ota->time = UPDATE_EACH_TIME; collect_msg_frame_fill(&msg, net_msg_type_update_start, OTA_START_INFO_LEN+2); //len = GATE_COLL_HEAD_LEN + OTA_START_INFO_LEN; crc = _crc16_get((uint8_t *)&msg,msg.len + GATE_COLL_HEAD_LEN -2 ); msg.taxinfo.info[msg.len -2] = crc&0xff; msg.taxinfo.info[msg.len - 1] = (crc>>8)&0xff; data_dump("send start updata", (uint8_t *)&msg, msg.len + 12); p_sys_net->downlink_send((char *)&msg, GATE_COLL_HEAD_LEN + msg.len); p_sys_net->workstate = DEV_WORK_STATE_UPDATING; } void lora_gw_ota_continues(system_network_t *p_sys_net,uint32_t address) { gateway_collect_com_t msg; ota_continues_info_t *p_ota = (ota_continues_info_t *)msg.taxinfo.info; OS_ERR err; uint32_t timer = 0; uint16_t crc = 0; char buff[256] = {0}; uint16_t i=0; printf("lora_gw_ota_continues\r\n"); p_ota->total_pkgs = ota_info.total_pkgs; p_ota->sub_pkg_len = OTA_UPDATE_PAYLAOA_LEN; p_ota->des_device_type = ota_info.des_device_type; p_ota->des_device_id = ota_info.des_device_id; p_ota->rcv_device_id = ota_info.rcv_device_id; p_ota->rcv_device_type = ota_info.rcv_device_type; timer = RadioTimeOnAir2(MODEM_LORA,140); timer = (timer>UPDATE_EACH_TIME) ? timer : UPDATE_EACH_TIME; printf("timer = %d\r\n", timer); printf("lora_update total_pkgs = %d\r\n",ota_info.total_pkgs); while(ota_info.sub_pkg_id <= ota_info.total_pkgs) { printf("lora_gw_ota_continues %d\r\n", ota_info.sub_pkg_id); p_ota->sub_pkg_id = ota_info.sub_pkg_id++; Flash_BufferRead(address + (p_ota->sub_pkg_id - 1)*OTA_UPDATE_PAYLAOA_LEN, ((uint8_t *)p_ota) + OTA_CONTINUES_INFO_LEN, OTA_UPDATE_PAYLAOA_LEN); collect_msg_frame_fill(&msg, net_msg_type_update_continues, OTA_CONTINUES_INFO_LEN + OTA_UPDATE_PAYLAOA_LEN+2); crc = _crc16_get((uint8_t *)&msg,msg.len-2+GATE_COLL_HEAD_LEN); msg.taxinfo.info[msg.len-2] = crc&0xff; msg.taxinfo.info[msg.len-1] = (crc>>8)&0xff; // memcpy(buff,(char*)&msg,msg.len + GATE_COLL_HEAD_LEN); memcpy(buff,(char*)&(msg.taxinfo.info[OTA_CONTINUES_INFO_LEN]),128); for(i=0;i< msg.len +GATE_COLL_HEAD_LEN;i++){ printf("%02x ",buff[i]); } printf("\r\n"); p_sys_net->downlink_send((char *)&msg, GATE_COLL_HEAD_LEN + msg.len); set_led_update_status(ota_info.total_pkgs - ota_info.sub_pkg_id); OSTimeDlyHMSM(0, 0, 0, timer, OS_OPT_TIME_DLY, &err); } p_sys_net->workstate = DEV_WORK_STATE_UPDATE_RETRANSMIT; lora_timer_one_shot(p_sys_net, 60, lora_gw_ota_timeout); } void lora_gw_ota_retransmit_resp(system_network_t *p_sys_net, ota_retransmit_req_t *p_req,uint32_t address) { char buff[256] = {0}; uint16_t i=0; uint16_t crc = 0; gateway_collect_com_t msg; ota_continues_info_t *p_ota = (ota_continues_info_t *)msg.taxinfo.info; p_ota->total_pkgs = ota_info.total_pkgs; p_ota->sub_pkg_id = p_req->repeat_sub_pkg_id; p_ota->sub_pkg_len = OTA_UPDATE_PAYLAOA_LEN; p_ota->des_device_type =ota_info.des_device_type; p_ota->des_device_id = ota_info.des_device_id; p_ota->rcv_device_id = ota_info.rcv_device_id; p_ota->rcv_device_type = ota_info.rcv_device_type; Flash_BufferRead(address + (p_req->repeat_sub_pkg_id - 1)*OTA_UPDATE_PAYLAOA_LEN, ((uint8_t *)p_ota) + OTA_CONTINUES_INFO_LEN, OTA_UPDATE_PAYLAOA_LEN); collect_msg_frame_fill(&msg, net_msg_type_update_retransmit_rsp, OTA_CONTINUES_INFO_LEN + OTA_UPDATE_PAYLAOA_LEN + 2); crc = _crc16_get((uint8_t *)&msg,msg.len-2+GATE_COLL_HEAD_LEN); msg.taxinfo.info[msg.len-2] = crc&0xff; msg.taxinfo.info[msg.len-1] = (crc>>8)&0xff; memcpy(buff,(char*)&msg,msg.len + GATE_COLL_HEAD_LEN); // memcpy(buff,(char*)&(msg.taxinfo.info[OTA_CONTINUES_INFO_LEN]),128); for(i=0;i< msg.len +GATE_COLL_HEAD_LEN;i++){ printf("%02x ",buff[i]); } printf("\r\n"); p_sys_net->downlink_send((char *)&msg, GATE_COLL_HEAD_LEN + msg.len); // p_sys_net->downlink_send((char *)&msg, GATE_COLL_HEAD_LEN + OTA_CONTINUES_INFO_LEN + OTA_UPDATE_PAYLAOA_LEN); } void lora_gw_ota_timeout(void *p_tmr, void *p_arg) { OS_ERR err; system_network_t *p_sys_net = (system_network_t *)p_arg; switch(p_sys_net->workstate) { case DEV_WORK_STATE_NORMAL: break; case DEV_WORK_STATE_UPDATING: break; case DEV_WORK_STATE_UPDATE_RETRANSMIT: p_sys_net->workstate = DEV_WORK_STATE_NORMAL; break; case DEV_WORK_STATE_ONLOOKER: p_sys_net->workstate = DEV_WORK_STATE_NORMAL; break; default: break; } } int lora_gw_ota_info_Init(update_msg_format *p_update, uint32_t total_len, uint32_t total_crc) { memset(&ota_info, 0, sizeof(ota_pkg_info_t)); ota_info.des_device_type = p_update->des_device_type; ota_info.des_device_id= p_update->des_device_id; ota_info.rcv_device_id = p_update->rcv_device_id; ota_info.rcv_device_type = p_update->rcv_device_type; //ota_info.update_type = p_update->update_type; ota_info.update_version = p_update->update_version; ota_info.total_bytes = total_len; ota_info.total_crc = total_crc; ota_info.total_pkgs = total_len/OTA_UPDATE_PAYLAOA_LEN; ota_info.lastRightPkgNum = 1; if(total_len%OTA_UPDATE_PAYLAOA_LEN) { ota_info.total_pkgs += 1; } ota_info.sub_pkg_id = 1; return 0; } int lora_node_ota_info_Init(ota_start_info_t *p_ota) { memset(&ota_info, 0, sizeof(ota_pkg_info_t)); ota_info.rcv_device_type = p_ota->rcv_device_type; ota_info.rcv_device_id = p_ota->rcv_device_id; ota_info.des_device_type = p_ota->des_device_type; ota_info.des_device_id = p_ota->des_device_id; ota_info.update_version = p_ota->update_version; ota_info.total_bytes = p_ota->total_bytes; ota_info.total_pkgs = p_ota->total_bytes/OTA_UPDATE_PAYLAOA_LEN; ota_info.lossPkgIndex = 0; ota_info.lastRightPkgNum = 1; if(p_ota->total_bytes%OTA_UPDATE_PAYLAOA_LEN) { ota_info.total_pkgs += 1; } ota_info.lossPkgCounter = 0; ota_info.sub_pkg_id = 1; ota_info.Send_interval = p_ota->time; return 0; } void lora_gw_ota_proc(system_network_t *p_sys_net, gateway_collect_com_t *p_msg) { ota_retransmit_req_t *p_req = NULL; uint32_t address = OTA_UPDATE_APP3_FLASH_START_ADDR; //if(p_sys_net->dev_type != DEV_TYPE_GATEWAY) { // return; //} p_req = (ota_retransmit_req_t *)p_msg->taxinfo.info; if(p_req->rcv_devict_type == 0x0201) address = OTA_UPDATE_APP3_FLASH_START_ADDR; else if(p_req->rcv_devict_type == 0x0301)address = OTA_UPDATE_APP1_FLASH_START_ADDR; printf("retransmit add = 0x%08x\r\n",address); switch(p_msg->type) { case net_msg_type_update_retransmit_req: set_led_update_status(p_req->repeat_sub_pkg_id); lora_gw_ota_retransmit_resp(p_sys_net, p_req,address); break; case net_msg_type_update_status: break; default: break; } } //旁观者定时器 void ota_timer_onlooker_one_shot(uint16_t timeout, timeout_cb cb) { OS_ERR err; OSTmrCreate(&ota_info.ota_onlooker_tmr, "ota_timer_onlooker", timeout, timeout, OS_OPT_TMR_ONE_SHOT, cb, NULL, &err); OSTmrStart(&ota_info.ota_onlooker_tmr, &err); //升级指示灯 //ota_start_led_init(); gch //Led_Single_State_Set(UPDATA_ONLOOKER_LED,LED_ON); gch //Data_last4bit_led(0xff,1); gch set_led_update_status(0); } void ota_timeout_onlooker(void *p_tmr, void *p_arg) { OS_ERR err; // if(device_info.alrd == DEVICE_ALRD)//已初始化 // { device_fixed_info.Work_State = DEV_WORK_STATE_NORMAL; // } // else // { // device_fixed_info.Work_State = DEV_WORK_STATE_UNINIT; // //未初始化时,将设备sn置为0xffffffff;设备类型是默认的 // device_info.device_id = 0xffffffff; // device_info.device_type = (SOFTWARE_VERSION_APP&0xffff0000)>>16; // } OSTmrStop(&ota_info.ota_continuous_tmr, OS_OPT_TMR_NONE, NULL, &err); OSTmrStop(&ota_info.ota_retransmit_tmr, OS_OPT_TMR_NONE, NULL, &err); ota_total_timer_start = 0;//关闭升级总定时器 printf("onlooker timeout \n"); g_runData.bUpdate = 0; g_updateProg.rec0x16 = 0x00; //升级指示灯 // LED_OFF_ALL(); // Data_lastNbit_led(SOFTWARE_VERSION_APP,2,1);//APP版本后2位常亮 } /* 重传定时器 */ void ota_timer_retransmit_one_shot(uint16_t timeout, timeout_cb cb) { OS_ERR err; OSTmrCreate(&ota_info.ota_retransmit_tmr, "ota_timer_retransmit", timeout, timeout, OS_OPT_TMR_ONE_SHOT, cb, NULL, &err); OSTmrStart(&ota_info.ota_retransmit_tmr, &err); } void ota_timeout_retransmit(void *p_tmr, void *p_arg) { device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //′ò?a??1????¨ê±?÷ updata_state = RETRANSMIT_TIMEOUT; updata_state_save = set_updata_state(updata_state); BKP_WriteBackupRegister(BKP_DR3, updata_state_save); printf("retransmit timeout \n"); } //连续接收定时器 void ota_timer_continuous_one_shot(uint16_t timeout, timeout_cb cb) { OS_ERR err; OSTmrCreate(&ota_info.ota_continuous_tmr, "ota_timer_continuous", timeout, timeout, OS_OPT_TMR_ONE_SHOT, cb, NULL, &err); OSTmrStart(&ota_info.ota_continuous_tmr, &err); } void ota_timeout_continuous(void *p_tmr, void *p_arg) { uint16_t i; switch(device_fixed_info.Work_State) { case DEV_WORK_STATE_OTA_BEGIN: device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 updata_state = PACKET_LOSS_MORE; updata_state_save = set_updata_state(updata_state); BKP_WriteBackupRegister(BKP_DR3, updata_state_save); break; case DEV_WORK_STATE_OTA_CONTINUOUS: //更新收包相关状态 for(i = ota_info.lastRightPkgNum;i < ota_info.total_pkgs+1;i++) { ota_info.lossPkgCounter++; ota_info.lossPkgId[ota_info.lossPkgIndex++] = i;//+1因为子包编号从0开始, //丢包太多了,超过了MAX_LOSS_PKG_COUNT,结束本次升级。 if(ota_info.lossPkgCounter == MAX_LOSS_PKG_COUNT) {//降为旁观者, 放弃本次升级 device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 updata_state = PACKET_LOSS_MORE; updata_state_save = set_updata_state(updata_state); BKP_WriteBackupRegister(BKP_DR3, updata_state_save); return; } } if(ota_info.lossPkgCounter == 0) //没有丢包 { ota_continuous_end_flag = OTA_CONTINUOUS_DIRECT; device_fixed_info.Work_State = DEV_WORK_STATE_OTA_UPGRADE_RCV_END; printf("check begin\n"); } else //有丢包 { //进入连续接收完成任务处理函数 ota_continuous_end_flag = OTA_CONTINUOUS_DIRECT; device_fixed_info.Work_State = DEV_WORK_STATE_OTA_RETRANSMIT; ota_timer_retransmit_one_shot(RETRANSMIT_TIMEOUT_TIME,ota_timeout_retransmit); //打开重传定时器 printf("retransmit begin\n"); } break; default: break; } printf("continuous timeout \n"); } //总定时器 void ota_timer_total_one_shot(uint16_t timeout, timeout_cb cb) { OS_ERR err; OSTmrCreate(&ota_info.ota_total_tmr, "ota_timer_total", timeout, timeout, OS_OPT_TMR_ONE_SHOT, cb, NULL, &err); OSTmrStart(&ota_info.ota_total_tmr, &err); } void ota_timeout_total(void *p_tmr, void *p_arg) { OS_ERR err; // if(device_info.alrd == DEVICE_ALRD)//已初始化 // { // device_fixed_info.Work_State = DEV_WORK_STATE_NORMAL; // } // else { device_fixed_info.Work_State = DEV_WORK_STATE_UNINIT; //未初始化时,将设备sn置为0xffffffff;设备类型是默认的 // device_info.device_id = 0xffffffff; gch // device_info.device_type = (SOFTWARE_VERSION_APP&0xffff0000)>>16; gch } device_fixed_info.Work_State = DEV_WORK_STATE_NORMAL; OSTmrStop(&ota_info.ota_onlooker_tmr, OS_OPT_TMR_NONE, NULL, &err); OSTmrStop(&ota_info.ota_continuous_tmr, OS_OPT_TMR_NONE, NULL, &err); OSTmrStop(&ota_info.ota_retransmit_tmr, OS_OPT_TMR_NONE, NULL, &err); updata_state = UPDATA_TOTAL_TIMEOUT; updata_state_save = set_updata_state(updata_state); BKP_WriteBackupRegister(BKP_DR3, updata_state_save); g_runData.bUpdate = 0; printf("total timeout \n"); //升级指示灯 // LED_OFF_ALL(); // Data_lastNbit_led(SOFTWARE_VERSION_APP,2,1);//APP版本后2位常亮 } //升级重传函数 void ota_retransmit_req(uint16_t repeat_sub_pkg_id) { char *p_msg = NULL; gateway_collect_com_t msg; ota_retransmit_req_t *p_ota = (ota_retransmit_req_t *)msg.taxinfo.info; p_ota->rcv_devict_type = ota_info.rcv_device_type; p_ota->rcv_device_id = ota_info.rcv_device_id; p_ota->repeat_sub_pkg_id = repeat_sub_pkg_id; net_msg_frame_fill(&msg, net_msg_type_update_retransmit_req, OTA_RETRNSMIT_INFO_LEN); p_msg = (char *)lora_queue_mem_calloc_must(); if(p_msg) { memcpy(p_msg, (char *)&msg, FRAME_HEADER_LEN + OTA_RETRNSMIT_INFO_LEN+2); lora_queue_insert((char *)p_msg, FRAME_HEADER_LEN + OTA_RETRNSMIT_INFO_LEN+2); } else { lora_queue_mem_free(p_msg); } } uint16_t OTA_Continuous_Timeout = 0; //网关下发的升级命令分析 void gateway_lora_ota_proc(gateway_collect_com_t *p_msg) { OS_ERR err; uint32_t i; uint32_t remain_pkg = 0; ota_start_info_t *p_start = NULL; ota_continues_info_t *p_cont = NULL; g_runData.bUpdate = 1; if(device_fixed_info.Work_State == DEV_WORK_STATE_ONLOOKER)//旁观者模式 { printf("p_msg->type:%x\n",p_msg->type); OSTmrStop(&ota_info.ota_onlooker_tmr, OS_OPT_TMR_NONE, NULL, &err); ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 } else //非旁观者模式 { switch(p_msg->type) { case net_msg_type_update_start: //开始升级指令 g_runData.bUpdate = 1; p_start = (ota_start_info_t *)p_msg->taxinfo.info; printf("p_msg->type:%x, work_state=%d\n",p_msg->type,device_fixed_info.Work_State); /* 校验当前设备是否为接收对象 */ if(device_type_and_id_cmp(p_start->rcv_device_type, p_start->rcv_device_id)) { OSTmrStop(&ota_info.ota_continuous_tmr, OS_OPT_TMR_NONE, NULL, &err); //关闭连续接收定时器 if(device_fixed_info.Work_State == DEV_WORK_STATE_NORMAL || device_fixed_info.Work_State == DEV_WORK_STATE_UNINIT) { Flash_RangeErase(OTA_UPDATE_APP3_FLASH_START_ADDR, OTA_UPDATE_APP3_FLASH_SIZE); //擦除app3 //打开升级总定时器 ota_total_timer_start = 1; ota_total_timer.counter = TickCounter; ota_total_timer.timeout = OTA_TOTAL_TIMEOUT_TIME_TICK; printf("open total timer\n"); //收到升级指令 updata_state = START_UPDATA; updata_state_save = set_updata_state(updata_state); BKP_WriteBackupRegister(BKP_DR3, updata_state_save); //升级指示灯 // ota_start_led_init(); gch // Led_Single_State_Set(UPDATA_SLAVE_LED,LED_ON); gch } //本设备为接收对象 device_fixed_info.Work_State = DEV_WORK_STATE_OTA_BEGIN; lora_node_ota_info_Init(p_start); OTA_Continuous_Timeout = (ota_info.total_pkgs * ota_info.Send_interval)/1000 + CONTINUOUS_TIMEOUT_DELAY_TIME;//连续接收定时时间 if(OTA_Continuous_Timeout > CONTINUOUS_TIMEOUT_TIME_MUX)//发送时间太长 { printf("continuous time to long\n"); printf("ota continuous time:%d\n",OTA_Continuous_Timeout); device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 return; } ota_timer_continuous_one_shot(OTA_Continuous_Timeout,ota_timeout_continuous);//打开连续接收定时器 printf("ota_totle_byte:%d, ota_totle_pkg:%d\n",ota_info.total_bytes,ota_info.total_pkgs); printf("send interval:%d, continuous time:%d\n",ota_info.Send_interval,OTA_Continuous_Timeout); } else { device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 } break; case net_msg_type_update_continues: //连续发包指令 g_runData.bUpdate = 1; p_cont = (ota_continues_info_t *)p_msg->taxinfo.info; if(device_fixed_info.Work_State == DEV_WORK_STATE_OTA_BEGIN || device_fixed_info.Work_State == DEV_WORK_STATE_OTA_CONTINUOUS) { if(device_type_and_id_cmp(p_cont->rcv_device_type, p_cont->rcv_device_id)) //是当前设备 { if(p_cont->sub_pkg_len > OTA_UPDATE_PAYLAOA_LEN)//收到的包长度大于128,收到的数据错误 return; if(device_fixed_info.Work_State == DEV_WORK_STATE_OTA_BEGIN) { device_fixed_info.Work_State = DEV_WORK_STATE_OTA_CONTINUOUS; } if(p_cont->total_pkgs == ota_info.total_pkgs) { OSTmrStop(&ota_info.ota_continuous_tmr, OS_OPT_TMR_NONE, NULL, &err); //关闭连续接收定时器 printf("update continues: type = 0x%x, id = 0x%x, {%d/%d/%d}\r\n", p_cont->rcv_device_type, p_cont->rcv_device_id, p_cont->total_pkgs, p_cont->sub_pkg_id,ota_info.lossPkgCounter); //接受本包并写入flash的对应位置 Flash_BufferWrite(OTA_UPDATE_APP3_FLASH_START_ADDR + (p_cont->sub_pkg_id - 1)*OTA_UPDATE_PAYLAOA_LEN, (uint32_t *)(&(p_msg->taxinfo.info[OTA_CONTINUES_INFO_LEN])), p_cont->sub_pkg_len); //更新收包相关状态 for(i = ota_info.lastRightPkgNum;i < p_cont->sub_pkg_id;i++) { ota_info.lossPkgCounter++; ota_info.lossPkgId[ota_info.lossPkgIndex++] = i;//+1因为子包编号从0开始, //丢包太多了,超过了MAX_LOSS_PKG_COUNT,结束本次升级。 if(ota_info.lossPkgCounter == MAX_LOSS_PKG_COUNT) {//降为旁观者, 放弃本次升级 device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 updata_state = PACKET_LOSS_MORE; updata_state_save = set_updata_state(updata_state); BKP_WriteBackupRegister(BKP_DR3, updata_state_save); return; } } ota_info.lastRightPkgNum = p_cont->sub_pkg_id + 1; if(p_cont->sub_pkg_id == ota_info.total_pkgs)//当前是最后一包 { if(ota_info.lossPkgCounter == 0) //没有丢包 { ota_continuous_end_flag = OTA_CONTINUOUS_DIRECT; device_fixed_info.Work_State = DEV_WORK_STATE_OTA_UPGRADE_RCV_END; printf("check begin\n"); } else //有丢包 { //进入连续接收完成任务处理函数 ota_retransmit_delay.timeout = OTA_FIRST_DELAYTIME; ota_retransmit_delay.counter = TickCounter; ota_continuous_end_flag = OTA_CONTINUOUS_DELAY; device_fixed_info.Work_State = DEV_WORK_STATE_OTA_RETRANSMIT; ota_timer_retransmit_one_shot(RETRANSMIT_TIMEOUT_TIME,ota_timeout_retransmit); //打开重传定时器 printf("retransmit begin\n"); } } else //收到最后一包不再打开连续定时器 { //连续接收定时时间 OTA_Continuous_Timeout = ((ota_info.total_pkgs-p_cont->sub_pkg_id) * ota_info.Send_interval)/1000 + CONTINUOUS_TIMEOUT_DELAY_TIME; ota_timer_continuous_one_shot(OTA_Continuous_Timeout,ota_timeout_continuous);//打开连续接收定时器 printf("send interval:%d, continuous time:%d\n",ota_info.Send_interval,OTA_Continuous_Timeout); } //指示灯显示 remain_pkg = ota_info.total_pkgs-p_cont->sub_pkg_id;// gch // Data_last4bit_led(remain_pkg,1); gch set_led_update_status(remain_pkg); } } else { device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 OSTmrStop(&ota_info.ota_continuous_tmr, OS_OPT_TMR_NONE, NULL, &err); //关闭连续接收定时器 } } else { device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 OSTmrStop(&ota_info.ota_continuous_tmr, OS_OPT_TMR_NONE, NULL, &err); //关闭连续接收定时器 } break; case net_msg_type_update_retransmit_rsp: //重传发包指令 g_runData.bUpdate = 1; p_cont = (ota_continues_info_t *)p_msg->taxinfo.info; if(device_fixed_info.Work_State == DEV_WORK_STATE_OTA_RETRANSMIT) { OSTmrStop(&ota_info.ota_retransmit_tmr, OS_OPT_TMR_NONE, NULL, &err); //关闭重传定时器 if(device_type_and_id_cmp(p_cont->rcv_device_type, p_cont->rcv_device_id)&& (p_cont->total_pkgs == ota_info.total_pkgs)) { if(p_cont->sub_pkg_len > OTA_UPDATE_PAYLAOA_LEN)//收到的包长度大于128,收到的数据错误 return; //判定该包是否为本设备丢的那些包之中的子包 for(i = 0;i < ota_info.lossPkgIndex;i++) { if(ota_info.lossPkgId[i] == p_cont->sub_pkg_id) { ota_info.lossPkgCounter--; ota_info.lossPkgId[i] = 0; //接受本包并写入flash的对应位置 Flash_BufferWrite(OTA_UPDATE_APP3_FLASH_START_ADDR + (p_cont->sub_pkg_id - 1)*OTA_UPDATE_PAYLAOA_LEN, (uint32_t *)(&(p_msg->taxinfo.info[OTA_CONTINUES_INFO_LEN]) ), p_cont->sub_pkg_len); printf("rcv retransmit pkgid:%d\n",p_cont->sub_pkg_id); break; } } if(ota_info.lossPkgCounter == 0) //丢包已收完 { ota_continuous_end_flag = OTA_CONTINUOUS_DIRECT; device_fixed_info.Work_State = DEV_WORK_STATE_OTA_UPGRADE_RCV_END; } printf("ota_info.lossPkgCounter = %d, lossPkgId:%d\r\n", ota_info.lossPkgCounter,p_cont->sub_pkg_id); //指示灯显示 remain_pkg = ota_info.lossPkgCounter; //gch //Data_last4bit_led(remain_pkg,1); gch set_led_update_status(remain_pkg); } ota_timer_retransmit_one_shot(RETRANSMIT_TIMEOUT_TIME,ota_timeout_retransmit); //打开重传定时器 } else { device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 OSTmrStop(&ota_info.ota_continuous_tmr, OS_OPT_TMR_NONE, NULL, &err); //关闭连续接收定时器 } break; default: break; } } } //连续接收完成任务处理函数 void ota_continuous_end_handle(void) { OS_ERR err; uint32_t crcVl,fixChar,fileVer,filelen; uint32_t getcrc; uint16_t i; switch(device_fixed_info.Work_State) { case DEV_WORK_STATE_OTA_UPGRADE_RCV_END: OSTmrStop(&ota_info.ota_retransmit_tmr, OS_OPT_TMR_NONE, NULL, &err); //关闭重传定时器 crcVl = *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+ota_info.total_bytes-4); //CRC校验 fixChar = *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+ota_info.total_bytes-8); // 固定字符 WBJW fileVer = *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+ota_info.total_bytes-12); // 固件信息 filelen = *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+ota_info.total_bytes-20); // 文件总长度 printf("read_fixchar:%08x, fixchar:%08x\n",fixChar,0x57424A57); if(fixChar != 0x57424A57) //固定字符错误 { device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 updata_state = FIXED_CHARACTER_ERROR; updata_state_save = set_updata_state(updata_state); BKP_WriteBackupRegister(BKP_DR3, updata_state_save); printf("fixChar error\r\n");// 升级文件固定字符校验错误 return; } printf("read_filever:%08x, device_type:%08x\n",fileVer,0x03013000); if((fileVer&0xfffff000) != 0x03013000) //固件信息错误 { device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 updata_state = DEVICE_TYPE_ERROR; updata_state_save = set_updata_state(updata_state); BKP_WriteBackupRegister(BKP_DR3, updata_state_save); printf("fileVer error\r\n");// 升级文件固件信息校验错误 return; } printf("read_filelen:%08x, total_bytes:%08x\n",filelen,(ota_info.total_bytes-20)); if(ota_info.total_bytes != (filelen+20))//长度错误 { // device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 updata_state = UPDATA_PACKAGE_LENGTH_ERROR; updata_state_save = set_updata_state(updata_state); BKP_WriteBackupRegister(BKP_DR3, updata_state_save); printf("filelen error\r\n");// 升级文件长度校验错误 return; } RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,ENABLE); CRC_ResetDR(); CRC_CalcBlockCRC((uint32_t*)OTA_UPDATE_APP3_FLASH_START_ADDR, (ota_info.total_bytes -4)/4); getcrc = CRC_GetCRC(); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,DISABLE); printf("read_crc:%x, get_crc:%x\n",crcVl,getcrc); if(getcrc!=crcVl) { //校验错误 printf("update file crc error\r\n");// 升级文件crc校验错误 device_fixed_info.Work_State = DEV_WORK_STATE_ONLOOKER; ota_timer_onlooker_one_shot(ONLOOKER_TIMEOUT_TIME,ota_timeout_onlooker); //打开旁观者定时器 updata_state = UPDATA_CRC_ERROR; updata_state_save = set_updata_state(updata_state); BKP_WriteBackupRegister(BKP_DR3, updata_state_save); return; } printf("收包正确\n"); updata_state = UPDATA_DATA_SUCCESS; updata_state_save = set_updata_state(updata_state); BKP_WriteBackupRegister(BKP_DR3, updata_state_save); //置升级标志 updata_state_info.updata_flag = set_updata_state(UPDATA_FLAG); BKP_WriteBackupRegister(BKP_DR2, updata_state_info.updata_flag); /* 置网关下发的升级状态 */ BKP_WriteBackupRegister(BKP_DR5, UP_PROG_FROM_GAT); // 升级的来源 0x44 来源来网关下发的 //存储APP3版本 //device_version_info.APP3_ver = fileVer; //eeprom_write_data(EECFG_APP3_VER0,(uint8_t *)&device_version_info.APP3_ver,4); g_firmwareMsg.gatewayMsg.verMsg.gate_appVr3 = fileVer; fram_write_gateway_version(); NVIC_SystemReset(); break; case DEV_WORK_STATE_OTA_RETRANSMIT: for(i = 0;i < ota_info.lossPkgIndex;i++) { if(ota_info.lossPkgId[i]) { ota_retransmit_req(ota_info.lossPkgId[i]); printf("send retransmit pkgid:%d\n",ota_info.lossPkgId[i]); break; } } break; default: break; } } void ota_process_handle(void) { //连续接收完成延时处理 if(ota_continuous_end_flag == OTA_CONTINUOUS_DIRECT) { ota_continuous_end_flag = OTA_CONTINUOUS_CLOSE; ota_continuous_end_handle(); } else if(ota_continuous_end_flag == OTA_CONTINUOUS_DELAY) { if(TickCounter - ota_retransmit_delay.counter >= ota_retransmit_delay.timeout) { ota_continuous_end_flag = OTA_CONTINUOUS_CLOSE; ota_continuous_end_handle(); //g_runData.bUpdate = 0; } } //升级总定时器计时 if(ota_total_timer_start) { if(TickCounter - ota_total_timer.counter >= ota_total_timer.timeout) { ota_total_timer_start = 0; ota_timeout_total(NULL,NULL); } } }