迪文科技论坛

 找回密码
 立即注册
搜索
查看: 5431|回复: 24

【开源】对迪文屏的数据文件实现在线升级的一种方法

[复制链接]

3

主题

38

回帖

447

积分

中级会员

Rank: 3Rank: 3

积分
447
发表于 2022-7-17 20:55:10 | 显示全部楼层 |阅读模式
背景:
目前迪文屏升级一共有两种方式:插卡和上位机通过串口升级,两者不足之处有 :1、批量生产升级效率慢且繁琐(当升级时,每个设备需要单独去插卡或者用电脑上位机升级) ,并且增加了人工成本。2、自己的项目中无法实现对迪文屏在线升级(当产品已发出需要修复BUG时,无法在线修复)。3、无法判断新老版本(当数据文件没有变化时执行了重复升级)。
设计:
基于以上不足,通过在自己的项目中嵌套一种方法实现对迪文屏数据文件的升级,弥补以上的不足。

实现效果的视频链接 https://b23.tv/3jOTtOW

以下是部分实现流程,具体请点击下载项目工程进行参考

/**
@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);               
        }
}





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0

主题

347

回帖

2036

积分

金牌会员

Rank: 6Rank: 6

积分
2036
发表于 2022-7-18 10:04:29 | 显示全部楼层
感谢楼主分享,赞一个
回复

使用道具 举报

0

主题

857

回帖

5102

积分

论坛元老

Rank: 8Rank: 8

积分
5102
发表于 2022-7-18 10:04:37 | 显示全部楼层
非常不错,顶一个!
回复

使用道具 举报

0

主题

8

回帖

629

积分

高级会员

Rank: 4

积分
629
发表于 2022-7-18 10:28:02 | 显示全部楼层
感谢楼主分享
回复

使用道具 举报

9

主题

113

回帖

3339

积分

论坛元老

Rank: 8Rank: 8

积分
3339
发表于 2022-7-18 10:55:50 | 显示全部楼层
感谢楼主分享
回复

使用道具 举报

3

主题

38

回帖

447

积分

中级会员

Rank: 3Rank: 3

积分
447
 楼主| 发表于 2022-7-18 16:17:59 | 显示全部楼层
后续测试发现有丢数据的现象,原因在于写的时候没有延时,因此需要改动一下
                                        writeDgusRam_ByAddr(DGUS_USER_RAM_ADDR,(uint8_t *)readBuff,sizeof(readBuff));
                                        writeDgussFlash_ByAddr(DGUS_USER_RAM_ADDR,addrTo32KBytes,50);
                                        Dgus_Dealyms(50);这几段代码改成这样就好了
回复

使用道具 举报

3

主题

38

回帖

447

积分

中级会员

Rank: 3Rank: 3

积分
447
 楼主| 发表于 2022-7-18 16:28:53 | 显示全部楼层
其实最严谨的做法应该把已经写入迪文屏外部flash中的数据以32K BYTE为单位再读回来与写入的数据做一下比较或者开启CRC校验,但是这样会影响会影响升级的速度
回复

使用道具 举报

3

主题

38

回帖

447

积分

中级会员

Rank: 3Rank: 3

积分
447
 楼主| 发表于 2022-7-18 21:26:50 | 显示全部楼层

大家一起共同进步
回复

使用道具 举报

3

主题

38

回帖

447

积分

中级会员

Rank: 3Rank: 3

积分
447
 楼主| 发表于 2022-7-18 21:28:40 | 显示全部楼层
DWIN_LZ 发表于 2022-7-18 10:04
非常不错,顶一个!

感谢支持
回复

使用道具 举报

3

主题

38

回帖

447

积分

中级会员

Rank: 3Rank: 3

积分
447
 楼主| 发表于 2022-7-18 21:30:05 | 显示全部楼层
wangyuxiang 发表于 2022-7-18 10:04
感谢楼主分享,赞一个

感谢宝子们的支持
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2024-7-27 21:34 , Processed in 0.139524 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表