Files
player/Project/Src/MyApp/system_updata.c
2025-07-05 19:47:28 +08:00

561 lines
13 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 "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;
}