diff --git a/HARDWARE/LTE/EC20/ec20ftp.c b/HARDWARE/LTE/EC20/ec20ftp.c index 8bb187e..f2357e7 100644 --- a/HARDWARE/LTE/EC20/ec20ftp.c +++ b/HARDWARE/LTE/EC20/ec20ftp.c @@ -303,28 +303,28 @@ int Ftp_Down_File( uint8_t *fileName, uint32_t startPos, uint16_t transLen) Ec20FtpBufReset() ; //FTP接收缓冲区初始化 UARTx_SendString(EC20_UART, (uint8_t *)sFtpCmd[DOWNFILE].cmdStr, fileName, startPos, transLen ) ; while( revTimes++ < sFtpCmd[DOWNFILE].timeout ) - { - Wait_For_Nms(10) ; - headPos = kmp(ec20FtpBuf, "CONNECT")+9 ; //下载的文件数据开始的地方相对用户数据开始处 在ec20FtpBuf中的偏移量 - sFtpCmd[DOWNFILE].trueOffset = kmp(&ec20FtpBuf[transLen+headPos], sFtpCmd[DOWNFILE].trueStr) ; //+QFTPGET: 0,2048在相对用户数据结尾处 在ec20FtpBuf中的偏移量 - if( sFtpCmd[DOWNFILE].trueOffset == 0) - { - if( headPos >= 0 ) //CONNECT和+QFTPGET: 0,2048之间的字节数 是否正常 - { - break ; - } - else - { - headPos = -1 ; - break ; - } - } - else if( kmp(ec20FtpBuf, sFtpCmd[DOWNFILE].falseStr) >= 0) + { + Wait_For_Nms(10) ; + headPos = kmp(ec20FtpBuf, "CONNECT")+9 ; //下载的文件数据开始的地方相对用户数据开始处 在ec20FtpBuf中的偏移量 + sFtpCmd[DOWNFILE].trueOffset = kmp(&ec20FtpBuf[transLen+headPos], sFtpCmd[DOWNFILE].trueStr) ; //+QFTPGET: 0,2048在相对用户数据结尾处 在ec20FtpBuf中的偏移量 + if( sFtpCmd[DOWNFILE].trueOffset == 0) + { + if( headPos >= 0 ) //CONNECT和+QFTPGET: 0,2048之间的字节数 是否正常 { - headPos = -1 ; - break ; + break ; } - } + else + { + headPos = -1 ; + break ; + } + } + else if( kmp(ec20FtpBuf, sFtpCmd[DOWNFILE].falseStr) >= 0) + { + headPos = -1 ; + break ; + } + } ftpDataMode = false ; //EC20串口接收模式切出FTP模式 return (headPos) ; } diff --git a/SYSTEM/FLASH/flash.c b/SYSTEM/FLASH/flash.c index a1876bd..6535993 100644 --- a/SYSTEM/FLASH/flash.c +++ b/SYSTEM/FLASH/flash.c @@ -245,7 +245,7 @@ RunResult Write_Flash(uint32_t writeAddr, uint8_t *writeBuf, uint16_t writeLen) FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);//清标志位 for( timeOut=0; (SET == FLASH_GetFlagStatus(FLASH_FLAG_BSY)); timeOut++) { - Wait_For_Nms(10) ; + Wait_For_Nms(50) ; if( timeOut>10 ) { SysErr("") ; //写Flash出错! diff --git a/SYSTEM/USART/usart.c b/SYSTEM/USART/usart.c index d00e165..4e80561 100644 --- a/SYSTEM/USART/usart.c +++ b/SYSTEM/USART/usart.c @@ -123,8 +123,8 @@ void _ttywrch(int ch) int fputc(int ch, FILE *f)//重定义fputc函数 { - UARTx_COM[UART_DEBUG]->DR = (u8) ch; - while(( UARTx_COM[UART_DEBUG]->SR & 0X40 ) == 0) ;//循环发送,直到发送完毕 TC + // UARTx_COM[UART_DEBUG]->DR = (u8) ch; + // while(( UARTx_COM[UART_DEBUG]->SR & 0X40 ) == 0) ;//循环发送,直到发送完毕 TC return ch; } #endif diff --git a/SYSTEM/USART/usart.h b/SYSTEM/USART/usart.h index 6fc1ddb..a6c521a 100644 --- a/SYSTEM/USART/usart.h +++ b/SYSTEM/USART/usart.h @@ -20,7 +20,7 @@ ****************************************************************************/ #define UART_DEBUG COM5 //log输出重定向 #define UARTx_DMATX_EN 1 //uart1`uart4可以选择是否通过串口DMA发送数据 -#define UART1_DMA_RX_MAXLEN 256 //串口1 DMA接收一帧数据的最大长度 +#define UART1_DMA_RX_MAXLEN 2560 //串口1 DMA接收一帧数据的最大长度 #define UART2_DMA_RX_MAXLEN 256 //串口2 DMA接收一帧数据的最大长度 #define UART3_DMA_RX_MAXLEN (1024*3) //串口3 DMA接收一帧数据的最大长度 #define UART4_DMA_RX_MAXLEN 256 //串口4 DMA接收一帧数据的最大长度 diff --git a/USER/IAP/iap.c b/USER/IAP/iap.c index 8c424ec..1817068 100644 --- a/USER/IAP/iap.c +++ b/USER/IAP/iap.c @@ -50,7 +50,7 @@ RUNAPP1: if((addr == (APP1_AREA_ADDR & 0xFFFF0000)) } case 0x00000032: case APP2_AREA_ADDR: { - if( ((*(vu32*)(APP2_AREA_ADDR+4))&0xFFFF0000) == (APP2_AREA_ADDR & 0xFFFF0000)) //校验存储在FLASH中的固件合法 + if( ((*(vu32*)(APP2_AREA_ADDR+4))&0xFFFF0000) >= (APP2_AREA_ADDR & 0xFFFF0000)) //校验存储在FLASH中的固件合法 { TcpUpdata( BOOTTOTCPFRAME, "开始执行APP2用户代码!") ; appAddr = APP2_AREA_ADDR ; diff --git a/USER/USERAPP/userapp.c b/USER/USERAPP/userapp.c index 07d67d1..d08eb28 100644 --- a/USER/USERAPP/userapp.c +++ b/USER/USERAPP/userapp.c @@ -153,21 +153,21 @@ RunResult DownSubpackVerify(DownFileP_s *psFileParm, int *pHeadPos) RunResult result = RUNERR ; *pHeadPos = Ftp_Down_File(psFileParm->fileName, 0, ONCE_DOWN_LEN) ; //下载第一个子包 if( *pHeadPos >= 0 ) /*下载数据成功*/ - { - psFileParm->appFlashAddr = Check_AppNum(*(vu32*)((u32)&ec20FtpBuf[*pHeadPos+4])) ; //检查APP中的栈顶地址是否符合APP2\APP3 - if( psFileParm->appFlashAddr != 0) // 固件校验合法 - { - result = RUNOK ; - } - else //固件校验失败 - { - result = RUNERR ; - } + { + psFileParm->appFlashAddr = Check_AppNum(*(vu32*)((u32)&ec20FtpBuf[*pHeadPos+4])) ; //检查APP中的栈顶地址是否符合APP2\APP3 + if( psFileParm->appFlashAddr != 0) // 固件校验合法 + { + result = RUNOK ; } + else //固件校验失败 + { + result = RUNERR ; + } + } else - { - result = TIMEOUT ; - } + { + result = TIMEOUT ; + } return (result) ; } @@ -186,9 +186,7 @@ RunResult DownOtherSubpack(DownFileP_s *psFileParm) int headPos ; for( psFileParm->subPackNum = 2; psFileParm->subPackNum <= psFileParm->subPackSum; psFileParm->subPackNum++ ) //从第2个包开始,采用循环下载 { - OledPrintf(LINE_LEFT, HIGH_16, LINE4, false, "下载子包:%d", psFileParm->subPackNum ) ; - Data_Led_Reverse() ; - Wait_For_Nms(5) ; + Wait_For_Nms(50) ; uint16_t downLen = ONCE_DOWN_LEN ; //本次下载数据的长度 if( psFileParm->subPackNum == psFileParm->subPackSum ) /*下载最后一个包,下载数据长度需要重新计算*/ { diff --git a/USER/USERCMD/usercmd.h b/USER/USERCMD/usercmd.h index 52ab148..2dec32e 100644 --- a/USER/USERCMD/usercmd.h +++ b/USER/USERCMD/usercmd.h @@ -19,7 +19,7 @@ /*配置:参数控制*/ #define IS_IapFlag_ALL_PERIPH(PERIPH) (((PERIPH) == 0x30) || \ ((PERIPH) == 0x31) ) //IAPConfig_s结构体中IapFlag参数校验 - + #define IS_RunAppNum_ALL_PERIPH(PERIPH) (((PERIPH) == 0x30) || \ ((PERIPH) == 0x31) || \ ((PERIPH) == 0x32) || \ diff --git a/USER/USER_TCP/user_tcp.c b/USER/USER_TCP/user_tcp.c index 6d26b4e..f44c083 100644 --- a/USER/USER_TCP/user_tcp.c +++ b/USER/USER_TCP/user_tcp.c @@ -42,7 +42,7 @@ ChannalP_s sChannal0 = { TCP_CONNECTID0, TCP_CONNECTID0_SERVERIP0, TCP_CONNECTID * 功能说明: 设置登TCP服务器的IP **************************************************************************************************/ void SetAppTcpIP(ChannalP_s *psChannal, char* ip) -{ +{ memset(psChannal->serverIP , 0, MAX_IP_LEN ) ; strcpy((char*)psChannal->serverIP, ip) ; } diff --git a/USER/main.c b/USER/main.c index 623e9d4..c201ed9 100644 --- a/USER/main.c +++ b/USER/main.c @@ -43,29 +43,27 @@ int main(void) Board_Init() ; //硬件驱动初始化和功能块初始化 Watchdog_Feed() ; //看门狗喂狗 +/*强制升级检测、开始变砖检测修复 ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼*/ + if( (uIapFlash.sIapFlash.JumpResult == 0x30) ) // 跳转失败或者按键操作进入恢复模式,则运行应急程序 + { + DisplayInfo("执行应急程序") ; + goto SAVEAPPOUT ; //跳转到应急程序运行 + } + else //跳转APP未出现失败,设置标志位jumpResult为暂未跳转成功状 + { + uIapFlash.sIapFlash.JumpResult = 0x30 ; //复位JumpResult标志位 + Set_uIapFlash(&uIapFlash) ; //保存JumpResult + } - /* -/*强制升级检测、开始变砖检测修复 ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ - if( (uIapFlash.sIapFlash.JumpResult == 0x30) ) /*跳转失败或者按键操作进入恢复模式,则运行应急程序 - { - DisplayInfo("执行应急程序") ; - Wait_For_Nms(20) ; //延时2S用于显示屏显示(实际项目可以屏蔽延时) - goto SAVEAPPOUT ; //跳转到应急程序运行 - } - else /*跳转APP未出现失败,设置标志位jumpResult为暂未跳转成功状 - { - uIapFlash.sIapFlash.JumpResult = 0x30 ; //复位JumpResult标志位 - Set_uIapFlash(&uIapFlash) ; //保存JumpResult - } - */ /*结束变砖检测修复、强制升级检测*/ /*开始检测是否需要升级APP(即判断IapFlag标志位)▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼*/ - if( true == IS_IapFlag_ALL_PERIPH(uIapFlash.sIapFlash.IapFlag) ) /*IapFlag合法*/ //IapFlag标志位合法性校验 + if(true == IS_IapFlag_ALL_PERIPH(uIapFlash.sIapFlash.IapFlag)) /*IapFlag合法*/ //IapFlag标志位合法性校验 { if(uIapFlash.sIapFlash.IapFlag == 0x30 ) /*升级标志位为‘0’, 说明不需要升级,直接跳转即可*/ { - // AppLogPrintf("无需升级,即将执行APP%c .", uIapFlash.sIapFlash.RunAppNum) ; + AppLogPrintf("无需升级,即将执行APP%c .", uIapFlash.sIapFlash.RunAppNum) ; + goto APPNUMOUT ; //跳转到RunAppNum,执行原先的程序 } } @@ -84,36 +82,36 @@ int main(void) /*∧∧网络连接开始∧∧∧∧∧∧∧∧∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨*/ result = NetTask() ; //网络初始化 - if( RUNERR == result ) /*TCP\FTP初始化、连接失败 */ - { - DisplayInfo("FTP连接失败") ; - TcpUpdata( BOOTTOTCPFRAME, "FTP初始化失败,即将跳转RunAppNum: APP%c!", uIapFlash.sIapFlash.RunAppNum) ; - Wait_For_Nms(20) ; //延时2S用于显示屏显示(实际项目可以屏蔽延时) - goto APPNUMOUT ; //跳转到RunAppNum,执行原先的程序 - } + if(RUNERR == result) /*TCP\FTP初始化、连接失败 */ + { + DisplayInfo("FTP连接失败") ; + TcpUpdata( BOOTTOTCPFRAME, "FTP初始化失败,即将跳转RunAppNum: APP%c!", uIapFlash.sIapFlash.RunAppNum) ; + Wait_For_Nms(20) ; //延时2S用于显示屏显示(实际项目可以屏蔽延时) + goto APPNUMOUT ; //跳转到RunAppNum,执行原先的程序 + } /*∧∧网络连接结束∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧*/ /*∨∨查找新固件开始∨∨∨∨∨∨∨∧∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨*/ TcpUpdata( BOOTTOTCPFRAME, "FTP初始化成功,即将开始升级!") ; Watchdog_Feed() ; //看门狗喂狗 result = FindAppFile(&sDownApp) ; //查找新固件 - if( RUNERR == result ) /*未找到新固件*/ - { - TcpUpdata( BOOTTOTCPFRAME, "未搜索到新固件,即将跳转RunAppNum: APP%c!", uIapFlash.sIapFlash.RunAppNum) ; - Wait_For_Nms(200) ; //延时2S用于显示屏显示(实际项目可以屏蔽延时) - goto APPNUMOUT ; //跳转到RunAppNum,执行原先的程序 - } + if(RUNERR == result) /*未找到新固件*/ + { + TcpUpdata( BOOTTOTCPFRAME, "未搜索到新固件,即将跳转RunAppNum: APP%c!", uIapFlash.sIapFlash.RunAppNum) ; + Wait_For_Nms(200) ; //延时2S用于显示屏显示(实际项目可以屏蔽延时) + goto APPNUMOUT ; //跳转到RunAppNum,执行原先的程序 + } /*∧∧查找新固件结束∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧*/ /*∨∨获取新固件文件大小开始∨∨∨∨∨∨∨∧∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨*/ sDownApp.fileSize = Ftp_Get_FileSize( sDownApp.fileName ) ; //获取新固件文件的大小 - if( sDownApp.fileSize <= 0 ) /*获取文件大小失败*/ - { - TcpUpdata( BOOTTOTCPFRAME, "获取新固件大小失败,即将跳转RunAppNum: APP%c!", uIapFlash.sIapFlash.RunAppNum) ; - goto APPNUMOUT ; //跳转到RunAppNum,执行原先的程序 - } + if(sDownApp.fileSize <= 0) /*获取文件大小失败*/ + { + TcpUpdata( BOOTTOTCPFRAME, "获取新固件大小失败,即将跳转RunAppNum: APP%c!", uIapFlash.sIapFlash.RunAppNum) ; + goto APPNUMOUT ; //跳转到RunAppNum,执行原先的程序 + } sDownApp.subPackSum = sDownApp.fileSize/ONCE_DOWN_LEN ; - if( sDownApp.fileSize%ONCE_DOWN_LEN > 0 ) + if(sDownApp.fileSize%ONCE_DOWN_LEN > 0) sDownApp.subPackSum = sDownApp.subPackSum + 1 ; //计算固件subPackSum TcpUpdata( BOOTTOTCPFRAME, "新固件包大小 %d bytes ; 拆分子包数目: %d 。",sDownApp.fileSize, sDownApp.subPackSum) ; /*∧∧获取新固件文件大小结束∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧*/ @@ -121,9 +119,9 @@ int main(void) /*∨∨新固件合法性校验开始∨∨∨∨∨∨∨∧∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨*/ int headPos = -1 ; result = DownSubpackVerify(&sDownApp, &headPos) ; //下载第一个subpack并进行固件合法性校验 - if( RUNERR == result ) /*固件校验不合法”*/ - { - TcpUpdata( BOOTTOTCPFRAME, "新固件栈顶地址校验失败!") ; + if(RUNERR == result) /*固件校验不合法”*/ + { + TcpUpdata( BOOTTOTCPFRAME, "新固件栈顶地址校验失败!") ; // char *newName = (char*)portMalloc(MAC_BYTES_LEN*2) ; // strncat( (char*)newName, (const char*)sDownApp.fileName, 2) ; // strncat( (char*)newName, "(BinErr)", 8) ; @@ -131,9 +129,9 @@ int main(void) // Wait_For_Nms(2000) ; //延时2S用于修改文件名(实测发现在下载完数据后立即更名,会返回+CME ERROR: 603错误) // Ftp_File_Rename( sDownApp.fileName , (uint8_t *)newName ) ; //对不合法的固件进行重名了, 防止二次升级 // portFree(newName) ; - goto APPNUMOUT ; // 跳转到RunAppNum,执行原先的程序 - } - else if( TIMEOUT == result ) /*固件校验失败*/ + goto APPNUMOUT ; // 跳转到RunAppNum,执行原先的程序 + } + else if(TIMEOUT == result) /*固件校验失败*/ { TcpUpdata( BOOTTOTCPFRAME, "新固件栈顶地址校验超时!") ; Wait_For_Nms(50) ; //延时2S用于显示屏显示(实际项目可以屏蔽延时) @@ -141,9 +139,7 @@ int main(void) } /*∧∧新固件合法性校验结束∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧*/ -/*∨∨下载新固件并写FLASH 开始∨∨∨∨∨∨∨∧∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨*/ - // OledPrintf(LINE_LEFT, HIGH_16, LINE3, false, "总子包数:%d", sDownApp.subPackSum) ; - // OledPrintf(LINE_LEFT, HIGH_16, LINE4, false, "下载子包:1" ) ; + Erase_App_Area(sDownApp.appFlashAddr) ; //擦除相应代码段准备将新的代码写入FLASH,此时该APP段已经不可用了,如果后续出现下载/写入FLASH错误,需要跳转到应急程序 TcpUpdata( BOOTTOTCPFRAME, "子包:1 。下载成功!") ; if( RUNOK == Write_Flash(sDownApp.appFlashAddr, (uint8_t*)(ec20FtpBuf+headPos), ONCE_DOWN_LEN)) /*写FLASH成功*///将上一步下载的subpack1写入falsh中 @@ -179,14 +175,14 @@ int main(void) /*∧∧下载新固件并写FLASH 结束∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧∧*/ APPNUMOUT: - - appAddr = QueryNewAppArea((u32)uIapFlash.sIapFlash.RunAppNum); //校验固件合法性、获取跳转的FLASH存放区域首地址 + appAddr = QueryNewAppArea(0x32); //校验固件合法性、获取跳转的FLASH存放区域首地址 + // appAddr = QueryNewAppArea((u32)uIapFlash.sIapFlash.RunAppNum); //校验固件合法性、获取跳转的FLASH存放区域首地址 NetDisconnetc() ; //断开网络连接,注销FTP登陆 Iap_Load_App(appAddr) ; //执行APP,不会再往下执行了 NEWAPPOUT: - uIapFlash.sIapFlash.IapFlag = 0x30 ; //清除升级标志位 + uIapFlash.sIapFlash.IapFlag = 0x32 ; //清除升级标志位 Set_uIapFlash(&uIapFlash) ; appAddr = QueryNewAppArea(sDownApp.appFlashAddr); //校验固件合法性、获取跳转的FLASH存放区域首地址 NetDisconnetc() ; //断开网络连接,注销FTP登陆