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

📄 xnpm.nc

📁 tinyos 一个xnp程序
💻 NC
📖 第 1 页 / 共 4 页
字号:
 * NPX__ISP:  * task to writes GROUP_ID and TOS_ID into eeprom, then invoke bootloader ****************************************************************************/task void NPX_ISP() {//setup parameters to pass//R20,R21 wProgId, R22:PageStart, R24,25:nwProgID   uint16_t wPID;   uint8_t cTemp;   uint8_t *pAddr;   cli(); //turnoff interrupts// Store GROUPID and LOCAL ADDRESS into EEPROM// note:this function blocks &waits until EEPROM is available    eeprom_write_byte ((uint8_t *)AVREEPROM_GROUPID_ADDR, TOS_AM_GROUP);    eeprom_write_byte ((uint8_t *)AVREEPROM_LOCALID_ADDR, TOS_LOCAL_ADDRESS);//lsbyte	eeprom_write_byte ((uint8_t *)AVREEPROM_LOCALID_ADDR+1, (TOS_LOCAL_ADDRESS>>8));//msbyte	//The following should really only be done when ISP has loaded the program...    pAddr = &wProgramID;	 //the prog id			   	eeprom_write_byte (AVREEPROM_PID_ADDR, *pAddr++);//lsbyte	eeprom_write_byte (AVREEPROM_PID_ADDR+1, *pAddr);//msbyte  	while (!eeprom_is_ready()); //wait for eeprom to finish    wPID = ~wProgramID;	 //inverted prog id    __asm__ __volatile__ ("movw r20, %0" "\n\t"::"r" (wPID):"r20", "r21");    wPID = wEEProgStart;    __asm__ __volatile__ ("movw r22, %0" "\n\t"::"r" (wPID):"r22", "r23");    wPID = wProgramID;	 //the prog id    __asm__ __volatile__ ("movw r24, %0" "\n\t"::"r" (wPID):"r24", "r25");//call bootloader - it may never return...    __asm__ __volatile__ ("call 0x1F800" "\n\t"::);		//bootloader at 0xFC00 //   __asm__ __volatile__ ("clr r1" "\n\t"::);//if here reboot/reprog failed   	bCommandOK= CMD_STATE_BADCHECKSUM;	 //default we don't recognize it	if(bAckMessage)		fNPXSendStatus();	return;}	/*****************************************************************************TOS TASK Write specified buffer  out to EEPROMOn completion, the CORRECT buffer FULL status will be cleared...Need a PENDING flag to keep trying until EEPROM ready or timeoutbELBuffAWE	[0,1] points to 1 of 2 256 byte buffers in EEPROMwEE_LineW	Absolute line# as starting address for written data. Actually modulo			16 because only 16 lines (16bytes/line * 16lines = 1page) are used.			But wEE_LineW as an absolute line# is used elsewhere in the TestBenchELBUFF_NOFLINES			Number of Lines (16bytes) to write.ELBuff		Data buffer. Must be 16*ELBUFF_NOFLINES bytes deepWhen reach end of a Page Buffer (256bytes) we switch buffers for writingAnd then EEWRITE_LINEDONE handler will flush out the previous buffer to EEPROM'sinternal ROMNotes"1. hINSTANCE is a constant - should be variable set by StartEEPROM!!!!This is handled differently (correctly) in NESC	!!!!*****************************************************************************/#define EEBufA 0	//Buffer IDs#define EEBufB 1	//Buffer IDstask void NPX_wEE_LineWrite() {	uint8_t iRet; 	if( bEEWriteEnabled ) { 	 if( !bEEPROMBusy){	//write the first of a 2line sequence	  bEELine1 = TRUE;	// 1st line	  iRet = call EEPROMWrite.write(wEE_LineW, (uint8_t*)&ELBuff );// ADD RETRY TIMEOUT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!	  if(!iRet)	//failed    		post NPX_wEE_LineWrite(); //keep trying			  bEEPROMBusy= TRUE;  	  //Handle variable number of line per buffer	  wEE_LineW++;	 //track absolute line number	  cLineinPage++; //next line within page	  if( cLineinPage >= NOFLINESPERPAGE ) { //at page boundary		bELBuffAWE = !bELBuffAWE; //toggle line buffer for writing lines		bELBuffFull = TRUE; //tells LineDone handler to flush internal buffer		cLineinPage = 0;	//reset line counter		}    	}		else	 //try again    		post NPX_wEE_LineWrite(); 	}}//tos-task/*****************************************************************************NPX_STATEMACHINEHandles various states during SREC Download.-On each SREC capsule received ()	writes srec line if EEPROM not busy, otherwise loops until ready.-SYS_DL_FAILCleansup / releases EEPROM resourceSend message to HostGoes into IDLE******************************************************************************/task void NPX_STATEMACHINE() {	uint8_t cNextState;	uint8_t bRePost;	uint8_t bRet;	uint16_t *wptr;	cNextState = sSYSState; //default is no change	bRePost = FALSE; //by default we do not repeat this statemachine task	switch( sSYSState )	{	case SYS_REQ_CIDMISSING: //get control back		//if the requested PID does not match our current PID we ignore the request		wptr = (uint16_t *)&(pNETTOSMsg->data[TS_PID]);		if( *wptr != wProgramID ) {			bCommandOK = CMD_STATE_BADSEQUENCE;			cNextState = SYS_ACK;			bRePost = TRUE;		}else {		 	cNextState = SYS_GET_CIDMISSING;			//Release EEFLASH		     bRet = call EEPROMWrite.endWrite();  //EEWriteEndDone will invoke NPX statemachine			 if(bRet==FAIL) 				bRePost = TRUE; //endWrite  will not signal enddone	go directly to next state			}		break;	case SYS_GET_CIDMISSING:		sSYSMState = SYSM_UPDATE;	 	fNPXGetNextEmptySREC(wCIDMissingPrevious);//this starts reading sequentially thru EEFLASH		cNextState = sSYSState;		break;	case SYS_DL_START:		cNextState = SYS_DL_START0; //this is a pseudo state waiting for APP to ack start dl request	    fNPXStartDownload(pNETTOSMsg); //prep & call app with DL request.Determines next state		cNextState = sSYSState; //SYS state maybe changed by functioncall		break;	case SYS_DL_START1: //get system into clean known state	 	cNextState = SYS_DL_START2;		//Release EEFLASH unconditionally to get into clean state	     bRet = call EEPROMWrite.endWrite();  //EEWriteEndDone will invoke NPX statemachine		 if(bRet==FAIL) 			bRePost = TRUE; //no endWrite to signal enddone so go directly to START1		break;	case SYS_DL_START2: //		//Clear flags		bEEWriteContinuous = FALSE; 		bEEWriteEnabled = FALSE;        // eeprom writing enabled flag		bEEPROMBusy = FALSE;     //reset any pending eprom writes 		//lock down EEPROM resource	    bRet = call EEPROMWrite.startWrite(); //a function call - no event signal	    if( !bRet )	{	  //eeprom not available			bCommandOK = CMD_STATE_BUSY;			sSYSState = SYS_DL_FAIL;		} else {			bEEWriteContinuous = TRUE; //donot release EEFLASH after each srec write			bEEWriteEnabled = TRUE;        // eeprom writing enabled flag			bEEPROMBusy = FALSE;     //reset any pending eprom writes 			wEEProgStart = EE_PageW<<4;//the starting point in EEFlash			wCapsuleNo = 0;		//update current capsule# -Network capsule# starts at 1			//fNPXS0RecBuild(); //fNPXS0RecBuild sets up for EEFLASH write of S0			bCommandOK = CMD_STATE_DONE;			sSYSMState = SYSM_DOWNLOAD;	 //Entered DOWNLOAD Major State			cNextState = SYS_ACK;	 //we are ready to accept SREC Downloads		}		bRePost = TRUE;		//goto next state	 		break;	case SYS_DL_SRECWRITE: //write SREC in DOWNLOAD Mode			fNPXSRECStore(pNETTOSMsg);	//storesrec			cNextState = sSYSState; //whatever fNPXSRECStore did to sSYSState			break;	case SYS_UP_SRECWRITE: //write SREC in UPDATE Mode			fNPXSRECUpdate(pNETTOSMsg);			cNextState = sSYSState; //whatever fNPXSRECUpdate did to sSYSState			break;	case SYS_EEFLASH_WRITE:	  #ifdef PLATFORM_MICA2DOT	  call Leds.redOn();	  #endif	  call Leds.yellowOn();		if( bEELineWritePending ){ 	//waiting to post a task to EEWrite		   	if( !bEEPROMBusy ){				post NPX_wEE_LineWrite();//write buffer out to EEPROM				bEELineWritePending = FALSE;		     	} else //EEPROM is busy					bRePost = TRUE;	//re-execute NPX_STATEMACHINE only if busy			}//writepending			else { //not pending 				cNextState = SYS_EEFLASH_WRITEDONE; //nothing to so so endit				bRePost = TRUE;				}	  		break;	case SYS_EEFLASH_WRITEDONE:		cNextState = SYS_ACK; //where we go next		if( !bEEWriteContinuous	) { //release the resource after each write            if( bEEWriteEnabled )            	 call EEPROMWrite.endWrite();  //EEWriteEndDone will invoke next state			else				bRePost = TRUE;	//chain to next state		} else bRePost = TRUE; //chain to next state    	call Leds.yellowOff();           //diagnostic 		break;		case SYS_DL_END:			//release EEPROM resource			cNextState = SYS_DL_END_SIGNAL;            if( bEEWriteEnabled )            	 call EEPROMWrite.endWrite();  //EEWriteEndDone will invoke NPX statemachine			else				bRePost = TRUE;			break;	case SYS_DL_END_SIGNAL:		 //signal application that download process is finished	-good	 	bCommandOK = CMD_STATE_DONE; 		wCapsuleNo = 0; //reset current Capsule#		signal Xnp.NPX_DOWNLOAD_DONE(wProgramID,TRUE, EE_PageW);		cNextState = SYS_ACK;		sSYSMState = SYSM_IDLE;			bRePost = TRUE;	//re-execute NPX_STATEMACHINE		break;	case SYS_DL_FAIL:			//release EEPROM resource if required			cNextState = SYS_DL_FAIL_SIGNAL;            if( bEEWriteEnabled )            	 call EEPROMWrite.endWrite();  //EEWriteEndDone will invoke NPX statemachine			else				bRePost = TRUE;			break;	case SYS_DL_FAIL_SIGNAL:			if(bAckMessage)				fNPXSendStatus();			sSYSMState = SYSM_IDLE;			wCapsuleNo = 0; //reset current Capsule#			//Tell client download has finished - badly			signal Xnp.NPX_DOWNLOAD_DONE(wProgramID,FALSE, EE_PageW);			cNextState = SYS_ACK;		// should wait for EEPROM flush buffer to fini?			bRePost = TRUE;	//re-execute NPX_STATEMACHINE		break;		case SYS_IDLE_RENTRY:		//resume idle conditions			cNextState = SYS_IDLE;  		   	bNXPMsgBusy = FALSE;			//call Leds.greenOn();       			break;		case SYS_IDLE: 			 bNXPMsgBusy = FALSE;			break;		case SYS_ISP_REQ:			wptr = (uint16_t *)&(pNETTOSMsg->data[TS_PID]);			wProgramID = *wptr++;			EE_PageW = EE_PAGE_START;			wEEProgStart = EE_PageW<<4;//the starting point in EEFlash			//check EEFLASH Capsule #1 (2lines per capsule)to verify this programID is present			wEE_LineR = wEEProgStart+2;	//Capsule#0 is legacy/expansion-future		   	bEELineReadPending = TRUE;	//statemachine handles retries etc		   	cNextState = SYS_ISP_REQ1;				bRePost = TRUE;			break;		case SYS_ISP_REQ1:		case SYS_GETNEXTCID:	   //have read 1st half of srec from FLASH			if( bEELineReadPending ){				#ifdef PLATFORM_MICA2DOT				call Leds.redOn();	   //led off during read/missing capsule check, ON at end if ok				#endif				call Leds.yellowOn();       				call EEPROMRead.read(wEE_LineR, (uint8_t*)&ELBuff );				}			//if fail do what? - go idle?			break;		case SYS_ACK: //send ack to network if required and then go idle			if(bAckMessage ) //acknowledge to network				fNPXSendStatus(); 			bNXPMsgBusy = FALSE;    		call Leds.redOff();           //diagnostic 			cNextState = SYS_IDLE;			break;			case SYS_GETDONE:			call Leds.yellowOff();       		   //	sSYSMState = SYS_IDLE;		//no ack and leaves LED ON			cNextState = SYS_IDLE;  		   	bNXPMsgBusy = FALSE;			break;		case SYS_BEACON:    	 //	call Leds.redOn();           //diagnostic 		 //	fNPXSendStatus();			if( !bTOSMsgBusy )				fProcessMissingCapsule(wProgramID, wCapsuleNo);			bRePost = TRUE;	//re-execute NPX_STATEMACHINE    	 //	call Leds.redOff();           //diagnostic 			break;		default:		 break;	}	//switch// update state	sSYSState = cNextState; //this updates BEFORE any new tasks start	if( bRePost )		post NPX_STATEMACHINE(); //try againreturn;}//TASK NXP Statemachine	/***************************************************************************** receive() - message from newtork******************************************************************************/event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr msgptr) {   int (*ptr)();  uint16_t *wptr;  uint8_t cNextState;  TOS_MsgPtr pPrevious;//Filter for correct GROUP_ID and MOTEID for GSK compatibility	if (msgptr->group != TOS_AM_GROUP) return msgptr;	if ((msgptr->addr != TOS_BCAST_ADDR) && (msgptr->addr != TOS_LOCAL_ADDRESS) )return msgptr;  if (bTOSMsgBusy) return msgptr;  if (bNXPMsgBusy) return msgptr;	//call Leds.yellowOff();    call Leds.greenOff();           //leds off    call Leds.redOn();           //diagnostic - turns off at exit of statemachine SYS_ACK  bNXPMsgBusy = TRUE;  pPrevious = pNETTOSMsg;	//save ptr to previous buffer  pNETTOSMsg = msgptr;	  //point to new buffer  cNextState = sSYSState; //statemachine updates// -------LOCAL COMMANDS addressed to this specific node  if( (msgptr->addr == TOS_LOCAL_ADDRESS) )	{	cCommand = msgptr->data[TS_CMD]; //save the netprog command ID	cSubCommand = msgptr->data[TS_SUBCMD]; //save the  command ID	bCommandOK= CMD_STATE_UKNOWN;	 //default we don't recognize it	bBCASTMsg = FALSE;	bAckMessage = TRUE;	switch (cCommand)	     //was [4]	{		case CMD_RST:	 //REBOOT		   ptr = 0;			ptr();			break;		case CMD_DOWNLOAD_STATUS:			bCommandOK= CMD_STATE_DONE;	 //status command req reqognized			cNextState = SYS_ACK;			break;		case CMD_STATUS:	//Get node status			bCommandOK= CMD_STATE_DONE;	 //status command req reqognized			cNextState = SYS_ACK;			break; 					case CMD_START_DOWNLOAD: //Header info for a code download//		    fNPXStartDownload(pNETTOSMsg);			cNextState = SYS_DL_START;			break;		case CMD_DOWNLOADING:			if(sSYSMState==SYSM_DOWNLOAD)				cNextState = SYS_DL_SRECWRITE;			else if (sSYSMState == SYSM_UPDATE)				cNextState = SYS_UP_SRECWRITE;			else cNextState = SYS_ACK; //ignore		  break;		case CMD_DOWNLOAD_COMPLETE:			cNextState = SYS_DL_END;			break;		case CMD_ISP_EXEC:			cNextState = SYS_ISP_REQ;			break;		case CMD_GET_CIDMISSING://			wptr = &(pNETTOSMsg->data[TS_PID]);	//tests are done in statemachine//			wProgramID = *wptr;			cNextState = SYS_REQ_CIDMISSING;		 	break;		case CMD_GET_PIDSTATUS:			fNPXGetProgramID(pNETTOSMsg); 			 bNXPMsgBusy = FALSE;    		call Leds.redOff();           //diagnostic - turns off at exit 			break;		default://			call Leds.yellowOn(); 			cNextState = SYS_ACK;			break; //invalid command	}//switch command	sSYSState = cNextState;	post NPX_STATEMACHINE(); //try again

⌨️ 快捷键说明

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