#include "ptz_header_file.h" #include "agent_hyt.h" #include "service_update.h" #include "comm_cfginfo.h" #include "includes.h" #include "w25q128.h" #include "rotate_plan.h" #include "enet_to_udp.h" #include "device_wdog.h" #include "onchip_flash.h" //void OnChip_Flash_read_in_add(uint32_t address,uint16_t cnt,uint8_t*bBuf); //uint8_t OnChip_Flash_write_byte(uint32_t address,uint16_t cnt, uint8_t buf[]); //uint8_t OnChip_Flash_erase_sector(uint16_t sectorNo); /****************************************************************************** ** 函数名称: ushort cmCRC_16(uchar *PuchMsg,ushort usDataLen) ** 功 能: 16位CRC校验 ** 修改日志: ******************************************************************************/ extern system_cfg_info system_info; static unsigned char auch_crc_h[]={ 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81, //DESCRIPTION:RTU CRC校验的高位字节表 0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0, 0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01, 0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81, 0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0, 0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01, 0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81, 0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0, 0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01, 0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41, 0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81, 0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0, 0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01, 0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40}; static unsigned char auch_crc_l[]={ 0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4, //DESCRIPTION:RTU CRC校验的低位字节表 0x04,0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09, 0x08,0xC8,0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,0x1E,0xDE,0xDF,0x1F,0xDD, 0x1D,0x1C,0xDC,0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3, 0x11,0xD1,0xD0,0x10,0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,0x36,0xF6,0xF7, 0x37,0xF5,0x35,0x34,0xF4,0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A, 0x3B,0xFB,0x39,0xF9,0xF8,0x38,0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,0xEE, 0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26, 0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2, 0x62,0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,0x6C,0xAC,0xAD,0x6D,0xAF,0x6F, 0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,0x78,0xB8,0xB9,0x79,0xBB, 0x7B,0x7A,0xBA,0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,0xB4,0x74,0x75,0xB5, 0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0,0x50,0x90,0x91, 0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,0x9C,0x5C, 0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98,0x88, 0x48,0x49,0x89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C, 0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40}; static struct sockaddr_in ptz_update_local;//本地IP和端口 static struct sockaddr_in ptz_update_from;//IP和端口 static socklen_t ptz_update_fromlen;//长度 static struct sockaddr_in ptz_update_serv_a;//指定的默认升级服务端 static socklen_t ptz_update_servlen_a; static struct sockaddr_in ptz_update_serv_b;//指定的默认升级服务端 static socklen_t ptz_update_servlen_b; static struct sockaddr_in ptz_update_serv_c;//指定的默认升级服务端 static socklen_t ptz_update_servlen_c; static struct sockaddr_in ptz_update_serv_d;//指定的默认升级服务端 static socklen_t ptz_update_servlen_d; static int ptz_update_fd;//升级通道句柄 static UpdateRecvFifoBuff udrb;//数据接收存储 static UpdateRecvFifoBuff udpb;//数据处理存储 static UpdateRecvFifoBuff udsb;//数据发送存储区 static UpdateRecvFifoBuff urfb[UPDATE_BUFF_FIFO_NUM];//循环缓冲区 static int ptz_update_communicaton = PTZ_CONNECT_STATE_DEAD; static unsigned short int ptz_update_fifo_read_addr;//循环存储区读地址标记 static unsigned short int ptz_update_fifo_write_addr;//循环存储区写地址标记 //static UpdateFileHead ptz_update_file_head;//升级文件头 static UpdateFileHead ptz_update_file_head_inf;//升级文件头 //用以保存接收到的升级frame的状态, //每一位对应一个frame,如果对应的帧已经接收成功,则把这一位设置起来 //用frame_bit_map的每一位保存每一帧升级数据的接收保存状态 static unsigned char update_frame_bit_map[256];//升级状态存储区 static int update_bit_map_count = 0; //总共有多少bit static int update_byte_map_count = 0;//总共有多少个byte static unsigned char update_state;//云台升级状态 //升级补包表 static u_int16_t update_retrans_table_buff[MAX_RETRANS_TABLE_LEN+1]; static UpdateRetransTable *update_retrans_table = (UpdateRetransTable *)update_retrans_table_buff; //文件校验 static u_int8_t flash_read_buff[256]; //片外flash读取的buffer static u_int8_t flash_read_buff2[256]; static u_int8_t flash_read_buff3[256]; static u_int16_t feeddog_num = 0; //UDP环形缓冲区的地址编号计算函数,如果到达唤醒缓冲区的尾部,将绕回到头部 static unsigned char ptz_update_fifo_addring(unsigned short int i) { return ((i + 1) == UPDATE_BUFF_FIFO_NUM) ? 0 : i+1; } //UDP环形缓冲区写入数据 static void ptz_update_fifo_write_data() { //把原来的数据清除 memset(&urfb[ptz_update_fifo_write_addr], 0, sizeof(urfb[ptz_update_fifo_write_addr])); //保存数据,保存有效数据长度 memcpy(&urfb[ptz_update_fifo_write_addr], &udrb, sizeof(udrb)); ptz_update_fifo_write_addr = ptz_update_fifo_addring(ptz_update_fifo_write_addr); } //UDP环形缓冲区读出数据 static UpdateRecvFifoBuff ptz_update_fifo_read_data() { UpdateRecvFifoBuff fifo_data; fifo_data = urfb[ptz_update_fifo_read_addr]; ptz_update_fifo_read_addr = ptz_update_fifo_addring(ptz_update_fifo_read_addr); return fifo_data; } //效验码计算 static unsigned short int ptz_update_calc_frame_crc16( unsigned char *PuchMsg,unsigned int usDataLen) { unsigned char uch_crc_h; //high byte of CRC initialized unsigned char uch_crc_l; //low byte of CRC initialized unsigned short int uIndex; //will index into CRC lookup table uch_crc_h=0xFF; uch_crc_l=0xFF; while(usDataLen--) { //calculate the CRC uIndex = uch_crc_h^(unsigned char)(*PuchMsg++); uch_crc_h = uch_crc_l^auch_crc_h[uIndex]; uch_crc_l = auch_crc_l[uIndex]; } return(uch_crc_h <<8|uch_crc_l); } //应用升级包数据片写入片外flash缓存空间,空间必须先被擦除 //request是升级包总描述信息,frame是要写入的分片 static BOOL ptz_update_write_frame_to_flash_buff(UpdateRequest *request, UpdateData *frame) { u_int32_t offset = UPDATE_FLASH_BUFF_BEGIN_ADDR + request->frame_len * frame->index; if((offset + frame->data_len) > UPDATE_FLASH_BUFF_END_ADDR) return FALSE; Flash_Write_MorePage(frame->data, offset, frame->data_len); return TRUE; } //擦除片外flash应用升级包缓存空间,total_len是升级包的长度 static BOOL ptz_update_erase_flash_buff(unsigned int total_len) { int i = 0; int block_count = total_len / Flash_BLOCKBYTE_LENGTH; if(total_len>UPDATE_FLASH_BUFF_SIZE) return FALSE; if(total_len % Flash_BLOCKBYTE_LENGTH) block_count++; feeddog_num = 0; for(i = 0; i sizeof(update_frame_bit_map)) { return 0; } else { update_bit_map_count = frame_count; update_byte_map_count = byte_count; memset(update_frame_bit_map, 0, sizeof(update_frame_bit_map)); return update_byte_map_count; } } //设置序号为index的帧对应的bit_map static BOOL ptz_update_set_frame_bit_map(int index) { if(index > update_bit_map_count)//index是从0开始的 return FALSE; int byte_offset = index / BITS_PER_UNIT; int bit_offset = index % BITS_PER_UNIT; update_frame_bit_map[byte_offset] |= (0x01<count = 0; memset(update_retrans_table_buff, 0, sizeof(update_retrans_table_buff)); for(byte_offset= 0; byte_offset < update_byte_map_count; byte_offset++) { for(bit_offset = 0; bit_offset < BITS_PER_UNIT; bit_offset++) { if(((0x01 << bit_offset) & update_frame_bit_map[byte_offset]) == 0) //该帧未成功收到 { if(table->count >= max_count) //超出返回容量 return FALSE; table->index[table->count] = index; table->count++; } index++; if(index >= request_info->frame_count) return TRUE; } } return TRUE; } static void ptz_update_CRC16_init(CPU_INT16U *crc16) { *crc16 = 0xFFFF; } static CPU_INT16U ptz_update_CRC16( CPU_INT08U *PuchMsg,CPU_INT32U usDataLen) { CPU_INT08U uchCRCHi; //high byte of CRC initialized CPU_INT08U uchCRCLo; //low byte of CRC initialized CPU_INT16U uIndex; //will index into CRC lookup table uchCRCHi=0xFF; uchCRCLo=0xFF; while(usDataLen--) { //calculate the CRC uIndex = uchCRCHi^(CPU_INT08U)(*PuchMsg++); uchCRCHi = uchCRCLo^auch_crc_h[uIndex]; uchCRCLo = auch_crc_l[uIndex]; } return(uchCRCHi <<8|uchCRCLo); } static void ptz_update_CRC16_update(CPU_INT16U *crc16, CPU_INT08U *PuchMsg,CPU_INT32U usDataLen) { CPU_INT08U uchCRCHi; //high byte of CRC initialized CPU_INT08U uchCRCLo; //low byte of CRC initialized CPU_INT16U uIndex; //will index into CRC lookup table uchCRCHi = (*crc16) >> 8; uchCRCLo = (*crc16) & 0xFF; while(usDataLen--) { uIndex = uchCRCHi^(CPU_INT08U)(*PuchMsg++); uchCRCHi = uchCRCLo^auch_crc_h[uIndex]; uchCRCLo = auch_crc_l[uIndex]; } *crc16 = (uchCRCHi <<8|uchCRCLo); } static u_int16_t _flash_buff_crc16(u_int32_t offset, u_int32_t len) { u_int16_t ret; u_int32_t read_len; ptz_update_CRC16_init(&ret); feeddog_num = 0; while(len) { if(len > sizeof(flash_read_buff)) read_len = sizeof(flash_read_buff); else read_len = len; Flash_Read(flash_read_buff, offset, read_len); ptz_update_CRC16_update(&ret, flash_read_buff, read_len); len -= read_len; offset += read_len; feeddog_num = feeddog_num + 1; if(feeddog_num % 20 == 0) { OSTimeDlyHMSM(0u, 0u, 0u, 5u); } } feeddog_num = 0; return ret; } //检验片外flash缓存空间中的应用升级包的CRC是否正确 //total_len是升级包的总长度,包括结尾的crc16 static BOOL ptz_update_flash_buff_file_crc_OK(u_int32_t total_len) { u_int16_t crc_calc = 0; u_int16_t crc_read = 0; if(total_len < sizeof(crc_calc)) return FALSE; crc_calc = flash_buff_crc16(total_len-2); Flash_Read((u_int8_t *)&crc_read, UPDATE_FLASH_BUFF_BEGIN_ADDR + total_len - sizeof(crc_calc), sizeof(crc_calc)); return crc_calc == crc_read; } void ptz_update_complete_frame_packet(UpdateFrame *pack) { pack->frame_type = UPDATE_FRAME_TYPE_SEND; *(u_int16_t *)(&pack->data[pack->data_len]) = ptz_update_CRC16((u_int8_t *)pack, UPDATE_FRAME_SIZE(pack) - sizeof(u_int16_t)); } //计算chcksum static u_int8_t ptz_check_sum(u_int8_t *p, int len) { u_int8_t ret = 0; int i = 0; for(; ihead_checksum) - (u_int8_t *)file_head) == file_head->head_checksum; } //校验片外存储器中缓存的升级包的完整性 static BOOL ptz_update_file_head_verify(u_int32_t total_len, UpdateFileHead *file_head) { Flash_Read((u_int8_t *)file_head, UPDATE_FLASH_BUFF_BEGIN_ADDR, sizeof(*file_head)); //检查头的checksum if(!ptz_update_file_head_checksum_OK(file_head)) return FALSE; //数据长度确认 if(file_head->data_len != (total_len - sizeof(u_int16_t) - sizeof(*file_head))) return FALSE; //起始标志检查 if(file_head->flag != UPDATE_RELEASE_FILE_FLAG) return FALSE; //头长度检验 if(file_head->head_len != sizeof(*file_head)) return FALSE; //文件类型检验 boot app cert key cfg_file if((file_head->file_type != UPDATE_FILE_TYPE_NW_INFO) && (file_head->file_type != UPDATE_FILE_TYPE_APP) && (file_head->file_type != UPDATE_FILE_TYPE_BOOT_LOADER) && (file_head->file_type != UPDATE_FILE_TYPE_CERT) && (file_head->file_type != UPDATE_FILE_TYPE_PUB_KEY)&& (file_head->file_type != UPDATE_FILE_TYPE_CFG_FILE) && ((file_head->file_type != UPDATE_FILE_TYPE_CFG_IP))) return FALSE; //文件格式版本 if(file_head->file_format_ver != 1) return FALSE; if(file_head->file_type == UPDATE_FILE_TYPE_APP){ //App //烧写地址检验 if(file_head->addr < (UPDATE_APP_ADDR_BEGIN - APP_ADD_BEGIN_OFFEST)) return FALSE; //空间检验 if((file_head->addr + file_head->data_len) > (UPDATE_APP_ADDR_END - APP_ADD_BEGIN_OFFEST)) return FALSE; }else if(file_head->file_type == UPDATE_FILE_TYPE_BOOT_LOADER){ //Bootloader //烧写地址检验 if(file_head->addr != 0) //bootloader必须以0为起始地址 return FALSE; //空间检验 if((file_head->addr + file_head->data_len) > UPDATE_BOOTLOADER_ADDR_END) return FALSE; }else if(file_head->file_type == UPDATE_FILE_TYPE_CERT){//CERT //烧写地址 if(file_head->addr < UPDATE_CERT_ADDR_BEGIN) return FALSE; //空间检验 if((file_head->addr + file_head->data_len) > UPDATE_CERT_ADDR_END) return FALSE; }else if(file_head->file_type == UPDATE_FILE_TYPE_PUB_KEY){//KEY //烧写地址 if(file_head->addr < UPDATE_KEY_ADDR_BEGIN) return FALSE; //空间检验 if((file_head->addr + file_head->data_len) > UPDATE_KEY_ADDR_END) return FALSE; }else if(file_head->file_type == UPDATE_FILE_TYPE_CFG_FILE){//CFG FILE //烧写地址 if(file_head->addr < UPDATE_CFG_FILE_ADDR_BEGIN) return FALSE; //空间检验 if((file_head->addr + file_head->data_len) > UPDATE_CFG_FILE_ADDR_END) return FALSE; }else if (file_head->file_type == UPDATE_FILE_TYPE_CFG_IP){//CFG IP //烧写地址 if(file_head->addr < UPDATE_CFG_IP_ADDR_BEGIN) return FALSE; //空间检验 if((file_head->addr + file_head->data_len) > UPDATE_CFG_IP_ADDR_END) return FALSE; }else if (file_head->file_type == UPDATE_FILE_TYPE_NW_INFO){//NW INFO //烧写地址 if(file_head->addr < UPDATE_CFG_NW_INFO_ADDR_BEGIN) return FALSE; //空间检验 if((file_head->addr + file_head->data_len) > UPDATE_CFG_NW_INFO_ADDR_END) return FALSE; } return TRUE; } //擦除应用程序在片内rom中的存储空间 //如果是应用app/bootloader擦除片内flash. //如果是cert--/key/cfg片外flash static BOOL ptz_update_program_flash_erase(UpdateFileHead *file_head) { //int i = 0; u_int32_t total_len = file_head->data_len; //int sector_begin = file_head->addr / UPDATE_ON_CHIP_FLASH_SECTOR_SIZE; //int sector_count = total_len / UPDATE_ON_CHIP_FLASH_SECTOR_SIZE; if(file_head->file_type == UPDATE_FILE_TYPE_APP) { if((file_head->addr + total_len) > UPDATE_APP_ADDR_END) { return FALSE; } // return TRUE; if(1 == OnChip_Flash_erase_sector(APP_PKG_HEAD_SECTOR_BEGIN)) { term_printf("\n 擦除片内rom失败,APP_PKG_HEAD_SECTOR_BEGIN \r\n"); return FALSE; } if(1 == OnChip_Flash_erase_sector(CTL_SECTOR_NUMBER_4)) { term_printf("\n 擦除片内rom失败,CTL_SECTOR_NUMBER_4 \r\n"); return FALSE; } if(1 == OnChip_Flash_erase_sector(CTL_SECTOR_NUMBER_5)) { term_printf("\n 擦除片内rom失败,CTL_SECTOR_NUMBER_5 \r\n"); return FALSE; } // OnChip_Flash_erase_sector(UPDATE_APP_PKG_HEAD_SECTOR_BEGIN);//同时为升级包的头信息删除一个sector // if(total_len % UPDATE_ON_CHIP_FLASH_SECTOR_SIZE) // sector_count++; // // for(i = 0; ifile_type == UPDATE_FILE_TYPE_PUB_KEY) { if((file_head->addr + total_len) > UPDATE_KEY_ADDR_END) return FALSE; Flash_Erase_Sector(UPDATE_EXT_FLASH_BLOCK_NUM,UPDATE_KEY_HEAD_SECTOR_BEGIN); Flash_Erase_Sector(UPDATE_EXT_FLASH_BLOCK_NUM,UPDATE_KEY_SECTOR_BEGIN); } else if(file_head->file_type == UPDATE_FILE_TYPE_CERT) { if((file_head->addr + total_len) > UPDATE_CERT_ADDR_END) return FALSE; Flash_Erase_Sector(UPDATE_EXT_FLASH_BLOCK_NUM,UPDATE_CERT_HEAD_SECTOR_BEGIN); Flash_Erase_Sector(UPDATE_EXT_FLASH_BLOCK_NUM,UPDATE_CERT_SECTOR_BEGIN); } else if(file_head->file_type == UPDATE_FILE_TYPE_CFG_FILE) { if((file_head->addr + total_len) > UPDATE_CFG_FILE_ADDR_END) return FALSE; Flash_Erase_Sector(UPDATE_EXT_FLASH_BLOCK_NUM,UPDATE_CFG_FILE_HEAD_SECTOR_BEGIN); Flash_Erase_Sector(UPDATE_EXT_FLASH_BLOCK_NUM,UPDATE_CFG_FILE_SECTOR_BEGIN); } else if(file_head->file_type == UPDATE_FILE_TYPE_CFG_IP) {//ip配置 if((file_head->addr + total_len) > UPDATE_CFG_IP_ADDR_END) return FALSE; Flash_Erase_Sector(UPDATE_EXT_FLASH_BLOCK_NUM16,UPDATE_CFG_IP_HEAD_SECTOR_BEGIN); Flash_Erase_Sector(UPDATE_EXT_FLASH_BLOCK_NUM16,UPDATE_CFG_IP_SECTOR_BEGIN); } else if(file_head->file_type == UPDATE_FILE_TYPE_NW_INFO) {//南网台帐信息 if((file_head->addr + total_len) > UPDATE_CFG_NW_INFO_ADDR_END) return FALSE; Flash_Erase_Sector(UPDATE_EXT_FLASH_BLOCK_NUM16,UPDATE_CFG_NW_INFO_HEAD_SECTOR_BEGIN); Flash_Erase_Sector(UPDATE_EXT_FLASH_BLOCK_NUM16,UPDATE_CFG_NW_INFO_SECTOR_BEGIN); Flash_Erase_Sector(UPDATE_EXT_FLASH_BLOCK_NUM16,UPDATE_CFG_NW_INFO_SECTOR_BEGIN+1); } return TRUE; } //app/booter从片外存储器将升级数据复制到片内rom //cert/key/cfg_file 从片外缓冲区复制到片外另外区域 static BOOL ptz_update_program_flash_copy(UpdateFileHead *file_head) { u_int32_t read_len; u_int32_t read_addr = UPDATE_FLASH_BUFF_BEGIN_ADDR + file_head->head_len; u_int32_t len = file_head->data_len + sizeof(u_int16_t); //复制内容包括结尾的crc16 // u_int32_t write_addr = file_head->addr; u_int32_t write_addr = APP_ADDR_BEGIN; char erase_state=0; if (file_head->file_type == UPDATE_FILE_TYPE_APP) {//应用程序 // return TRUE; while(len) {//写程序 if(erase_state == 0) { erase_state++; if(1 == OnChip_Flash_erase_sector(CTL_SECTOR_NUMBER_4)) { term_printf("\n 擦除片内rom失败,CTL_SECTOR_NUMBER_4 \r\n"); return FALSE; } } if(len > sizeof(flash_read_buff)) { read_len = sizeof(flash_read_buff); }else{ read_len = len; } memset(flash_read_buff,0,sizeof(flash_read_buff)); Flash_Read(flash_read_buff, read_addr, read_len); // FeedDog(); // term_printf("\n 程序写入成功,地址write_addr = %d \r\n",flash_read_buff); if(OnChip_Flash_write_byte(write_addr, read_len, flash_read_buff) != 0) { term_printf("\n 程序写入失败,地址write_addr = \r\n",write_addr); return FALSE; } OnChip_Flash_read_in_add(write_addr, read_len, (uint8_t*)&flash_read_buff3); if (memcmp(flash_read_buff, flash_read_buff3, read_len) != 0) { term_printf("\n write rom error to different \r\n"); return FALSE; } len -= read_len; read_addr += read_len; write_addr += read_len; if(erase_state == 1 && write_addr >= 0x801FFFF) { erase_state++; if(1 == OnChip_Flash_erase_sector(CTL_SECTOR_NUMBER_5)) { term_printf("\n 擦除片内rom失败,CTL_SECTOR_NUMBER_5 \r\n"); return FALSE; } } } term_printf("\n 程序写入成功,地址write_addr = %d \r\n",write_addr); // if(write_addr >= 0x8040c00) // { // term_printf("\n write_addr == 0x8040c00 \r\n"); // } // OnChip_Flash_erase_sector(APP_PKG_HEAD_SECTOR_BEGIN); if (OnChip_Flash_write_byte(APP_PKG_HEAD_BEGIN, sizeof(*file_head), (u_int8_t *)file_head) != 0)//写头 { term_printf("\n 文件头写入失败,地址write_addr = \r\n",APP_PKG_HEAD_BEGIN); return FALSE; } } else { feeddog_num = 0; while(len) { if(len > sizeof(flash_read_buff)) read_len = sizeof(flash_read_buff); else read_len = len; Flash_Read(flash_read_buff, read_addr, read_len); Flash_Write_Page(flash_read_buff,write_addr,read_len); len -= read_len; read_addr += read_len; write_addr += read_len; feeddog_num = feeddog_num + 1; if(feeddog_num % 20 == 0) { OSTimeDlyHMSM(0u, 0u, 0u, 5u); } } feeddog_num = 0; if (file_head->file_type == UPDATE_FILE_TYPE_PUB_KEY) {//公钥 Flash_Write_Page((u_int8_t *)file_head,UPDATE_KEY_HEAD_BEGIN,sizeof(*file_head)); } else if(file_head->file_type == UPDATE_FILE_TYPE_CERT) {//证书 Flash_Write_Page((u_int8_t *)file_head,UPDATE_CERT_HEAD_BEGIN,sizeof(*file_head)); } else if(file_head->file_type == UPDATE_FILE_TYPE_CFG_FILE) {//配置文件 Flash_Write_Page((u_int8_t *)file_head,UPDATE_CFG_FILE_HEAD_BEGIN,sizeof(*file_head)); } else if(file_head->file_type == UPDATE_FILE_TYPE_CFG_IP) {//IP配置文件 Flash_Write_Page((u_int8_t *)file_head,UPDATE_CFG_IP_HEAD_BEGIN,sizeof(*file_head)); } else if(file_head->file_type == UPDATE_FILE_TYPE_NW_INFO) {//南网台帐 Flash_Write_Page((u_int8_t *)file_head,UPDATE_CFG_NW_INFO_HEAD_BEGIN,sizeof(*file_head)); } } return TRUE; } //校验已写入片内rom的应用程序包 //通过读出片外flash内容与片内内容完全比较的方式校验 static BOOL ptz_update_program_app_verify(u_int8_t file_type) { u_int32_t read_len, len; u_int32_t read_addr = UPDATE_FLASH_BUFF_BEGIN_ADDR + sizeof(UpdateFileHead); static UpdateFileHead file_head; static UpdateFileHead file_head2; u_int32_t app_addr = 0; memset(&file_head, 0, sizeof(file_head)); //首先校验头信息 if (file_type == UPDATE_FILE_TYPE_APP) {//APP app_addr = UPDATE_APP_ADDR_BEGIN; Flash_Read((u_int8_t *)&file_head, UPDATE_FLASH_BUFF_BEGIN_ADDR, sizeof(file_head)); if(memcmp(&file_head, (u_int8_t *)UPDATE_APP_PKG_HEAD_BEGIN, sizeof(file_head)) != 0) return FALSE; len = file_head.data_len + sizeof(u_int16_t); //校验包括crc16内容 while(len){ if(len > sizeof(flash_read_buff)) read_len = sizeof(flash_read_buff); else read_len = len; Flash_Read(flash_read_buff, read_addr, read_len); if(memcmp(flash_read_buff, (u_int8_t *)app_addr, read_len) != 0) return FALSE; len -= read_len; read_addr += read_len; app_addr += read_len; } return TRUE; } else { if (file_type == UPDATE_FILE_TYPE_CERT) {//CERT app_addr = UPDATE_CERT_ADDR_BEGIN; Flash_Read((u_int8_t *)&file_head, UPDATE_FLASH_BUFF_BEGIN_ADDR, sizeof(file_head)); Flash_Read((u_int8_t *)&file_head2, UPDATE_CERT_HEAD_BEGIN, sizeof(file_head2)); if(memcmp(&file_head,&file_head2, sizeof(file_head)) != 0) return FALSE; } else if(file_type == UPDATE_FILE_TYPE_PUB_KEY) { app_addr = UPDATE_KEY_ADDR_BEGIN; Flash_Read((u_int8_t *)&file_head, UPDATE_FLASH_BUFF_BEGIN_ADDR, sizeof(file_head)); Flash_Read((u_int8_t *)&file_head2, UPDATE_KEY_HEAD_BEGIN, sizeof(file_head2)); if (memcmp(&file_head,&file_head2, sizeof(file_head)) != 0) return FALSE; } else if(file_type ==UPDATE_FILE_TYPE_CFG_FILE) { app_addr = UPDATE_CFG_FILE_ADDR_BEGIN; Flash_Read((u_int8_t *)&file_head, UPDATE_FLASH_BUFF_BEGIN_ADDR, sizeof(file_head)); Flash_Read((u_int8_t *)&file_head2, UPDATE_CFG_FILE_HEAD_BEGIN, sizeof(file_head2)); if (memcmp(&file_head,&file_head2, sizeof(file_head)) != 0) return FALSE; } else if(file_type ==UPDATE_FILE_TYPE_CFG_IP) { app_addr = UPDATE_CFG_IP_ADDR_BEGIN; Flash_Read((u_int8_t *)&file_head, UPDATE_FLASH_BUFF_BEGIN_ADDR, sizeof(file_head)); Flash_Read((u_int8_t *)&file_head2, UPDATE_CFG_IP_HEAD_BEGIN, sizeof(file_head2)); if (memcmp(&file_head,&file_head2, sizeof(file_head)) != 0) return FALSE; } else if(file_type ==UPDATE_FILE_TYPE_NW_INFO) { app_addr = UPDATE_CFG_NW_INFO_ADDR_BEGIN; Flash_Read((u_int8_t *)&file_head, UPDATE_FLASH_BUFF_BEGIN_ADDR, sizeof(file_head)); Flash_Read((u_int8_t *)&file_head2, UPDATE_CFG_NW_INFO_HEAD_BEGIN, sizeof(file_head2)); if (memcmp(&file_head,&file_head2, sizeof(file_head)) != 0) return FALSE; } len = file_head.data_len + sizeof(u_int16_t); //校验包括crc16内容 feeddog_num = 0; while(len) { if(len > sizeof(flash_read_buff)) read_len = sizeof(flash_read_buff); else read_len = len; Flash_Read(flash_read_buff, read_addr, read_len); Flash_Read(flash_read_buff2,app_addr,read_len); if(memcmp(flash_read_buff,flash_read_buff2, read_len) != 0) return FALSE; len -= read_len; read_addr += read_len; app_addr += read_len; feeddog_num = feeddog_num + 1; if(feeddog_num % 20 == 0) { OSTimeDlyHMSM(0u, 0u, 0u, 5u); } } feeddog_num = 0; } return TRUE; } //校验并把片外flash中缓存的App升级包烧写进片内rom,然后再校验 static BOOL ptz_update_program_file(u_int32_t total_len) { static UpdateFileHead file_head; memset(&file_head, 0, sizeof(file_head)); Flash_Read((u_int8_t *)&file_head, UPDATE_FLASH_BUFF_BEGIN_ADDR, sizeof(file_head)); if(!ptz_update_file_head_verify(total_len, &file_head)) return FALSE; if((file_head.file_type == UPDATE_FILE_TYPE_NW_INFO) || (file_head.file_type == UPDATE_FILE_TYPE_APP) || (file_head.file_type == UPDATE_FILE_TYPE_PUB_KEY) || (file_head.file_type == UPDATE_FILE_TYPE_CERT) || (file_head.file_type == UPDATE_FILE_TYPE_CFG_FILE) || (file_head.file_type == UPDATE_FILE_TYPE_CFG_IP)) { if(!ptz_update_program_flash_erase(&file_head)) return FALSE; if(!ptz_update_program_flash_copy(&file_head)) return FALSE; if(!ptz_update_program_app_verify(file_head.file_type)) return FALSE; }else //不认识的文件类型 return FALSE; return TRUE; } static BOOL ptz_update_burn_bootloader(u_int32_t total_len) { static UpdateFileHead file_head; memset(&file_head, 0, sizeof(file_head)); Flash_Read((u_int8_t *)&file_head, UPDATE_FLASH_BUFF_BEGIN_ADDR, sizeof(file_head)); if(file_head.file_type == UPDATE_FILE_TYPE_BOOT_LOADER) { if(!ptz_update_file_head_verify(total_len, &file_head)) return FALSE; // if(!ptz_update_bootloader_flash_erase(&file_head)) // return FALSE; // // if(!ptz_update_bootloader_flash_copy(&file_head)) // return FALSE; // // if(!ptz_update_bootloader_verify()) // return FALSE; }else //不认识的文件类型 return FALSE; return TRUE; } //云台向升级端发送升级回复 static void ptz_send_update_reply(unsigned char pack_type, const void *data, int len) { //建立一个指针指向发送数据缓冲区 UpdateFrame *pack = (UpdateFrame *)udsb.data_buff; //对发送缓冲区数据清0 memset(&udsb, 0, sizeof(udsb)); //数据封包 pack->flag = UPDATE_FRAME_HEAD_FLAG;//帧头 pack->data_len = len;//数据长度 if(data && (len > 0))//判断有无数据 memcpy(pack->data, data, len);//有数据则装载数据 memcpy(pack->id, system_info.cmd_id, sizeof(pack->id));//复制设备ID pack->frame_type = UPDATE_FRAME_TYPE_SEND; pack->pack_type = pack_type; //计算数据包总长度 udsb.data_len = UPDATE_FRAME_SIZE(pack); ptz_update_complete_frame_packet(pack); //发送数据 BSP_OS_SemWait(&udp_send_data_mutex, 0u); if(ptz_update_communicaton == PTZ_CONNECT_STATE_SUCCESS){ int ret = sendto(ptz_update_fd, pack, udsb.data_len, 0, (struct sockaddr*)&ptz_update_from, ptz_update_fromlen); if(ret == -1){ ptz_update_communicaton = PTZ_CONNECT_STATE_FAILED; close(ptz_update_fd); } } BSP_OS_SemPost(&udp_send_data_mutex); } //云台向指定的升级端发送心跳包ptz_send_update_reply(UPDATE_FRAME_TYPE_KEEP_ALIVE, NULL, 0); static void ptz_send_update_heartbeat() { int ret; //建立一个指针指向发送数据缓冲区 UpdateFrame *pack = (UpdateFrame *)udsb.data_buff; //对发送缓冲区数据清0 memset(&udsb, 0, sizeof(udsb)); //数据封包 pack->flag = UPDATE_FRAME_HEAD_FLAG;//帧头 pack->data_len = 0;//数据长度 memcpy(pack->id, system_info.cmd_id, sizeof(pack->id));//复制设备ID pack->frame_type = UPDATE_FRAME_TYPE_SEND; pack->pack_type = UPDATE_FRAME_TYPE_KEEP_ALIVE; //计算数据包总长度 udsb.data_len = UPDATE_FRAME_SIZE(pack); ptz_update_complete_frame_packet(pack); //发送数据 BSP_OS_SemWait(&udp_send_data_mutex, 0u); if(ptz_update_communicaton == PTZ_CONNECT_STATE_SUCCESS) { ret = sendto(ptz_update_fd, pack, udsb.data_len, 0, (struct sockaddr*)&ptz_update_serv_a, ptz_update_servlen_a); if(ret == -1){ ptz_update_communicaton = PTZ_CONNECT_STATE_FAILED; close(ptz_update_fd); BSP_OS_SemPost(&udp_send_data_mutex); return; } ret = sendto(ptz_update_fd, pack, udsb.data_len, 0, (struct sockaddr*)&ptz_update_serv_b, ptz_update_servlen_b); if(ret == -1){ ptz_update_communicaton = PTZ_CONNECT_STATE_FAILED; close(ptz_update_fd); BSP_OS_SemPost(&udp_send_data_mutex); return; } ret = sendto(ptz_update_fd, pack, udsb.data_len, 0, (struct sockaddr*)&ptz_update_serv_c, ptz_update_servlen_c); if(ret == -1){ ptz_update_communicaton = PTZ_CONNECT_STATE_FAILED; close(ptz_update_fd); BSP_OS_SemPost(&udp_send_data_mutex); return; } ret = sendto(ptz_update_fd, pack, udsb.data_len, 0, (struct sockaddr*)&ptz_update_serv_d, ptz_update_servlen_d); if(ret == -1){ ptz_update_communicaton = PTZ_CONNECT_STATE_FAILED; close(ptz_update_fd); BSP_OS_SemPost(&udp_send_data_mutex); return; } } BSP_OS_SemPost(&udp_send_data_mutex); } //升级数据接收 static void ptz_update_rece_data_task() { while(1) { //建立本地连接通道 if(ptz_update_communicaton != PTZ_CONNECT_STATE_SUCCESS) { ptz_update_fd = CreateUDPClientSock(); if(ptz_update_fd != -1) { // 设置服务器端ip和端口号 memset(&ptz_update_from, 0, sizeof(struct sockaddr_in)); ptz_update_local.sin_family = PF_INET; // 监听端口 ptz_update_local.sin_port = htons(PTZ_UPDATE_PORT); ptz_update_local.sin_addr.s_addr = INADDR_ANY; ptz_update_fromlen = sizeof(ptz_update_from); if(0!=bind(ptz_update_fd,(struct sockaddr*)&ptz_update_local,sizeof(ptz_update_local))) { close(ptz_update_fd); } else { ptz_update_communicaton = PTZ_CONNECT_STATE_SUCCESS; } } else { ptz_update_communicaton = PTZ_CONNECT_STATE_FAILED; close(ptz_update_fd); } } if(ptz_update_communicaton == PTZ_CONNECT_STATE_SUCCESS) { memset(&udrb, 0, sizeof(udrb));//'\0' udrb.data_len = recvfrom(ptz_update_fd, udrb.data_buff, sizeof(udrb.data_buff), 0, (struct sockaddr*)&ptz_update_from, &ptz_update_fromlen); if (udrb.data_len >0) { //将数据保存到环形缓冲区 ptz_update_fifo_write_data(); } else { ptz_update_communicaton = PTZ_CONNECT_STATE_FAILED; close(ptz_update_fd); } } OSTimeDlyHMSM(0u, 0u, 0u, 2u); } } //云台升级数据处理 static void ptz_update_data_process_task() { static char info_str[256]; static char kh = 0; int count = 0; static UpdateFrame* update_frame = (UpdateFrame *)udpb.data_buff;//升级帧 static UpdateRequest request_info;//升级请求 static UpdateData* update_data = NULL;//升级具体数据 static unsigned char update_active_connect_switch = 0;//主动连接指定升级服务端开关 static unsigned int update_active_connect_timer = 0;//主动连接指定升级服务端计时 while(1) { #if 1 //判断循环buff里面是否有未处理的数据 if(ptz_update_fifo_read_addr != ptz_update_fifo_write_addr) { memset(&udpb, 0, sizeof(udpb)); //从循环buff读取数据 // udpb = ptz_update_fifo_read_data(); udpb = urfb[ptz_update_fifo_read_addr]; ptz_update_fifo_read_addr = ptz_update_fifo_addring(ptz_update_fifo_read_addr); //开始处理数据 if(ptz_update_calc_frame_crc16(udpb.data_buff, udpb.data_len - 2) == UPDATE_FRAME_GET_CRC16(update_frame)) //首先判断每一帧的校验码是否正确 { if(update_frame->frame_type == UPDATE_FRAME_TYPE_RECE &&//判断帧类型是不是接收数据 update_frame->flag == UPDATE_FRAME_HEAD_FLAG)//判断帧头是否正确 { switch(update_frame->pack_type) { case UPDATE_FRAME_TYPE_KEEP_ALIVE: //0X01 用以保持连接 ptz_send_update_reply(UPDATE_FRAME_TYPE_KEEP_ALIVE, NULL, 0); break; case UPDATE_FRAME_TYPE_GET_DEVICE_INFO: //0X02 用于获取设备信息,包括软硬件版本等 memset((u_int8_t *)&ptz_update_file_head_inf, 0, sizeof(ptz_update_file_head_inf)); memcpy((u_int8_t *)&ptz_update_file_head_inf, (u_int8_t *)UPDATE_APP_PKG_HEAD, sizeof(ptz_update_file_head_inf)); //校验包头,若干片内没有头信息,则为出厂程序,头信息赋初始值 //检查头的checksum if(!ptz_update_file_head_checksum_OK(&ptz_update_file_head_inf)) { ptz_update_file_head_inf.hardware_type[0] = HARD_WARE_TYPE_DEFAULT_K; ptz_update_file_head_inf.hardware_type[1] = HARD_WARE_TYPE_DEFAULT_6; ptz_update_file_head_inf.hardware_ver = 1; ptz_update_file_head_inf.software_ver = 1; ptz_update_file_head_inf.addr = 0x00010000; } ptz_send_update_reply(UPDATE_FRAME_TYPE_GET_DEVICE_INFO, (u_int8_t *)&ptz_update_file_head_inf, sizeof(ptz_update_file_head_inf)); break; case UPDATE_FRAME_TYPE_RESET_DEVICE: //0X03 设备复位 ptz_hori_stop(0); ptz_vert_stop(0); count = sprintf(info_str, "OK"); ptz_send_update_reply(UPDATE_FRAME_TYPE_RESET_DEVICE, info_str, count); OSTimeDlyHMSM(0u, 0u, 0u, 10u); GD32_RESET(); break; case UPDATE_FRAME_TYPE_BOOT_APP: //0X04 要求设备载入应用(直接复位) ptz_hori_stop(0); ptz_vert_stop(0); count = sprintf(info_str, "OK"); ptz_send_update_reply(UPDATE_FRAME_TYPE_BOOT_APP, info_str, count); OSTimeDlyHMSM(0u, 0u, 0u, 10u); GD32_RESET(); break; case UPDATE_FRAME_TYPE_UPGRADE_REQ: //0X05 升级设备请求,数据内容是一个upgrade_request结构 memset(&request_info, 0, sizeof(request_info)); update_bit_map_count = 0; //总共有多少bit,每一位bit存储每一帧接收的状态 update_byte_map_count = 0;//总共有多少个byte,存储所有帧接收的状态要用多少个字节 //提取升级文件头 memcpy(&request_info, update_frame->data, sizeof(request_info)); //判断存储每一个帧的状态需要多少位BIT,多少个字节BYTE if(!ptz_update_init_frame_bit_map(request_info.frame_count)) { count = sprintf(info_str, "准备接收数据出错(init_frame_bit_map)!"); ptz_send_update_reply(UPDATE_FRAME_TYPE_ERROR, info_str, count); break; } //判断升级数据包是否超出设定的片外FLASH存储的大小 if(!ptz_update_erase_flash_buff(request_info.total_len)) { count = sprintf(info_str, "准备接收数据出错(erase_upgrad_flash_buff)!"); ptz_send_update_reply(UPDATE_FRAME_TYPE_ERROR, info_str, count); break; } update_state = UPDATE_STATE_UPGRADE_DATA_TRANS; ptz_send_update_reply(UPDATE_FRAME_TYPE_UPGRADE_REQ, &request_info, sizeof(request_info)); break; case UPDATE_FRAME_TYPE_UPGRADE_DATE: //0X06 升级设备数据,数据内容是一个upgrade_frame结构 update_data = (UpdateData*)update_frame->data; if(update_state != UPDATE_STATE_UPGRADE_DATA_TRANS) { count = sprintf(info_str, "设备未进入接收状态,请先发送升级请求包!"); ptz_send_update_reply(UPDATE_FRAME_TYPE_ERROR, info_str, count); break; } if(!ptz_update_write_frame_to_flash_buff(&request_info, update_data)) { count = sprintf(info_str, "升级数据写入失败!"); ptz_send_update_reply(UPDATE_FRAME_TYPE_ERROR, info_str, count); break; } if(!ptz_update_set_frame_bit_map(update_data->index)) { count = sprintf(info_str, "升级帧状态保存总数溢出"); ptz_send_update_reply(UPDATE_FRAME_TYPE_ERROR, info_str, count); break; } break; case UPDATE_FRAME_TYPE_UPGRADE_FINISH: //0X07 升级设备结束,SRV->Device数据内容空 if(update_state != UPDATE_STATE_UPGRADE_DATA_TRANS) { count = sprintf(info_str, "设备未进入接收状态,请先发送升级请求包!"); ptz_send_update_reply(UPDATE_FRAME_TYPE_ERROR, info_str, count); break; } //判断哪些帧接收失败 if(!ptz_update_get_upgrade_retrans_table(&request_info, update_retrans_table, MAX_RETRANS_TABLE_LEN)) { count = sprintf(info_str, "准备重传数据出错!"); ptz_send_update_reply(UPDATE_FRAME_TYPE_ERROR, info_str, count); update_state = UPDATE_STATE_IDEL; break; } //判断是否需要重传 if(update_retrans_table->count > 0) { ptz_send_update_reply(UPDATE_FRAME_TYPE_UPGRADE_FINISH, update_retrans_table, UPDATE_RETRANS_TABLE_SIZE(update_retrans_table)); update_state = UPDATE_STATE_UPGRADE_DATA_TRANS; break; } //校验升级包文件 if(!ptz_update_flash_buff_file_crc_OK(request_info.total_len)) { count = sprintf(info_str, "升级包CRC校验失败!"); ptz_send_update_reply(UPDATE_FRAME_TYPE_ERROR, info_str, count); update_state = UPDATE_STATE_IDEL; break; } //将bootloader存入单片机内部的RAM if(request_info.file_head.file_type == UPDATE_FILE_TYPE_BOOT_LOADER) { // if(!ptz_update_burn_bootloader(request_info.total_len)) // { // count = sprintf(info_str, "升级失败!!!!"); // ptz_send_update_reply(UPDATE_FRAME_TYPE_ERROR, info_str, count); // update_state = UPDATE_STATE_IDEL; // break; // } ptz_send_update_reply(UPDATE_FRAME_TYPE_UPGRADE_FINISH, update_retrans_table, UPDATE_RETRANS_TABLE_SIZE(update_retrans_table)); update_state = UPDATE_STATE_IDEL; break; } //其他文件升级,包含应用程序,配置文件等 if(request_info.file_head.file_type != UPDATE_FILE_TYPE_BOOT_LOADER) { // if(!ptz_update_program_file(request_info.total_len)) // { // count = sprintf(info_str, "升级包失败!!!!"); // ptz_send_update_reply(UPDATE_FRAME_TYPE_ERROR, info_str, count); // update_state = UPDATE_STATE_IDEL; // break; // } ptz_send_update_reply(UPDATE_FRAME_TYPE_UPGRADE_FINISH, update_retrans_table, UPDATE_RETRANS_TABLE_SIZE(update_retrans_table)); update_state = UPDATE_STATE_IDEL; } break; } } } } #endif //初始化指定升级服务端的IP和端口 if(ptz_update_communicaton == PTZ_CONNECT_STATE_SUCCESS) { if(update_active_connect_switch == 0) { //初始化指定升级服务端的IP和端口 ptz_update_serv_a.sin_family = PF_INET; ptz_update_serv_a.sin_port = htons(PTZ_UPDATE_SERV_PORT_A); ptz_update_serv_a.sin_addr.s_addr = inet_addr(PTZ_UPDATE_SERV_IP_A); ptz_update_servlen_a = sizeof(ptz_update_serv_a); ptz_update_serv_b.sin_family = PF_INET; ptz_update_serv_b.sin_port = htons(PTZ_UPDATE_SERV_PORT_A); ptz_update_serv_b.sin_addr.s_addr = inet_addr(PTZ_UPDATE_SERV_IP_B); ptz_update_servlen_b = sizeof(ptz_update_serv_b); ptz_update_serv_c.sin_family = PF_INET; ptz_update_serv_c.sin_port = htons(PTZ_UPDATE_SERV_PORT_B); ptz_update_serv_c.sin_addr.s_addr = inet_addr(PTZ_UPDATE_SERV_IP_A); ptz_update_servlen_c = sizeof(ptz_update_serv_c); ptz_update_serv_d.sin_family = PF_INET; ptz_update_serv_d.sin_port = htons(PTZ_UPDATE_SERV_PORT_B); ptz_update_serv_d.sin_addr.s_addr = inet_addr(PTZ_UPDATE_SERV_IP_B); ptz_update_servlen_d = sizeof(ptz_update_serv_d); update_active_connect_timer = 0;//发送间隔时间清0 update_active_connect_switch = 1;//初始化完成后默认打开发送心跳包 } } //判断是否需要发送心跳包 if(update_active_connect_switch != 0) {//首先发送的端口和通道要完成初始化 if(update_state == UPDATE_STATE_UPGRADE_DATA_TRANS) { update_active_connect_switch = 2;//关闭心跳包发送 } else//update_state == UPDATE_STATE_IDEL || update_state == UPDATE_STATE_DEAD { update_active_connect_switch = 1;//打开心跳包发送 } } //主动发送升级心跳包 if(ptz_update_communicaton == PTZ_CONNECT_STATE_SUCCESS) { if(update_active_connect_switch == 1) { if(kh == 0) {//一旦进入应用程序先发送2包升级心跳包 kh = 1; ptz_send_update_heartbeat();//发送升级心跳包 OSTimeDlyHMSM(0u, 0u, 1u, 0u); ptz_send_update_heartbeat();//发送升级心跳包 } update_active_connect_timer = update_active_connect_timer + 2;//改时间根据任务挂起时间计算 if(update_active_connect_timer >= 30000)//30S发一次 { update_active_connect_timer = 0; ptz_send_update_heartbeat();//发送升级心跳包 } } } OSTimeDlyHMSM(0u, 0u, 0u, 2u); } } static OS_STK task_update_rece_data_stk[TASK_PTZ_UPDATE_RECE_DATA_STK_SIZE]; static void creat_task_update_rece_data(void) { CPU_INT08U task_err; CPU_INT08U name_err; task_err = OSTaskCreateExt((void (*)(void *)) ptz_update_rece_data_task, (void *) 0, (OS_STK *)&task_update_rece_data_stk[TASK_PTZ_UPDATE_RECE_DATA_STK_SIZE - 1], (INT8U ) TASK_PTZ_UPDATE_RECE_DATA_PRIO, (INT16U ) TASK_PTZ_UPDATE_RECE_DATA_PRIO, (OS_STK *)&task_update_rece_data_stk[0], (INT32U ) TASK_PTZ_UPDATE_RECE_DATA_STK_SIZE, (void *) 0, (INT16U )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR)); #if (OS_TASK_NAME_EN > 0) OSTaskNameSet(TASK_PTZ_UPDATE_RECE_DATA_PRIO, "ptz_update_rece_data_task", &name_err); #endif if ((task_err == OS_ERR_NONE) && (name_err == OS_ERR_NONE)) { pdebug(DEBUG_LEVEL_INFO,"create ptz_update_rece_data_task success...\n\r"); } else { pdebug(DEBUG_LEVEL_FATAL,"create ptz_update_rece_data_task failed...\n\r"); } } static OS_STK task_update_data_process_stk[TASK_PTZ_UPDATE_DATA_PROCESS_STK_SIZE]; static void creat_task_update_data_process(void) { CPU_INT08U task_err; CPU_INT08U name_err; task_err = OSTaskCreateExt((void (*)(void *)) ptz_update_data_process_task, (void *) 0, (OS_STK *)&task_update_data_process_stk[TASK_PTZ_UPDATE_DATA_PROCESS_STK_SIZE - 1], (INT8U ) TASK_PTZ_UPDATE_DATA_PROCESS_PRIO, (INT16U ) TASK_PTZ_UPDATE_DATA_PROCESS_PRIO, (OS_STK *)&task_update_data_process_stk[0], (INT32U ) TASK_PTZ_UPDATE_DATA_PROCESS_STK_SIZE, (void *) 0, (INT16U )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR)); #if (OS_TASK_NAME_EN > 0) OSTaskNameSet(TASK_PTZ_UPDATE_DATA_PROCESS_PRIO, "ptz_update_data_process_task", &name_err); #endif if ((task_err == OS_ERR_NONE) && (name_err == OS_ERR_NONE)) { pdebug(DEBUG_LEVEL_INFO,"create ptz_update_data_process_task success...\n\r"); } else { pdebug(DEBUG_LEVEL_FATAL,"create ptz_update_data_process_task failed...\n\r"); } } void init_update_module() { creat_task_update_rece_data(); creat_task_update_data_process(); } /*****************************/