⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tskprot.c

📁 本人编写的无线电话程序,给予PIC18C801设计,包括了uCOS的移植以及菜单,自己设计的拼音注入法,完整地一级汉字库,希望对大家有所帮助
💻 C
📖 第 1 页 / 共 2 页
字号:
//Protocol process tasks.
//The transmission stack work like this:
//The lowest layer----tskDEBUG, function:packet/depacket and check ACK frame out 
//The second layer----tskRxProtocol & tskTxProtocol
//					  function: segment and reasamble MCNM data blocks, and deal with
//                              such operations like retransmission, timeout, resync, etc
//The highest layer---tskMCNM
//					  function: save parameters according to bitmap in received data block
//                              and answer with the polled domain

//This file containing tskTxProtocol and tskRxProtocol
#include "includes.h"

extern OS_EVENT 	*rom peventTxProtocol;
extern OS_EVENT 	*rom peventRxProtocol;
extern OS_EVENT		*rom peventMCNM;
extern OS_EVENT		*rom peventDEBUG;
extern OS_EVENT		*rom peventWICCmd;
extern OS_EVENT 	*rom peventTimer;

extern OS_MEM			*pMemSml;
extern OS_MEM			*pMemLge;
extern OS_MEM			*pMemHug;

extern unsigned char DebugContent[48];
extern rom unsigned char *DebugReadAddr;

#define PROT_TIME_OUT_ID	0x0001

#define LONG_TIMEOUT		50	//unit:second
#define SHORT_TIMEOUT		10	//unit:second

#define MAX_TX_FRAME_LEN	138
#define MAX_RX_FRAME_LEN	256



//Service type word in frame
#define FT_PAYPHONE			0x04
#define FT_SYS				0x00
//Subtype
#define FC_DATA				0x00
#define FC_ACK				0x01
#define FC_MON				0x02

#define BIT_SYN				0b01000000
#define BIT_TOBECONTINUE 	0b10000000

//link status
#define LS_IDLE				0	//idle state
#define LS_WAITANS			1	//waiting answer
#define LS_WAITFOLLOW		2	//waiting following frames


extern void Func_Clear_Msg(INT8U rom * pMsg);

INT8U TestNR(INT8U rom *ptrF);
INT8U TestNT(INT8U rom *ptrF);
INT8U TestACK(INT8U rom *ptrF);
INT8U TestToBeContinue(INT8U rom *ptrF);
INT8U Data_Rx_Proc(INT8U rom * ptrF, INT8U port);
void Data_Tx_Proc(INT8U rom * ptrF, INT16U Len, INT8U port);
void SendACK(INT8U port);
void SendFrame(INT8U rom * ptrD, INT16U len, INT8U port, INT8U option);

#pragma romdata EXTRAM
INT8U rom CurNT;
INT8U rom CurNR;
INT8U rom ActivePort;

INT8U rom * rom ptrRxBuf;
INT8U rom * rom ptrRxBufBase;
OS_MEM * rom ptrRxBufMem;

INT16U rom CurTimeOut;

INT8U rom Syn_Needed;

#pragma code MYCODE
void tskRxProtocol(void * data){
	void rom * pMsg;
	INT8U err;
	INT8U rom * pSml;
	
	CurNT = 0;
	CurNR = 0;
	ActivePort = PT_NONE;
	CurTimeOut = LONG_TIMEOUT;
	ptrRxBuf = NULL_PTR;
	ptrRxBufBase = NULL_PTR;
	
	for(;;){        
		pMsg = OSQPend(peventRxProtocol, 0, &err);                                       //Wait for the messages
		if(err == OS_NO_ERR){
			if((INT24U)pMsg >= PTR_MAX){                            //If is a direct message--just a value
				switch ((INT24U)pMsg){
					
				}
			}
			else{                                                  //If it's a undirect message--a pointer
				switch (((MSG_HEAD *)pMsg)->Msg_ID){
					case MSG_PROT_RECEIVE:
						if(((MSG_HEAD *)pMsg)->Origin == peventDEBUG){
							ActivePort = PT_HDLC;
							CurTimeOut = SHORT_TIMEOUT;
						}
						else{
							ActivePort = PT_SM;
							CurTimeOut = LONG_TIMEOUT;
						}
						if(Data_Rx_Proc(((MSG_HEAD *)pMsg)->pMem,ActivePort) == 1){
							//open or clear the timer
							pSml=OSMemGet(pMemSml,&err);
							if(err == OS_NO_ERR){
								((MSG_HEAD *)pSml)->Msg_ID=MSG_TIMER_START;
								((MSG_HEAD *)pSml)->Origin=peventRxProtocol;
								((MSG_HEAD *)pSml)->pmemME=pMemSml;
								((MSG_HEAD *)pSml)->Attached=FALSE;
								((MSG_HEAD *)pSml)->LenOfBody=4;
								((TIMER_MESSAGE *)pSml)->TID=PROT_TIME_OUT_ID;
								((TIMER_MESSAGE *)pSml)->Val=OS_TICKS_PER_SEC * CurTimeOut;
							    OSQPost(peventTimer,pSml);
							}
						}
						break;
					case MSG_TIMER_EXPIRE:
						if(ptrRxBufBase != NULL_PTR){//if a rx buffer has been applied
							OSMemPut(ptrRxBufMem, ptrRxBufBase);
							ptrRxBufBase = NULL_PTR;
						}
						break;
				}
				Func_Clear_Msg(pMsg);
				//if(((MSG_HEAD *)pMsg)->Attached == TRUE){
				//	OSMemPut(((MSG_HEAD *)pMsg)->pmemATT, ((MSG_HEAD *)pMsg)->pMem);
				//}
				//OSMemPut(((MSG_HEAD *)pMsg)->pmemME, pMsg);
			}
		}
	}
} 

//if return "0" means current data block is completed, "1" means further frames expected
INT8U Data_Rx_Proc(INT8U rom * ptrF, INT8U port){
	INT8U Type, SubType, SubNet;
	INT8U Temp,err;
	INT16U i;
	OS_MEM * pSml;
	
	Temp = TestNR(ptrF);
	if(Temp == 2){//do not match
	//if a frame with error NT(not agree with CurNR), current and former frames shall be discarded
		if(ptrRxBufBase != NULL_PTR){
			OSMemPut(ptrRxBufMem, ptrRxBufBase);
			ptrRxBufBase = NULL_PTR;
			return(0);
		}
	}
	else if(Temp == 1){//resync needed
		if(ptrRxBufBase != NULL_PTR){
			ptrRxBuf = ptrRxBufBase;//clear the buffer
		}
	}
	if(TestNT(ptrF)== FALSE) Syn_Needed = TRUE; //if the NR in information frame does not agree with local NT,
												//resynchronization is needed
	
	//if it's a correct frame
	if(TestToBeContinue(ptrF)==TRUE){
		if(ptrRxBufBase == NULL_PTR){
			ptrRxBuf=OSMemGet(pMemHug,&err);
			if(err != OS_NO_ERR) return(0);
			ptrRxBufBase = ptrRxBuf;
			ptrRxBufMem = pMemHug;
		}
		Temp = *ptrF;	//the length fo frame
		ptrF +=5;
		for(i=0; i<Temp-5; i++){
			*ptrRxBuf = *ptrF;
			ptrRxBuf++;
			ptrF++;
		}
		SendACK(port);//no wait here
		return (1);
	}
	else{
		if(ptrRxBufBase == NULL_PTR){
			ptrRxBuf=OSMemGet(pMemLge,&err);
			if(err != OS_NO_ERR) return(0);
			ptrRxBufBase = ptrRxBuf;
			ptrRxBufMem = pMemLge;
		}
		Temp = *ptrF;
		ptrF +=3;

		Type = *ptrF & 0x07;
		SubType = (*ptrF & 0xf0)>>4;
		ptrF++;
		SubNet = *ptrF;
		ptrF++;
		
		for(i=0; i<Temp-5; i++){
			*ptrRxBuf = *ptrF;
			//DebugContent[i] = *ptrF;
			ptrRxBuf++;
			ptrF++;
		}
		DebugReadAddr = ptrRxBuf;
		pSml = OSMemGet(pMemSml,&err);
		if(err == OS_NO_ERR){
			((MSG_HEAD *)pSml)->Msg_ID = MSG_MCNM_RECEIVE;
			((MSG_HEAD *)pSml)->Origin = peventRxProtocol;
			((MSG_HEAD *)pSml)->pmemME = pMemSml;
			((MSG_HEAD *)pSml)->Attached = TRUE;
			((MSG_HEAD *)pSml)->LenOfAttach = (INT16U)(((INT24U)ptrRxBuf) - ((INT24U)ptrRxBufBase));
			((MSG_HEAD *)pSml)->pMem = ptrRxBufBase;
			((MSG_HEAD *)pSml)->pmemATT = ptrRxBufMem;
			((MSG_HEAD *)pSml)->LenOfBody = 3;
			((MSG_PROTOCOL *)pSml)->Type = Type;
			((MSG_PROTOCOL *)pSml)->SubType = SubType;
			((MSG_PROTOCOL *)pSml)->SubNet = SubNet;
			OSQPost(peventMCNM, pSml);
			ptrRxBufBase = NULL_PTR;	//mark that no mem. block is applied
			//OSTimeDly(((MSG_HEAD *)pSml)->LenOfAttach /32+1);
			//note: the worst situation is to write "len" bytes in MCNM, so cost about len/32 *10 ms
			SendACK(port);
			return(0);
		}
	}
}


void tskTxProtocol(void * data){
	void rom * pMsg;            //The pointer of message, it has to be a pointer point to the "rom: region
	INT8U err;                      //Used to return the error value. It must be a variable in data region
	for(;;){                                                                               //The main loop
		pMsg = OSQPend(peventTxProtocol, 0, &err);                                       //Wait for the messages
		if(err == OS_NO_ERR){
			if((INT24U)pMsg >= PTR_MAX){                            //If is a direct message--just a value
				switch ((INT24U)pMsg){
					
				}
			}
			else{                                                  //If it's a undirect message--a pointer
				switch (((MSG_HEAD *)pMsg)->Msg_ID){
					case MSG_MCNM_TRANSMIT:
						if(ActivePort != PT_NONE){
							Data_Tx_Proc(((MSG_HEAD *)pMsg)->pMem, ((MSG_HEAD *)pMsg)->LenOfAttach,ActivePort);
						}
						else{
							OSQPost(peventMCNM, (OS_EVENT *)MSG_MCNM_TXNOPORT);
						}
						break;
					case MSG_MCNM_SETPORT:
						if(((MSG_PROTOCOL *)pMsg)->Port != ActivePort){
							ActivePort = ((MSG_PROTOCOL *)pMsg)->Port;
							if(ActivePort == PT_HDLC){
							//to dialup or something
							}
						}
						break;
				}
				Func_Clear_Msg(pMsg);
				//if(((MSG_HEAD *)pMsg)->Attached == TRUE){
				//	OSMemPut(((MSG_HEAD *)pMsg)->pmemATT, ((MSG_HEAD *)pMsg)->pMem);
				//}
				//OSMemPut(((MSG_HEAD *)pMsg)->pmemME, pMsg);
			}
		}
	}
} 


//This level deal with frame
void Data_Tx_Proc(INT8U rom * ptrF, INT16U Len, INT8U port){
	INT8U rom * pMsg;
	INT8U err,SendEn;
	//INT16U TimeOut;
	INT8U Option,Err_Cnt;
	
	//decide if the syn bit of NT byte shall be set

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -