561 lines
13 KiB
C
561 lines
13 KiB
C
#include "system_updata.h"
|
||
|
||
|
||
|
||
|
||
|
||
//通过SD卡进行系统文件升级
|
||
void SysFile_Updata(char *FileName,char *FilePath)
|
||
{
|
||
u8 ret=0;
|
||
if (FLASH_FindFile(FileName,0)==0)
|
||
{
|
||
FILINFO *file_info=mymalloc(sizeof (FILINFO));
|
||
FIL *file_fil=mymalloc (sizeof(FIL));
|
||
u8 *file_mem=mymalloc(4096);
|
||
u32 read_size=0;
|
||
UINT real_size=0;
|
||
u32 read_size_left=0;
|
||
u32 flash_write_addr=FLASH_GetUsed();
|
||
ret=f_stat (FilePath,file_info);
|
||
if (ret==FR_OK)
|
||
{
|
||
FLASH_CheckErase(flash_write_addr,file_info->fsize);
|
||
f_open(file_fil,FilePath,FA_READ);
|
||
read_size_left=file_info->fsize;
|
||
FLASH_AddFile(FileName,flash_write_addr,read_size_left);
|
||
while(read_size_left)
|
||
{
|
||
if (read_size_left>4096)
|
||
{
|
||
read_size=4096;
|
||
}
|
||
else
|
||
{
|
||
read_size=read_size_left;
|
||
}
|
||
f_read (file_fil,file_mem,read_size,&real_size);
|
||
FLASH_WriteData(file_mem,flash_write_addr,real_size);
|
||
read_size_left-=read_size;
|
||
flash_write_addr+=real_size;
|
||
}
|
||
f_close(file_fil);
|
||
}
|
||
myfree(file_info);
|
||
myfree(file_fil);
|
||
myfree(file_mem);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
//读取一个文件
|
||
u8 *SysFile_GetFileByName (char *name,u32 *size)
|
||
{
|
||
u8 *data=0;
|
||
if (name==0) return data;
|
||
if (name[0]=='0'&&name[1]==':')
|
||
{
|
||
FIL *file=mymalloc (sizeof(FIL));
|
||
FILINFO *file_info=mymalloc(sizeof(FILINFO));
|
||
UINT br;
|
||
u8 res=0;
|
||
f_stat(name,file_info);
|
||
data=mymalloc (file_info->fsize);
|
||
if (data)
|
||
{
|
||
f_open(file,name,FA_READ);
|
||
f_read(file,data,file_info->fsize,&br);
|
||
f_close(file);
|
||
if (size) *size=file_info->fsize;
|
||
}
|
||
myfree(file);
|
||
myfree(file_info);
|
||
return data;
|
||
}
|
||
else
|
||
{
|
||
u32 file_size=0;
|
||
if (FLASH_FindFile (name,&file_size)!=0)
|
||
{
|
||
//在外置FLASH中读取图像数据
|
||
data=mymalloc (file_size);
|
||
FLASH_ReadFile (name,0,(u8*)data,file_size);
|
||
if (size) *size=file_size;
|
||
}
|
||
return data;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//从接收buff中提取数据,并进行crc校验
|
||
static int SysFile_GetData (u8 *buff,int len);
|
||
|
||
//下载数据时调用这个函数处理
|
||
int cmd_0x01 (SysFile_UpdataStruct *u,u8 *data,int dataLen);
|
||
|
||
//保存一个字节
|
||
void SysFile_UpdataSaveByte (SysFile_UpdataStruct *u,u8 byte);
|
||
|
||
//这个函数处理下载数据时保存在内存里
|
||
int cmd_0x01_Mem (SysFile_UpdataStruct *u,u8 *data,int dataLen);
|
||
|
||
|
||
|
||
//void SysFile_DeleteUpdata (SysFile_UpdataStruct *u)
|
||
//{
|
||
// if (u->data)
|
||
//}
|
||
|
||
|
||
|
||
|
||
//通过USB进行系统文件升级,在中断中调用这个函数
|
||
void SysFile_UpdataByIrq (u8 *data,int len)
|
||
{
|
||
int datalen=0;
|
||
int ret=0;
|
||
static SysFile_UpdataStruct *updata=0;
|
||
if (datalen=SysFile_GetData(data,len),datalen)
|
||
{
|
||
if (data[0]==0x01)
|
||
{
|
||
//必须是传输开始包才创建
|
||
if (data[1]==0x01)
|
||
{
|
||
if (updata)
|
||
{
|
||
//上次传输没有完成并且下次传输到来
|
||
//发送上次传输失败消息
|
||
SysFile_RecvedStruct *recv=mymalloc (sizeof (SysFile_RecvedStruct));
|
||
recv->structType=SYSFILE_TYPE_RECVFILE;
|
||
recv->data=(u8*)updata->saveAddr;
|
||
recv->dataLen=updata->buffUsed;
|
||
recv->recved=0; //失败
|
||
mymemcpy (recv->name,updata->name,strlen(updata->name)+1);
|
||
WIN_PlaceExtData (recv,sizeof (SysFile_RecvedStruct));
|
||
myfree(recv);
|
||
if (updata->saveAddr) myfree((void *)updata->saveAddr);
|
||
myfree(updata); updata=0;
|
||
}
|
||
updata=mymalloc (sizeof (SysFile_UpdataStruct));
|
||
mymemset (updata,0,sizeof (SysFile_UpdataStruct));
|
||
}
|
||
//必须是有效包才进入传输
|
||
if (updata&&(ret=cmd_0x01_Mem (updata,data+1,datalen-1),ret!=0))//传输失败
|
||
{
|
||
//在这里把接收失败的消息发给窗口
|
||
SysFile_RecvedStruct *recv=mymalloc (sizeof (SysFile_RecvedStruct));
|
||
recv->structType=SYSFILE_TYPE_RECVFILE;
|
||
recv->data=(u8*)updata->saveAddr;
|
||
recv->dataLen=updata->buffUsed;
|
||
recv->recved=0; //失败
|
||
mymemcpy (recv->name,updata->name,strlen(updata->name)+1);
|
||
WIN_PlaceExtData (recv,sizeof (SysFile_RecvedStruct));
|
||
myfree(recv);
|
||
if (updata->saveAddr) myfree((void *)updata->saveAddr);
|
||
myfree(updata); updata=0;
|
||
}
|
||
if (updata->step==0x04) //数据传输完成
|
||
{
|
||
//在这里把接收到数据的消息发给窗口
|
||
SysFile_RecvedStruct *recv=mymalloc (sizeof (SysFile_RecvedStruct));
|
||
recv->structType=SYSFILE_TYPE_RECVFILE;
|
||
recv->data=(u8*)updata->saveAddr;
|
||
recv->dataLen=updata->buffUsed;
|
||
recv->recved=1;
|
||
mymemcpy (recv->name,updata->name,strlen(updata->name)+1);
|
||
if (WIN_PlaceExtData (recv,sizeof (SysFile_RecvedStruct))!=0)
|
||
myfree((void *)updata->saveAddr);//发送失败时释放掉文件占用的内存
|
||
myfree(recv);
|
||
//这里释放了 SysFile_UpdataStruct 结构体,但是文件占用的内存没有释放
|
||
myfree(updata); updata=0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//通过协议进行系统文件升级
|
||
void SysFile_UpdataByCom (void)
|
||
{
|
||
int real=0;
|
||
int datalen=0;
|
||
u8 *databuff=mymalloc (256);
|
||
u8 ret[10]={0};
|
||
int t=0;
|
||
SysFile_UpdataStruct *updata=mymalloc (sizeof (SysFile_UpdataStruct));
|
||
mymemset (updata,0,sizeof (SysFile_UpdataStruct));
|
||
do
|
||
{
|
||
if (datalen=SysFile_GetData(databuff,256),datalen)
|
||
{
|
||
if (databuff[0]==0x01)
|
||
{
|
||
if (t=cmd_0x01 (updata,databuff+1,datalen-1),t==0)
|
||
{ real=1; }
|
||
else
|
||
{ real=0;}
|
||
mymemset (ret,t,5);
|
||
// usb_sendData(ret,5);
|
||
if (updata->step==0x04) break;//数据传输完成
|
||
}
|
||
}
|
||
}while (real);
|
||
myfree(databuff);
|
||
myfree(updata);
|
||
}
|
||
|
||
|
||
|
||
|
||
//从接收buff中提取数据,并进行crc校验
|
||
static int SysFile_GetData (u8 *buff,int len)
|
||
{
|
||
u8 crc[2]={0};
|
||
//u8 *buf=mymalloc (256);
|
||
u8 *buf=buff;
|
||
u8 *buf_ptr=0;
|
||
int ret=0;
|
||
int recv_len=len;//usb_getRecvData (buf,256);
|
||
|
||
// //把半个字节的数据整理成一个字节
|
||
// recv_len/=2;
|
||
// for (int i=0;i<recv_len;i++)
|
||
// {
|
||
// buf[i]=(buf[i*2]<<4)|(buf[i*2+1]&0x0f);
|
||
// }
|
||
|
||
if (recv_len>6)
|
||
{
|
||
if (((buf[2]<<8)|buf[3])==recv_len-2)
|
||
{
|
||
buf_ptr=buf+2;
|
||
Get_Crc16 (buf_ptr,recv_len-4,crc);
|
||
if ((crc[0]==buf_ptr[recv_len-2-2])&&(crc[1]==buf_ptr[recv_len-2-1]))
|
||
{
|
||
//crc校验通过,复制有效数据到buff
|
||
mymemcpy (buff,buf_ptr+2,recv_len-6);
|
||
ret=recv_len-6;
|
||
}
|
||
}
|
||
}
|
||
//myfree(buf);
|
||
return ret;
|
||
}
|
||
|
||
|
||
//下载数据时调用这个函数处理
|
||
int cmd_0x01 (SysFile_UpdataStruct *u,u8 *data,int dataLen)
|
||
{
|
||
int ret=-1;
|
||
if (u->step==0x00)
|
||
{
|
||
if (data[0]==0x01)
|
||
{
|
||
if (FLASH_FindFile ((char *)data+1,0)==0)
|
||
{
|
||
u->saveAddr=FLASH_GetUsed();
|
||
mymemcpy (u->name,data+1,dataLen-1);
|
||
u->step=data[0];
|
||
ret=0;
|
||
}
|
||
} else { ret=-1; }
|
||
}
|
||
else if (u->step==0x01)
|
||
{
|
||
if (data[0]==0x02)
|
||
{
|
||
u->dataLen=((data[1]<<24)|(data[2]<<16)|(data[3]<<8)|data[4]);
|
||
//如果文件大小超过限制,这里应该返回失败
|
||
FLASH_CheckErase (u->saveAddr,u->dataLen);
|
||
FLASH_AddFile (u->name,u->saveAddr,u->dataLen);
|
||
u->step=data[0];
|
||
ret=0;
|
||
} else { ret=-2; }
|
||
}
|
||
else if (u->step==0x02)
|
||
{
|
||
if (data[0]==0x03)
|
||
{
|
||
u->packet_all=(data[1]<<8)|data[2];
|
||
u->packet_now=0;
|
||
if (u->packet_now+1==((data[3]<<8)|data[4]) )
|
||
{
|
||
u->packet_now++;
|
||
for (int i=0;i<dataLen-5;i++)
|
||
SysFile_UpdataSaveByte (u,data[5+i]);
|
||
u->step=data[0]; ret=0;} else { ret=-3; }
|
||
} else { ret=-4; }
|
||
}
|
||
else if (u->step==0x03)
|
||
{
|
||
if (data[0]==0x03)
|
||
{
|
||
if (u->packet_all==((data[1]<<8)|data[2]))
|
||
{
|
||
if (u->packet_now+1==((data[3]<<8)|data[4]) )
|
||
{
|
||
u->packet_now++;
|
||
for (int i=0;i<dataLen-5;i++)
|
||
SysFile_UpdataSaveByte (u,data[5+i]);
|
||
if (u->packet_now==u->packet_all)
|
||
{
|
||
//最后一包数据
|
||
FLASH_WriteData(u->dataBuff,u->saveAddr,u->buffUsed);
|
||
u->saveAddr+=u->buffUsed;
|
||
u->buffUsed=0;
|
||
u->step=0x04;
|
||
}
|
||
ret=0;
|
||
} else { ret=-5; }
|
||
} else { ret=-6; }
|
||
} else { ret=-7; }
|
||
} else { ret=-8; }
|
||
return ret;
|
||
}
|
||
|
||
//保存一个字节
|
||
void SysFile_UpdataSaveByte (SysFile_UpdataStruct *u,u8 byte)
|
||
{
|
||
if (u->buffUsed<UPDATA_BUFF_SIZE)
|
||
{
|
||
u->dataBuff[u->buffUsed]=byte;
|
||
u->buffUsed++;
|
||
if (u->buffUsed==UPDATA_BUFF_SIZE)
|
||
{
|
||
FLASH_WriteData(u->dataBuff,u->saveAddr,u->buffUsed);
|
||
u->saveAddr+=u->buffUsed;
|
||
u->buffUsed=0;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//在内存中保存一个字节
|
||
void SysFile_UpdataSaveByteMem (SysFile_UpdataStruct *u,u8 byte)
|
||
{
|
||
u8 *data=(u8 *)u->saveAddr;
|
||
data[u->buffUsed]=byte;
|
||
u->buffUsed++;
|
||
}
|
||
|
||
|
||
|
||
|
||
//这个函数处理下载数据时保存在内存里
|
||
int cmd_0x01_Mem (SysFile_UpdataStruct *u,u8 *data,int dataLen)
|
||
{
|
||
int ret=-1;
|
||
if (u->step==0x00)
|
||
{
|
||
if (data[0]==0x01)
|
||
{
|
||
mymemcpy (u->name,data+1,dataLen-1);
|
||
u->step=data[0];
|
||
ret=0;
|
||
} else { ret=-1; }
|
||
}
|
||
else if (u->step==0x01)
|
||
{
|
||
if (data[0]==0x02)
|
||
{
|
||
u->dataLen=((data[1]<<24)|(data[2]<<16)|(data[3]<<8)|data[4]);
|
||
//如果文件大小超过限制,这里应该返回失败
|
||
if (u->saveAddr=(u32)mymalloc (u->dataLen),u->saveAddr)
|
||
{
|
||
u->buffUsed=0;
|
||
u->step=data[0];
|
||
ret=0;
|
||
}
|
||
else {ret=-1;}
|
||
} else { ret=-2; }
|
||
}
|
||
else if (u->step==0x02)
|
||
{
|
||
if (data[0]==0x03)
|
||
{
|
||
u->packet_all=(data[1]<<8)|data[2];
|
||
u->packet_now=0;
|
||
if (u->packet_now+1==((data[3]<<8)|data[4]) )
|
||
{
|
||
u->packet_now++;
|
||
for (int i=0;i<dataLen-5;i++)
|
||
SysFile_UpdataSaveByteMem (u,data[5+i]);
|
||
u->step=data[0]; ret=0;} else { ret=-3; }
|
||
} else { ret=-4; }
|
||
}
|
||
else if (u->step==0x03)
|
||
{
|
||
if (data[0]==0x03)
|
||
{
|
||
if (u->packet_all==((data[1]<<8)|data[2]))
|
||
{
|
||
if (u->packet_now+1==((data[3]<<8)|data[4]) )
|
||
{
|
||
u->packet_now++;
|
||
for (int i=0;i<dataLen-5;i++)
|
||
SysFile_UpdataSaveByteMem (u,data[5+i]);
|
||
if (u->packet_now==u->packet_all)
|
||
{
|
||
//最后一包数据
|
||
u->step=0x04;
|
||
}
|
||
ret=0;
|
||
} else { ret=-5; }
|
||
} else { ret=-6; }
|
||
} else { ret=-7; }
|
||
} else { ret=-8; }
|
||
return ret;
|
||
}
|
||
|
||
|
||
// 初始化
|
||
int SysFile_SendFileInit(SysFile_SendStruct *send,char *name,char *path,
|
||
int (*send_data)(void *data,int len),int (*progress)(int now,int all))
|
||
{
|
||
mymemset(send,0,sizeof(SysFile_SendStruct));
|
||
send->name=name;
|
||
send->path=path;
|
||
send->send_data=send_data;
|
||
send->progress=progress;
|
||
return 0;
|
||
}
|
||
|
||
|
||
// 发送文件名,返回0成功
|
||
int SysFile_SendFileName(SysFile_SendStruct *send)
|
||
{
|
||
int ret=0;
|
||
u8 *file_mem=mymalloc(SEND_FILE_PACK_MAXSIZE+10);
|
||
u8 *send_pack=mymalloc(SEND_FILE_PACK_MAXSIZE+20);
|
||
|
||
int len=strlen(send->name);
|
||
file_mem[0]=0x01;
|
||
mymemcpy(&file_mem[1],send->name,len);
|
||
int pack_len=SysFile_PackData(send_pack,file_mem,len+1);
|
||
if(send->send_data)ret=send->send_data(send_pack,pack_len);
|
||
else ret=-1;
|
||
myfree(file_mem);
|
||
myfree(send_pack);
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
// 发送文件尺寸,返回0成功
|
||
int SysFile_SendFileInfo(SysFile_SendStruct *send)
|
||
{
|
||
int ret=0;
|
||
u8 *file_mem=mymalloc(SEND_FILE_PACK_MAXSIZE+10);
|
||
u8 *send_pack=mymalloc(SEND_FILE_PACK_MAXSIZE+20);
|
||
FILINFO *file_info=mymalloc(sizeof (FILINFO));
|
||
u8 err=f_stat (send->path,file_info);
|
||
int read_size=0;
|
||
UINT real_size=0;
|
||
if (err==FR_OK)
|
||
{
|
||
send->file_size=file_info->fsize;
|
||
file_mem[0]=0x02;
|
||
file_mem[1]=send->file_size>>24;
|
||
file_mem[2]=send->file_size>>16;
|
||
file_mem[3]=send->file_size>>8;
|
||
file_mem[4]=send->file_size>>0;
|
||
int pack_len=SysFile_PackData(send_pack,file_mem,4+1);
|
||
if(send->send_data) ret=send->send_data(send_pack,pack_len);
|
||
else ret=-1;
|
||
}
|
||
else ret=-1;
|
||
myfree(file_info);
|
||
myfree(file_mem);
|
||
myfree(send_pack);
|
||
return ret;
|
||
}
|
||
|
||
|
||
// 发送文件数据,返回0成功
|
||
int SysFile_SendFileData(SysFile_SendStruct *send)
|
||
{
|
||
int ret;
|
||
u8 err=0;
|
||
FIL *file_fil=mymalloc (sizeof(FIL));
|
||
u8 *file_mem=mymalloc(SEND_FILE_PACK_MAXSIZE+10);
|
||
u8 *send_pack=mymalloc(SEND_FILE_PACK_MAXSIZE+20);
|
||
int read_size=0;
|
||
UINT real_size=0;
|
||
if (err==FR_OK)
|
||
{
|
||
send->size_left=send->file_size;
|
||
send->packet_all=send->file_size/SEND_FILE_PACK_MAXSIZE;
|
||
if(send->file_size%SEND_FILE_PACK_MAXSIZE)
|
||
send->packet_all++;
|
||
f_open(file_fil,send->path,FA_READ);
|
||
while(send->size_left)
|
||
{
|
||
if (send->size_left>SEND_FILE_PACK_MAXSIZE)
|
||
{
|
||
read_size=SEND_FILE_PACK_MAXSIZE;
|
||
}
|
||
else
|
||
{
|
||
read_size=send->size_left;
|
||
}
|
||
|
||
send->packet_now++;
|
||
file_mem[0]=0x03;
|
||
file_mem[1]=send->packet_all>>8;
|
||
file_mem[2]=send->packet_all;
|
||
file_mem[3]=send->packet_now>>8;
|
||
file_mem[4]=send->packet_now;
|
||
f_read (file_fil,file_mem+5,read_size,&real_size);
|
||
|
||
int pack_len=SysFile_PackData(send_pack,file_mem,real_size+5);
|
||
if(send->send_data) ret=send->send_data(send_pack,pack_len);
|
||
else ret=-1;
|
||
if(ret!=0) break;
|
||
if(send->progress) send->progress(send->packet_now,send->packet_all);
|
||
send->size_left-=read_size;
|
||
}
|
||
f_close(file_fil);
|
||
}
|
||
else ret=-1;
|
||
myfree(file_fil);
|
||
myfree(file_mem);
|
||
myfree(send_pack);
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// 打包,成功打包后的数据长度
|
||
int SysFile_PackData(u8 *out,u8 *in,int in_size)
|
||
{
|
||
if(out==0||in==0) return 0;
|
||
if(in_size==0) return 0;
|
||
u8 crc[2]={0};
|
||
|
||
out[0]=0xff;
|
||
out[1]=0xff;
|
||
out[2]=(in_size+5)>>8;
|
||
out[3]=(in_size+5);
|
||
out[4]=0x01;
|
||
mymemcpy(&out[5],in,in_size);
|
||
Get_Crc16 (&out[2],in_size+3,crc);
|
||
out[5+in_size]=crc[0];
|
||
out[5+in_size+1]=crc[1];
|
||
return 5+in_size+2;
|
||
}
|
||
|