|
【开源】对迪文屏的数据文件实现在线升级的一种方法 1.背景介绍:
目前迪文屏升级一共有两种方式:插卡和上位机通过串口升级,两者不足之处有:
(1)批量生产升级效率慢且繁琐(当升级时,每个设备需要单独去插卡或者用电脑上位机升级) ,并且增加了人工成本。
(2)自己的项目中无法实现对迪文屏在线升级(当产品已发出需要修复BUG时,无法在线修复)。
(3)无法判断新老版本(当数据文件没有变化时执行了重复升级)。
2.方案设计:
基于以上不足,通过在自己的项目中嵌套一种方法实现对迪文屏数据文件的升级,弥补以上的不足。
实现效果的视频链接 https://b23.tv/3jOTtOW
3.以下是部分程序实现流程
/**
@brief 获取norflash和本地文件夹的版本号以及通过文件名称前面的序号计算出外部flash更新的以32K BYTE为单位的地址
@param pUpgradeDgus UpgradeDgus_t 结构体指针
@return 无
*/
void get_VersionAnd32KByteAddr_ByFileName(UpgradeDgus_t *pUpgradeDgus)
{
int i=0;
uint8_t fileBuff[256];
uint8_t readNorFlashBuff[DGUS_USER_DEFINE_VERSION_NORFLASH_SIZE];
char *pstr=NULL;
char *str=NULL;
char numStr[5];
memset(numStr,0,sizeof(numStr));
for(i=0;i<2;i++)//取文件序号
{
if(pUpgradeDgus->File<=0x39&&pUpgradeDgus->File>=0x30)
{
numStr = pUpgradeDgus->File;
}
}
pUpgradeDgus->addrTo32KBytes = atoi(numStr);
pUpgradeDgus->addrTo32KBytes*=256;
pUpgradeDgus->addrTo32KBytes/=32;//计算要存放外部flash的位置
pstr = strstr(pUpgradeDgus->File,USER_DEFINE_VERSION_KEY_WORD);
str = strstr(pUpgradeDgus->File,".");
if(str!=NULL&&pstr!=NULL)
{
strncpy(pUpgradeDgus->CurrVer,pstr,str-pstr);
}
readDgusNorFlash_ByAddr(DGUS_USER_RAM_ADDR,DGUS_NOR_FLASH_ADDR,DGUS_USER_DEFINE_VERSION_NORFLASH_SIZE/2);//从NorFlash中读老版本到DGUS RAM
Dgus_Dealyms(100);
readDgusRam_ByAddr(DGUS_USER_RAM_ADDR,readNorFlashBuff,DGUS_USER_DEFINE_VERSION_NORFLASH_SIZE);//从DGUS RAM取出数据
//下面主要是取版本号的操作
if(strstr((char *)readNorFlashBuff,pstr)==NULL)
{
memset(fileBuff,0,sizeof(fileBuff));
pstr = strstr(pUpgradeDgus->File,USER_DEFINE_VERSION_KEY_WORD);
strncpy((char *)fileBuff,pUpgradeDgus->File,pstr - pUpgradeDgus->File);
strcat((char *)fileBuff,USER_DEFINE_VERSION_KEY_WORD);
pstr = strstr((char *)readNorFlashBuff,(char *)fileBuff);
if(pstr!=NULL)
{
str = (char *)readNorFlashBuff + (pstr - (char *)readNorFlashBuff);
pstr = strstr(str,".");
memset(fileBuff,0,sizeof(fileBuff));
if(pstr!=NULL)
{
strncpy((char *)fileBuff,str,pstr-str);
pstr = strstr((char *)fileBuff,USER_DEFINE_VERSION_KEY_WORD);
if(pstr!=NULL)
{
strcpy(pUpgradeDgus->LasTVer,pstr);
}
}
}
else
{
strcpy(pUpgradeDgus->LasTVer," ");
}
}
else
{
pstr = strstr((char *)readNorFlashBuff,pUpgradeDgus->File);
if(pstr!=NULL)
{
str = (char *)readNorFlashBuff + (pstr - (char *)readNorFlashBuff);
pstr = strstr(str,".");
memset(fileBuff,0,sizeof(fileBuff));
if(pstr!=NULL)
{
strncpy((char *)fileBuff,str,pstr-str);
pstr = strstr((char *)fileBuff,USER_DEFINE_VERSION_KEY_WORD);
if(pstr!=NULL)
{
strcpy(pUpgradeDgus->LasTVer,pstr);
}
}
}
}
}
/**
@brief 将一个文件升级到DGUS 外部FLASH指定位置
pUpgradeDgus UpgradeDgus_t 结构体指针
@return false / true
*/
bool upgradeFiles(UpgradeDgus_t *pUpgradeDgus)
{
FIL dgusFile;
FRESULT uRet;
char filePath[256];
UINT br;
uint16_t addrTo32KBytes=0;
uint8_t readBuff[32*1024];
memset(filePath,0,sizeof(filePath));
strcpy(filePath,DWIN_SET_PASTH);
strcat(filePath,pUpgradeDgus->File);
uRet = f_open(&dgusFile,filePath,FA_READ);
addrTo32KBytes = pUpgradeDgus->addrTo32KBytes;
if(!uRet)
{
DGUS_ShowStrDesctibe_t Desctibe;
Desctibe.textAddr = 0x1800;
Desctibe.textColor = 0x00;
Desctibe.font0Id=0;
Desctibe.font1Id=7;
Desctibe.fontXDots = 24;
Desctibe.fontYDots = 26;
Desctibe.encodeMode = 0xC0; //居中对齐,8bit编码
Desctibe.HorDis=2;
Desctibe.VerDis=1;
show_StrInit(&Desctibe,0x8000);
show_StrByAddr(Desctibe.textAddr,filePath,100);
while(1)
{
memset(readBuff,0,sizeof(readBuff));
uRet = f_read(&dgusFile,readBuff,sizeof(readBuff),&br);
if(!uRet)
{
writeDgusRam_ByAddr(DGUS_USER_RAM_ADDR,(uint8_t *)readBuff,sizeof(readBuff));
writeDgussFlash_ByAddr(DGUS_USER_RAM_ADDR,addrTo32KBytes,5);
addrTo32KBytes++;
if(br<sizeof(readBuff))
break;
}
else
{
return false;
}
}
return true;
}
return false;
}
/**
@brief 升级DGUS除内核以外的所有数据文件
@param dgusFilePath DWIN_SET的路径
@return 无
*/
void upgradeDgusFiles(char* dgusFilePath)
{
int i=0;
char *pstr=NULL;
uint16_t isUpgradeCount=0;
uint16_t okFileCount=0;
uint16_t Len=0;
uint16_t outPathLen=0;
char strBuff[256];
char outFileBuff[1024];
char fileVersionBuff[DGUS_USER_DEFINE_VERSION_NORFLASH_SIZE];
uint16_t fileNum=0;
memset(outFileBuff,0,sizeof(outFileBuff));
get_DgusDirsFileName(dgusFilePath,outFileBuff,&fileNum);
outPathLen=0;
okFileCount=0;
for(i=0;i<fileNum;i++)
{
Len=strlen(outFileBuff+outPathLen)+1;
strcpy(UpgradeDgus[okFileCount].File,outFileBuff+outPathLen);
outPathLen+=Len;
if(checkFileName(UpgradeDgus[okFileCount].File))
okFileCount++;
}
for(i=0;i<okFileCount;i++)
{
get_VersionAnd32KByteAddr_ByFileName(&UpgradeDgus);
}
isUpgradeCount=0;
memset(fileVersionBuff,0,sizeof(fileVersionBuff));
for(i=0;i<okFileCount;i++)
{
if(strcmp(UpgradeDgus.CurrVer,UpgradeDgus.LasTVer)!=0)
{
//需要升级
show_JumpPageById(0x0001);
strcat(fileVersionBuff,UpgradeDgus.File);
upgradeFiles(&UpgradeDgus);
isUpgradeCount++;
}
else
{
memset(strBuff,0,sizeof(strBuff));
pstr = strstr(UpgradeDgus.File,USER_DEFINE_VERSION_KEY_WORD);
strncpy(strBuff,UpgradeDgus.File,pstr - UpgradeDgus.File );
strcat(strBuff,UpgradeDgus.LasTVer);
strcat(strBuff,strstr(UpgradeDgus.File,"."));
strcat(fileVersionBuff,strBuff);
}
}
if(isUpgradeCount!=0)
{
writeDgusRam_ByAddr(DGUS_USER_RAM_ADDR,(uint8_t *)fileVersionBuff,DGUS_USER_DEFINE_VERSION_NORFLASH_SIZE);
writeDgusNorFlash_ByAddr(DGUS_USER_RAM_ADDR,DGUS_NOR_FLASH_ADDR,DGUS_USER_DEFINE_VERSION_NORFLASH_SIZE);
Dgus_Dealyms(100);
resetDgus();//复位Dgus
Dgus_Dealyms(DGUS_RESET_DELAY);
NVIC_SystemReset();//mcu复位
}
else
{
show_JumpPageById(0x0001);
DGUS_ShowStrDesctibe_t Desctibe;
Desctibe.textAddr = 0x1800;
Desctibe.textColor = 0x00;
Desctibe.font0Id=0;
Desctibe.font1Id=7;
Desctibe.fontXDots = 24;
Desctibe.fontYDots = 26;
Desctibe.encodeMode = 0xC0; //居中对齐,8bit编码
Desctibe.HorDis=2;
Desctibe.VerDis=1;
show_StrInit(&Desctibe,0x8000);
show_StrByAddr(Desctibe.textAddr,"No files need to be upgraded",100);
}
}
备注说明:如需源码,请参考此链接:http://inforum.dwin.com.cn:20080/forum.php?mod=viewthread&tid=6361&_dsign=858504a2
|
|