MW22-02A/APP/Service/service_update.c

1306 lines
47 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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<block_count; i++)
{
Flash_Erase_Block(UPDATE_FLASH_BUFF_BEGIN_BLOCK + i);
feeddog_num = feeddog_num + 1;
if(feeddog_num % 2 == 0)
{
OSTimeDlyHMSM(0u, 0u, 0u, 2u);
}
}
feeddog_num = 0;
return TRUE;
}
//初始化frame_bit_map清空同时设置总数
static int ptz_update_init_frame_bit_map(int frame_count)
{
int byte_count = frame_count / BITS_PER_UNIT;
if(frame_count % BITS_PER_UNIT)
byte_count++;
if(byte_count > 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<<bit_offset);
return TRUE;
}
//根据bit_map返回补包表参数max_count传入表中能保存的最大记录数
static BOOL ptz_update_get_upgrade_retrans_table(UpdateRequest *request_info, UpdateRetransTable *table, int max_count)
{
int byte_offset = 0;
int bit_offset = 0;
int index = 0;
table->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(; i<len; i++)
{
ret += p[i];
}
return (~ret)+1;
}
//检查片内升级包头的checksum
static u_int8_t ptz_update_file_head_checksum_OK(UpdateFileHead *file_head)
{
return ptz_check_sum((u_int8_t *)file_head, (u_int8_t *)(&file_head->head_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; i<sector_count; i++){
// OnChip_Flash_erase_sector(sector_begin + i);
// }
}
else if(file_head->file_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();
}
/*****************************/