123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- #include "mcuIap.h"
- #include "mallocSw.h"
- #include "ticket.h"
- #include "mcu.h"
- #include "crc.h"
- /*
- 业务逻辑
- 本应用在启动后的前N秒内只运行通用队列任务,且检测本地参数MCUIAPFLAG
- MCUIAPFLAG:1 则需要进行MCU升级流程,进入逻辑A
- MCUIAPFLAG:0 不需要进行MCU升级流程,进入逻辑B
- 逻辑A:
- 则会定时发APP_DOWNLOAD指令检测是否有MCU响应文件请求,如果有,则进入
- MCU的IAP升级APP逻辑,如果收到MCU响应升级完成 ,则复位MCUIAPFLAG;
- 如果没有,则执行正常的逻辑业务
- 逻辑B:
- 则会定时发检测MCU的版本号指令,如果检测到与应用中的MCU版本一致,则执
- 行正常的逻辑业务;如果不一致,则发一条指令(+FOTA:MCUIAP未定)到串口,同时
- 置位MCUIAPFLAG,同时等待被MCU复位,如果超时N秒还没有被复位,则复位
- MCUIAPFLAG,直接执行正常的业务逻辑
- 当超时N秒,如果MCUIAPFLAG已置位,则复位之,然后执行正常的业务逻辑
- MCU部份:
- APP:APP添加响应MCU版本指令以及+FOTA:MCUIAP指令,收到+FOTA:MCUIAP指令
- 后,将参数中的FOTAMODEM置位,然后马上复位MCU。
- IAP:IAP启动后,检测FOTAMODEM状态
- FOTAMODEM复位状态:按原来逻辑运行
- FOTAMODEM置位状态:先启动模块(同时考虑复位FOTAMODEM),然后运行原来的
- 逻辑,但在升级APP完成后,回发一条升级完成的指令给串口,让本应用复位
- MCUIAPFLAG
- */
- #define MIAP_TRIGGER_INFO "<<DOWNLOAD_APP\r\n"
- #define MIAP_PROTOCOL_INFO "PCTA"
- #define MIAP_COMPLETE_INFO "[MSG]Completed!\r\n"
- #define MIAP_MSG_INFO "[MSG]"
- typedef enum{
- MIAP_IDLE, //空闲
- MIAP_START, //定时发MIAP_TRIGGER_INFO
- MIAP_BUSY, //正在传输文件
- MIAP_DONE, //设备完成升级
- MIAP_STOP
- }MIAP_ENUM;
- static T_UINT8 iapStatus=MIAP_IDLE;
- #define MAX_WAIT_TIME_UPGRADE 5//升级模式下如果此时间内收不到版本或数据请求,则退出升级模式
- unsigned char mcuIapMode=0;//当前是否进入正常的IAP模式
- unsigned char mcuIapUpgradeCnt=0;//进入升级模式后的超时计数
- void mcuIapModeUpdate(unsigned char newmode){
- if(newmode==mcuIapMode) return;
- if(newmode==1) normalTaskStatus(FALSE);
- else normalTaskStatus(TRUE);
- mcuIapMode=newmode;
- }
- #define MAX_WAIT_VERSION_TIME 30
- T_UINT8 mcuCheckTimeCnt=0;//开机后MAX_WAIT_VERSION_TIME内接受MCU版本指令
- #define MAX_SEND_TRIGGER_TIME 5
- T_UINT8 mcuVersionSendCnt;//发送MIAP_TRIGGER_INFO时间计数
- static void isMcuIapTaskIdle(void){
- if(MIAP_IDLE==iapStatus) ticketVote(TICKET_PT_MCUIAP);
- else ticketDeVote(TICKET_PT_MCUIAP);
- }
- #define MSG_BUFFER_SIZE 512
- unsigned char msgPtr[MSG_BUFFER_SIZE];
- void miapStatusUpdate(MIAP_ENUM newstatus){
- if(newstatus==iapStatus) return;
- if(MIAP_START==newstatus){
- wlog_warn("mcu version start ok");
- }
- iapStatus=newstatus;
- }
- static void mcuVersionAcceptTime(void){
- if(mcuCheckTimeCnt<=MAX_WAIT_VERSION_TIME*2) mcuCheckTimeCnt++;
- if(MIAP_START==iapStatus){
- if(++mcuVersionSendCnt>=MAX_SEND_TRIGGER_TIME*2){
- miapStatusUpdate(MIAP_STOP);
- wlog_info("Mcu no ack for asking, timeout");
- }
- }else mcuVersionSendCnt=0;
- if(mcuIapMode==1){
- if(++mcuIapUpgradeCnt>=MAX_WAIT_TIME_UPGRADE*2){
- wlog_warn("Miap:timeout no version or data req");
- miapStatusUpdate(MIAP_STOP);
- }
- }else mcuIapUpgradeCnt=0;
- }
- PT_THREAD (ptMcuIapTask(pt_timer_t *ptPool, struct pt *pt)){
- static pt_timer_t ptTimer;
- PT_BEGIN(pt);
- while(1){
- switch(iapStatus){
- case MIAP_IDLE:
- break;
- case MIAP_START:
- msgToOutter(MIAP_TRIGGER_INFO);
- break;
- case MIAP_BUSY:
- break;
- case MIAP_DONE:
- break;
- case MIAP_STOP:
- wlog_info("MIAP_STOP");
- mcuIapModeUpdate(0);
- miapStatusUpdate(MIAP_IDLE);
- break;
- }
- mcuVersionAcceptTime();
- isMcuIapTaskIdle();
- PTTimerStart(ptPool, &ptTimer,50);
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
- }
- PT_END(pt);
- }
- static int IapRecvMsgHandle(unsigned char *msg, unsigned int len);
- //处理由串口收到的数据包
- char miapRecvFromUart(unsigned char *data, int length){
- static unsigned int recvLen=0;
- unsigned int i,k;
- unsigned short len;
- unsigned char protocol;
- int plen=length;
- for(i=0;i<plen;i++){
- if(recvLen>=MSG_BUFFER_SIZE){
- wlog_error("maip recvbuf overflow,reset");
- recvLen=0;
- continue;
- }
- msgPtr[recvLen++]=data[i];
- if(recvLen<5) continue;
- if(0==memcmp(msgPtr, MIAP_PROTOCOL_INFO,strlen(MIAP_PROTOCOL_INFO))){
- protocol=msgPtr[4];
- if(recvLen<26) continue;
- len=(unsigned short)msgPtr[25]<<8;
- len+=(unsigned short)msgPtr[24];
- len+=26;
- if(recvLen<len) continue;
- if(UPDATE_PROTOCOL_APP==protocol){
- miapStatusUpdate(MIAP_BUSY);
- IapRecvMsgHandle(msgPtr,recvLen);
- }
- recvLen=0;
- }else if(0==memcmp(msgPtr, MIAP_MSG_INFO, strlen(MIAP_MSG_INFO))){
- for(k=0;k<recvLen;k++){
- if(msgPtr[k]<=0x0A){
- msgPtr[k]=0;
- break;
- }
- }
- if(k<recvLen){
- wlog_info("%s",msgPtr);
- if(0==memcmp(msgPtr, MIAP_COMPLETE_INFO,strlen(MIAP_COMPLETE_INFO))) miapStatusUpdate(MIAP_DONE);
- recvLen=0;
- }
- }else return 0;
- }
- return 1;
- }
- unsigned char *getMd5Data(void){
- static unsigned char md5[32];
- memcpy(md5, getMcuAppMD5(),32);
- restoreDataFormatByHex(md5,32);
- return md5;
- }
- static int IapRecvMsgHandle(unsigned char *pData, unsigned int Datalen){
- int i;
- unsigned char data;
- unsigned char code;
- unsigned short count;
- update_hdr_t *pHeader;
- update_version_req_t *pVersionReq;
- update_version_rsp_t VersionRsp;
- update_data_req_t *pDataReq;
- update_data_rsp_t DataRsp;
- static unsigned char m_Rand;
- unsigned char *m_FileMD5=getMd5Data();
- unsigned int m_FileSize=getMcuAppDataSize();
- unsigned char *m_FileData=getMcuAppData();
- pHeader=(update_hdr_t *)pData;
- if(pHeader->magic != PCTA_MAGIC)return -1;
- if(pHeader->protocol != UPDATE_PROTOCOL_APP )return -2;
- if(pHeader->code==UPDATE_CODE_VERSION_REQ){
- if(pHeader->count!=(sizeof(update_version_req_t)-sizeof(update_hdr_t)))return -3;
- //ShowMsg(_T("UPDATE_CODE_VERSION_REQ"));
- pVersionReq= (update_version_req_t *)pData;
- memcpy(&VersionRsp.hdr,&pVersionReq->hdr,sizeof(update_hdr_t));
- VersionRsp.hdr.count=sizeof(update_version_rsp_t)-sizeof(update_hdr_t);
- VersionRsp.size=m_FileSize;
- memcpy(VersionRsp.version_md5,m_FileMD5,16);
- m_Rand=pHeader->tid;
- //Send
- wlog_info("version req ok, feed back");
- //showHexData((unsigned char *)&VersionRsp,sizeof(update_version_rsp_t));
- LSAPI_OSI_ThreadSleep(10);//不能太快发给MCU
- uartOutPut((unsigned char *)&VersionRsp,sizeof(update_version_rsp_t));
- return 1;
- }else if(pHeader->code == UPDATE_CODE_DATA_WITH_CRC_REQ){
- if(pHeader->count!=(sizeof(update_data_req_t)-sizeof(update_hdr_t)))return -3;
- //ShowMsg(_T("UPDATE_CODE_DATA_WITH_CRC_REQ"));
- pDataReq=(update_data_req_t *)pData;
- memcpy(&DataRsp.hdr,&pDataReq->hdr,sizeof(update_hdr_t));
- memcpy(DataRsp.version_md5,m_FileMD5,16);
- DataRsp.offset=pDataReq->offset;
- DataRsp.length=0;
- for(i=0;i<pDataReq->length;i++){
- if((DataRsp.offset+DataRsp.length)>=m_FileSize || DataRsp.length>=UPDATE_DATA_SIZE_MAX)break;
- data=m_FileData[DataRsp.offset+DataRsp.length];
- data^=m_Rand;//加密
- DataRsp.data[DataRsp.length]=data;
- DataRsp.length++;
- }
- //CRC
- unsigned short crc=crc16_calc(0,DataRsp.data,DataRsp.length);
- DataRsp.data[DataRsp.length++]=crc&0xff;
- DataRsp.data[DataRsp.length++]=crc>>8;
- DataRsp.hdr.count=DataRsp.length + 24 ;//长度
- //Send
- LSAPI_OSI_ThreadSleep(10);//不能太快发给MCU
- uartOutPut((unsigned char *)&DataRsp,DataRsp.hdr.count+sizeof(update_hdr_t));
- return 0;
- }
- return 0;
- }
- /*启动LTE进入MCU_IAP模式*/
- void McuIapStart(void){
- mcuIapModeUpdate(1);
- miapStatusUpdate(MIAP_START);
- mcuCheckTimeCnt=0xff;
- }
- /*MCU没有通过正常流程而是直接发PCTA消息过来时,需要启动MCUIAP*/
- void McuIapKeepOn(void){
- if(mcuIapMode!=0) return;
- McuIapStart();
- }
- //系统休眠后醒来要更新计数器
- void miapCntUpdate(T_INT32 value){
- T_INT32 temp;
- temp=MAX_WAIT_VERSION_TIME*2-mcuCheckTimeCnt;
- if(temp<=0) return;
- if(value>temp) mcuCheckTimeCnt=0xff;
- else mcuCheckTimeCnt += value;
- }
- T_INT32 getMaipCnt(void){
- T_INT32 temp;
- temp=MAX_WAIT_VERSION_TIME*2-mcuCheckTimeCnt;
- if(temp<=0) return NO_SLEEP_TIME;
- else return temp;
- }
- T_BOOL isMcuIapOff(void){
- if(mcuIapMode==0) return TRUE;
- else return FALSE;
- }
|