#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;i6) { 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;istep=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;ipacket_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->buffUseddataBuff[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;istep=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;ipacket_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; }