📄 xnpm.nc
字号:
return pPrevious; //TOS LOCAL COmmand exit - return original buffer?? } // if TOS_LOCAL_ADDRESS// -------TOS_BCAST_ADDR COMMANDS addressed to this specific node if( (msgptr->addr == TOS_BCAST_ADDR) ) { cCommand = msgptr->data[TS_CMD]; //save the command ID cSubCommand = msgptr->data[TS_SUBCMD]; //save the command ID bCommandOK= CMD_STATE_UKNOWN; //default we don't recognize it bBCASTMsg = TRUE; bAckMessage = FALSE; //bydefault no message acknowledment switch (cCommand) //was [4] { case CMD_START_DOWNLOAD: //Header info for a code downloaf if( cSubCommand == TOS_LOCAL_ADDRESS ) bAckMessage = TRUE; //acknowledge broadcast message cNextState = SYS_DL_START; break; case CMD_DOWNLOADING: if( cSubCommand == TOS_LOCAL_ADDRESS ) bAckMessage = TRUE; //acknowledge broadcast message if(sSYSMState==SYSM_DOWNLOAD) cNextState = SYS_DL_SRECWRITE; else if (sSYSMState == SYSM_UPDATE) cNextState = SYS_UP_SRECWRITE; else cNextState = SYS_ACK; break; case CMD_DOWNLOAD_COMPLETE: if( cSubCommand == TOS_LOCAL_ADDRESS ) bAckMessage = TRUE; //acknowledge broadcast message cNextState = SYS_DL_END; break; case CMD_ISP_EXEC: cNextState = SYS_ISP_REQ; break; case CMD_GET_PIDSTATUS: fNPXGetProgramID(pNETTOSMsg); bNXPMsgBusy = FALSE; call Leds.redOff(); //diagnostic - turns off at exit break; case CMD_GET_CIDMISSING: wptr = &(msgptr->data[TS_PID]); if( (cSubCommand == TOS_LOCAL_ADDRESS)| (!cSubCommand) ){ //for this mote or all motes (subC==0) bAckMessage = TRUE; //acknowledge broadcast message } if( wProgramID != *wptr) bAckMessage = FALSE; //keep quiet if incorrect ProgramID - but call statemachine for cleanup cNextState = SYS_REQ_CIDMISSING; break; default: cNextState = SYS_ACK; break; //invalid command }//switch command sSYSState = cNextState; post NPX_STATEMACHINE(); //try again return msgptr; //TOS broadcast COmmand exit - return original buffer?? } // if TOS_BCAST sSYSState = cNextState; return pPrevious;}//NPX_TOSMsg_Rx/*****************************************************************************SendDoneTOS Message Sent*****************************************************************************/event result_t SendMsg.sendDone(TOS_MsgPtr msg_rcv, bool success) { bTOSMsgBusy = 0; //broadcast message complete ptrmsg = msg_rcv; //hold onto the buffer for next message switch( TOSMsgType ) { default: TOSMsgType = MSG_IDLE; //command message complete break; } return(1); }//MSG_SEND_DONE/***************************************************************************** writeDone - EEPROM finished writing a line of data to eprom buffer If buffer is full, execute EEPROM command to flush buffer into ROM Note that during this flush, line writing can continue by writing into alternate buffer. bEEPROMBusy is NOT set during FLUSH operation. Need to add EEPROM_GetStatus to check EEPROM is idle before doing FLUSH A flush of 256byte page takes 20mSec + some overhead 20msec/256bytes = 78uSec/byte or ~100Kbit/sec*****************************************************************************/event result_t EEPROMWrite.writeDone(uint8_t *buf){ uint8_t cRet; if(bEELine1 ) { //write 2nd line out-still busy bEELine1 = FALSE; cRet = call EEPROMWrite.write(wEE_LineW, (uint8_t*)&ELBuff[ELBUFF_SIZE/2]); //wEE_LineW++; //EELine now maintained by SREC Parser return( TRUE ); } bEEPROMBusy=0; post NPX_STATEMACHINE(); //execute the NPX Statemachine for next state return( TRUE) ; }/***************************************************************************** endWriteDone() - finished use of eeprom for writing - release resource*****************************************************************************/event result_t EEPROMWrite.endWriteDone(result_t success){ bEEWriteContinuous = FALSE; bEEWriteEnabled = 0; //disable writing post NPX_STATEMACHINE(); //execute the NPX Statemachine for next state return(success); //1=success}/******************************************************************************* NPX_SET_IDS* -Check to see if Mote_Id and Group_Id are in Atmega eeprom. If so, use them* -If values returned have 0xff byte values then eeprom was erased and * never written. Default to original values stored in Atmega code space.* -If values returned <>0xff then assume the Mote_Id and Group_Id were * stored in eeprom during net reprogramming. ******************************************************************************/command result_t Xnp.NPX_SET_IDS(){ uint8_t cTemp; uint16_t wTemp; if((cTemp=eeprom_read_byte ((uint8_t *)AVREEPROM_GROUPID_ADDR)) != 0xFF ) TOS_AM_GROUP = cTemp; if((wTemp=eeprom_read_word ((uint16_t *)AVREEPROM_LOCALID_ADDR)) != 0xFFFF ) TOS_LOCAL_ADDRESS = wTemp;#ifdef JTAG TOS_LOCAL_ADDRESS = TOS_LOCAL; //Jtag debug#endif}/******************************************************************************NPX_SENDSTATUSClient can send a status message to Network - diagnostic******************************************************************************/ command result_t Xnp.NPX_SENDSTATUS(uint16_t wAck ) { uint8_t bRet; wCapsuleNo = wAck; //code capsule number fNPXSendStatus(); return(1); }//send/*****************************************************************************NPX_ISP_REQ-Allows application to invoke In System ProgrammingCaller must supply Program ID and its inverse.If these do compare function returns - avoids inadvertent call/jump******************************************************************************/command result_t Xnp.NPX_ISP_REQ(uint16_t wProgID, uint16_t wEEPageStart, uint16_t nwProgID){ if( wProgID != ~nwProgID ) return(FALSE); wEEProgStart = wEEPageStart<<4; //translate to line number wProgramID = wProgID; fNPXGetEEProgID(wEEProgStart); //check valid progid and invoke ISP return(SUCCESS); //not quite correct - wait for result of GetEEProgID}/*************************************************************************fStartDownloadGet header info for upcoming code downloadSignal CLient application for Request*************************************************************************/void fNPXStartDownload(TOS_MsgPtr msgptr) { // uint16_t *wptr; TOS_MsgPtr *wptr; wptr = &(msgptr->data[TS_PID]); wProgramID = (uint16_t)*wptr++; wNofCapsules= (uint16_t)*wptr; //Initialize EEPROM writing wEE_LineW = EE_LINE_START; //reset eprom write count EE_PageW = EE_PAGE_START; //reset eprom page wCIDMissingPrevious = 1; wCIDMissing = 1; bCIDMissing = FALSE; bCommandOK = CMD_STATE_BUSY; //assume we are busy //Ask client to stop/suspend main application etc // -16 capsules per EEPage signal Xnp.NPX_DOWNLOAD_REQ(wProgramID,EE_PageW, wNofCapsules<<4); //now wait for client to respond. If doesnt should have a timeout and goto idle? return;}//fNPXStartDownload/****************************************************************************** NPX_DOWNLOAD_ACK: Acknowledge from Client to proceed/cancel Netprogramming pending download request******************************************************************************/ command result_t Xnp.NPX_DOWNLOAD_ACK(uint8_t cAck ) { uint8_t bRet; if( (sSYSState != SYS_DL_START ) ){ //bogus call from app! sSYSState = SYS_IDLE; bCommandOK = CMD_STATE_WRONGSTATE; return(FALSE); } if( !cAck ) { //Client is not allowing download bCommandOK = CMD_STATE_BUSY; sSYSState = SYS_ACK; }else { //Check status of Battery and return OK/Bad status //Reset/init all states and start bCommandOK = CMD_STATE_BUSY; //still processing the start request sSYSState = SYS_DL_START1; }//ack is OK post NPX_STATEMACHINE();//get going return(FALSE); }/****************************************************************************** fNPXS0RecBuild: Write an S0 record and go...******************************************************************************/void fNPXS0RecBuild(){ wEEProgStart = EE_PageW<<4;//the starting point in EEFlash wCapsuleNo = 0; //update current capsule# -Network capsule# starts at 1 wPIDinFLASH = wProgramID;//Write a pseudo S0 record w/ ProgramID into Flash ELBuff[POS_PID] = (uint8_t) wProgramID; //lsbyte of ProgID ELBuff[POS_PID+1] = (uint8_t)(wProgramID>>8); //ms of address ELBuff[POS_CID] = 0; //capsule number is 0 ELBuff[POS_CID+1] = 0; ELBuff[POS_STYPE] = SREC_S0; //srec9 only has 2byte address ELBuff[POS_SNOFB] = 3; //progid plus crc ELBuff[POS_S0_PID] = (uint8_t)wProgramID; //lsbyte of ProgID ELBuff[POS_S0_PID+1] = (uint8_t)(wProgramID>>8); //ms of address ELBuff[POS_S0_CRC] = 0xAA; //progid plus crc wEE_LineW = wEEProgStart; //2 lines per srec -1st line is S0 bEELineWritePending = TRUE; //main state machine handles posting task and busy retries sSYSState = SYS_EEFLASH_WRITE; post NPX_STATEMACHINE();//store srec to eeprom bCommandOK = CMD_STATE_DONE; return;}//fnpx_downloadgo//======================= LOCAL FUNCTIONS ==================================/********************************************************************************************fNPXGetProgramIDCompare current applications ProgramID with caller If request TS_MSGDATA parameter is TRUE , acknowledge if PIDs matchIf request TS_MSGDATA parameter is FALSE , acknowledge if PIDs do NOT match*******************************************************************************************/void fNPXGetProgramID(TOS_MsgPtr msgptr){//Get programID from ATMEL EEPROM and compare with Network Requested PROGID uint8_t bPIDMatch; uint8_t bIFMatch; uint16_t wlPID; uint16_t *wptr; uint16_t wTemp; bIFMatch = msgptr->data[TS_MSGDATA]; wptr = &(msgptr->data[TS_PID]); wTemp = *wptr; wlPID = eeprom_read_word ((uint16_t *)AVREEPROM_PID_ADDR); bPIDMatch = (wTemp== wlPID); bCommandOK = CMD_STATE_DONE; if( bBCASTMsg ) {//only respond according to flag if( (bIFMatch && bPIDMatch) | (!bIFMatch && !bPIDMatch)) //re match fNPXSendPIDStatus(wlPID); }//broadcast else fNPXSendPIDStatus(wlPID);}/*************************************************************************fNPXSRECStoreGot a code capsule containing 1 srec from radio[0]:commandid[1.2]:program id[3:4]:nofcapsules (srecords)Copies into a local buffer for passing to EEFLASH driver. The source buffer(TOSMsg) is not available after function returns because TOS reuses it.NOTES1.Desireable to reuse msgptr buffer vs EELinebuffer to avoid locking up RAMspace that is used only during boot-download.*************************************************************************/void fNPXSRECStore(TOS_MsgPtr msgptr) { uint8_t bRet,j; unsigned short wTemp; uint8_t cLen; uint8_t cSRecType; uint8_t bSRecValid; uint8_t bFini = FALSE; uint16_t *wptr; if( sSYSMState != SYSM_DOWNLOAD ) { bCommandOK = CMD_STATE_WRONGSTATE; // sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; //back to statemachine } wptr = (uint16_t *)&(msgptr->data[TS_PID]); wTemp = *wptr; if( wTemp != wProgramID ) { //not the same ProgramID so ignore bCommandOK = CMD_STATE_BADSEQUENCE; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; //back to statemachine } //Get and check capsule # wptr = (uint16_t *)&(msgptr->data[TS_CAPSULEID]); wTemp = *wptr; if( wTemp != wCapsuleNo+1 ) { //missed a capsule? if(!bCIDMissing ) {//first one missed? bCIDMissing = TRUE; wCIDMissing = wCapsuleNo+1; wCIDMissingPrevious = wCIDMissing; } wNofLostCapsules = wTemp-wCapsuleNo-1; }//here if wrong capsule # but we continue on... wCapsuleNo = wTemp; //update current capsule# cSRecType = msgptr->data[TS_TYPE]; bSRecValid = fNPXSRECParse( msgptr ); //parse the srec if(!bSRecValid) { bCommandOK = CMD_STATE_BADSTYPE; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; //back to statemachine }//!srecvalid //if srec parsed then save to external flash -Capsule starts at 1 wEE_LineW = wEEProgStart + (wCapsuleNo<<1); //2 lines per srec bCommandOK = CMD_STATE_DONE; bEELineWritePending = TRUE; //main state machine handles posting task and busy retries sSYSState = SYS_EEFLASH_WRITE; post NPX_STATEMACHINE();//store srec to eepromnreturn;} //fnpx_srecstore/*************************************************************************fNPXSRECUpdateGot an update code capsule containing 1 srec from radioReplaces a missing or bad srec in EEFLASH Verifies correct PIDVerifies a valid srecEnables EEFLASH WritewriteRelease EEFLASHCopies into a local buffer for passing to EEFLASH driver. The source buffer(TOSMsg) is not available after function returns because TOS reuses it.NOTES*************************************************************************/void fNPXSRECUpdate(TOS_MsgPtr msgptr) { uint8_t bRet,j; unsigned short wTemp; uint8_t cLen; uint8_t cSRecType; uint8_t bSRecValid; uint8_t bFini = FALSE; uint16_t *wptr; if( sSYSMState != SYSM_UPDATE ) { bCommandOK = CMD_STATE_WRONGSTATE; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; } wptr = (uint16_t *)&(msgptr->data[TS_PID]); wTemp = *wptr; if( wTemp != wProgramID ) { //not the same ProgramID downloading bCommandOK = CMD_STATE_BADSEQUENCE; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; } //Get and check capsule # wptr = (uint16_t *)&(msgptr->data[TS_CAPSULEID]); wCapsuleNo = *wptr; //update current capsule# cSRecType = msgptr->data[TS_TYPE]; bSRecValid = fNPXSRECParse( msgptr ); //parse the srec if(!bSRecValid) { bCommandOK = CMD_STATE_BADSTYPE; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; }//!srecvalid //if srec parsed then save to external flash -Capsule starts at 1 wEE_LineW = wEEProgStart + (wCapsuleNo<<1); //2 lines per srec bCommandOK = CMD_STATE_DONE; bEELineWritePending = TRUE; //main state machine handles posting task and busy retries if( !bEEWriteEnabled ) { //here if doing random SREC writes so must Writeenable the EEFLASH bRet = call EEPROMWrite.startWrite(); if( !bRet ) { //eeprom not available bCommandOK = CMD_STATE_BUSY; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; } }//!beeLocked
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -