//------------------------------------------------------------- //协议解析 //------------------------------------------------------------- #include "....SystemCom.h" #include "....SystemMemory.h" #include "....SystemMessage.h" #include "....SystemQueue.h" #include "....SystemCommunicateQueue.h"
enum TaskState { eSTX, eSync, eDataLength, eData, eChkSum, eETX };
struct InPackTask { struct CommunicateQueue *pCommunicate; void (*CallBack_Package)( struct CommunicateQueue *pCommunicate ); //解析到正确包后给外部程序处理 U8 mTask; U8 mDataLength; };
struct InPackage { struct InPackTask *pPackTask; U8 mTaskMax; U8 mTaskRegisterId; }; struct InPackage sInPackage;
#define this sInPackage
//------------------------------------------------------------- //检查校验和 //正确返回TRUE //------------------------------------------------------------- bool InPackage_ChkSumCheck( struct InPackTask *pPackTask ) { U8 i; U8 j; U8 mSum = 0; j = pPackTask->mDataLength + 3 - 1; for( i=1; i<j; i++ ) { mSum += Queue_Read( pPackTask->pCommunicate->psReci, i ); } if( mSum == Queue_Read( pPackTask->pCommunicate->psReci, i ) ) { return true; } else { return false; } }
//------------------------------------------------------------- //注册包解析的回调处理 //------------------------------------------------------------- void Package_Register( struct CommunicateQueue *pCommunicate, void (*CallBack_Package)( struct CommunicateQueue *pCommunicate ) ) { struct InPackTask *pPackTask = &this.pPackTask[ this.mTaskRegisterId++ ]; pPackTask->pCommunicate = pCommunicate; pPackTask->CallBack_Package = CallBack_Package; }
//------------------------------------------------------------- //初始化 //入口:队列指针 //------------------------------------------------------------- void Package_Init( U8 mTaskMax ) { Memory_Memset( (U8 *)&this, 0, sizeof(struct InPackage) ); this.pPackTask = (struct InPackTask *)Memory_Malloc( sizeof(struct InPackTask) * mTaskMax ); this.mTaskMax = mTaskMax; }
//------------------------------------------------------------- //单任务解析 //------------------------------------------------------------- void InPackage_SingleTask( struct InPackTask *pPackTask ) { switch( pPackTask->mTask ) { L_ProtcolLoop: case eSTX: if( Queue_Num( pPackTask->pCommunicate->psReci ) ) { if( Queue_Pop( pPackTask->pCommunicate->psReci ) != STX ) { goto L_ProtcolError; } pPackTask->mTask = eSync; } else break; case eSync: if( Queue_Num( pPackTask->pCommunicate->psReci ) ) { if( Queue_Read( pPackTask->pCommunicate->psReci, 0 ) != SYNC ) { goto L_ProtcolError; } pPackTask->mTask = eDataLength; } else break; case eDataLength: if( Queue_Num( pPackTask->pCommunicate->psReci ) >= 3 ) { //已经收到数据块长度 pPackTask->mDataLength = Queue_Read( pPackTask->pCommunicate->psReci, 1 ); pPackTask->mTask = eData; } else break; case eData: if( Queue_Num( pPackTask->pCommunicate->psReci ) >= (pPackTask->mDataLength + 2 ) ) { pPackTask->mTask = eChkSum; } else break; case eChkSum: if( Queue_Num( pPackTask->pCommunicate->psReci ) >= (pPackTask->mDataLength + 3 ) ) { //检查校验和 if( InPackage_ChkSumCheck( pPackTask ) ){ pPackTask->mTask = eETX; } else { goto L_ProtcolError; } } else break; case eETX: if( Queue_Num( pPackTask->pCommunicate->psReci ) >= (pPackTask->mDataLength + 4 ) ) { //检查ETX if( Queue_Read( pPackTask->pCommunicate->psReci, pPackTask->mDataLength + 4 - 1 ) == ETX ) { //正确包,去掉同步后给程序使用 Queue_Pop( pPackTask->pCommunicate->psReci ); if( pPackTask->CallBack_Package ){ ( *pPackTask->CallBack_Package )( pPackTask->pCommunicate ); } else { //无处理函数,丢弃整个包 Queue_Pop( pPackTask->pCommunicate->psReci ); //长度字 while( pPackTask->mDataLength-- ) { Queue_Pop( pPackTask->pCommunicate->psReci ); } } Queue_Pop( pPackTask->pCommunicate->psReci ); //chksum Queue_Pop( pPackTask->pCommunicate->psReci ); //etx pPackTask->mTask = eSTX; goto L_ProtcolLoop; //从头重新检测 } else{ goto L_ProtcolError; } } break; } return;
L_ProtcolError: pPackTask->mTask = eSTX; goto L_ProtcolLoop; //从头重新检测 }
//------------------------------------------------------------- //循环 //------------------------------------------------------------- void Package_Loop( void ) { U8 i; struct InPackTask *pPackTask = this.pPackTask; for( i=0; i<this.mTaskRegisterId; i++ ) { InPackage_SingleTask( pPackTask++ ); } }
|