Files
player/Project/Src/MyApp/system_updata.c

561 lines
13 KiB
C
Raw Normal View History

2025-06-27 00:32:57 +08:00
#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;
u32 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;
}