boolean MySensor::sendRoute(MyMessage &message) { // Make sure to process any incoming messages before sending (could this end up in recursive loop?) // process(); bool isInternal = mGetCommand(message) == C_INTERNAL; // If we still don't have any node id, re-request and skip this message. if (nc.nodeId == AUTO && !(isInternal && message.type == I_ID_REQUEST)) { requestNodeId(); return false; } if (repeaterMode) { uint8_t dest = message.destination; uint8_t route = getChildRoute(dest); if (route>GATEWAY_ADDRESS && route<BROADCAST_ADDRESS && dest != GATEWAY_ADDRESS) { // --- debug(PSTR("route %d.\n"), route); // Message destination is not gateway and is in routing table for this node. // Send it downstream return sendWrite(route, message); } else if (isInternal && message.type == I_ID_RESPONSE && dest==BROADCAST_ADDRESS) { // Node has not yet received any id. We need to send it // by doing a broadcast sending, return sendWrite(BROADCAST_ADDRESS, message, true); } } if (!isGateway) { // --- debug(PSTR("route parent\n")); // Should be routed back to gateway. bool ok = sendWrite(nc.parentNodeId, message); if (!ok) { // Failure when sending to parent node. The parent node might be down and we // need to find another route to gateway. if (autoFindParent && failedTransmissions > SEARCH_FAILURES) { findParentNode(); } failedTransmissions++; } else { failedTransmissions = 0; } return ok; } return false; }
//Send a block of data to the FPGA, raise the execution signal, wait for the execution // signal to be lowered, then read back up to values of results // startAddress: local address on FPGA input buffer to begin writing at // length: # of bytes to write // inData: data to be sent to FPGA // maxWaitTime: # of seconds to wait until execution timeout // outData: readback data buffer (if function returns successfully) // maxOutLength: maximum length of outData buffer provided // outputLength: number of bytes actually returned (if function returns successfully) // Returns true if entire process is successful. // If function fails for any reason, returns false. // Check error code with getLastError(). // error == FAILCAPACITY: The output was larger than provided buffer. Rather than the number of // bytes actually returned, the outputLength variable will contain the TOTAL number bytes the // function wanted to return (the number of bytes actually returned will be maxOutLength). // If this occurs, user should read back bytes {maxOutLength, outputLength - 1} manually // with a subsequent sendRead command. // error == FAILREADACK: The write and execution phases completed correctly, but we retried // the readback phase too many times. In this case, like the FAILCAPICITY error, outputLength // will contain the TOTAL number bytes the function wanted to return. The state of outData is unknown, // but some data has been partially written. The user could try calling sendRead // from {0, outputLength-1} manually if re-calling sendWriteAndRun is not easy // (for example, if inData and outData overlapped). // error == anything else: see normal error list BOOL PICO_SIRC::sendWriteAndRun(uint32_t startAddress, uint32_t inLength, uint8_t *inData, uint32_t maxWaitTimeInMsec, uint8_t *outData, uint32_t maxOutLength, uint32_t *outputLength) { setLastError( 0); //Check the input parameters if(!inData){ setLastError( INVALIDBUFFER); return false; } if(startAddress > OUTPUT_OFFSET){ setLastError( INVALIDADDRESS); return false; } if(inLength == 0 || startAddress + inLength > OUTPUT_OFFSET){ setLastError( INVALIDLENGTH); return false; } //Check the output parameters if(!outData){ setLastError( INVALIDBUFFER); return false; } if(maxOutLength == 0 || maxOutLength > OUTPUT_OFFSET){ setLastError( INVALIDLENGTH); return false; } //Send the data to the FPGA if (!sendWrite(startAddress,inLength,inData)){ return false; } //Send the run cmd if (!sendRun()){ return false; } //Wait till done if (!waitDone( maxWaitTimeInMsec)){ return false; } //Read back data //BUGBUG what about partial results?? if (!sendRead(0,maxOutLength,outData)){ return false; } *outputLength = maxOutLength; //and done return true; }
/***************************************************************************** DISCRIPTION : コマンドスレッドメイン1 ARGUMENT : argc argv RETURN : 0 = 正常終了 0以外 = 異常終了 NOTE : - UPDATED : 2014-06-22 *****************************************************************************/ int command_main(int argc, char** argv) { char* pcBuf; int iSize; uint32 ulAddr = 0x00003034; sendUse(SERIAL_DEFAULT_DEV); while(1) { sendWrite("cmd> "); /* コンソールからの受信文字列を受け取る */ kzRecv(MSGBOX_ID_CONS_INPUT, &iSize, &pcBuf); pcBuf[iSize] = '\0'; if(strncmp(pcBuf, "echo", 4) == TRUE) { sendWrite(&pcBuf[4]); sendWrite("\n"); } #if 1 else if(strncmp(pcBuf, "usb", 3) == TRUE) { usb_main(0,NULL); } #endif else if(pcBuf[0] == '\0') { /* 何もしない */ } else if(strcmp(pcBuf, "0000") == TRUE) { //pFuncEntry = (int (*)(int argc, char** argv))ppcOsEntryFp; //pFuncEntry(1, ppcOsEntryFp); ((void (*)())ulAddr)(); } else { sendWrite("unknown.\n"); } kzMfree(pcBuf); } return 0; }
void MySensor::findParentNode() { failedTransmissions = 0; // Set distance to max nc.distance = 255; // Send ping message to BROADCAST_ADDRESS (to which all relaying nodes and gateway listens and should reply to) build(msg, nc.nodeId, BROADCAST_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT, false).set(""); sendWrite(BROADCAST_ADDRESS, msg, true); // Wait for ping response. waitForReply(); }
static bool sendAndWait(uint8_t reqType, uint8_t resType) { outMsg.type = reqType; // outer loop, retries for (uint8_t i = 0; i < MAX_RESEND; i++) { sendWrite(outMsg); // loop 20 times, wait time 0.1s if no/wrong data => 2s for (uint8_t j = 0; j < 20; j++) { // loop 100 times, wait 1ms if no/wrong data => 0.1s for (uint8_t k = 0; k < 100; k++) { watchdogReset(); // Tx FIFO data available? (we don't care about the pipe here) if (available(NULL)) { // read message from FIFO, skip if size = 0 if (readMessage(inMsg.array) > 0) { // protocol compatible? if not ignore msg if ((mGetVersion(inMsg) != PROTOCOL_VERSION)) { continue; } // msg for us? if (inMsg.destination == nc.nodeId) { // internal command: find parent if ((mGetCommand(inMsg) == C_INTERNAL) && (inMsg.type == I_FIND_PARENT_RESPONSE)) { // static parent found? if (configuredParentID == inMsg.sender) { configuredParentFound = true; } if ( ((inMsg.bValue < nc.distance - 1) && ( !configuredParentFound) ) || (configuredParentID == inMsg.sender)) { // got new routing info, update settings nc.distance = inMsg.bValue + 1; nc.parentNodeId = inMsg.sender; } } // did we receive expected reply? if ((mGetCommand(inMsg) == mGetCommand(outMsg)) && (inMsg.type == resType)) { return true; } } } } else { // wait 1ms if no data available _delay_ms(1); } } } } return false; }
boolean MySensor::process() { uint8_t pipe; boolean available = RF24::available(&pipe); if (!available || pipe>6) return false; uint8_t len = RF24::getDynamicPayloadSize(); RF24::read(&msg, len); RF24::writeAckPayload(pipe,&pipe, 1 ); // Add string termination, good if we later would want to print it. msg.data[mGetLength(msg)] = '\0'; debug(PSTR("read: %d-%d-%d s=%d,c=%d,t=%d,pt=%d,l=%d:%s\n"), msg.sender, msg.last, msg.destination, msg.sensor, mGetCommand(msg), msg.type, mGetPayloadType(msg), mGetLength(msg), msg.getString(convBuf)); if(!(mGetVersion(msg) == PROTOCOL_VERSION)) { debug(PSTR("version mismatch\n")); return false; } uint8_t command = mGetCommand(msg); uint8_t type = msg.type; uint8_t sender = msg.sender; uint8_t last = msg.last; uint8_t destination = msg.destination; if (repeaterMode && command == C_INTERNAL && type == I_FIND_PARENT) { // Relaying nodes should always answer ping messages // Wait a random delay of 0-2 seconds to minimize collision // between ping ack messages from other relaying nodes delay(millis() & 0x3ff); sendWrite(sender, build(msg, nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_RESPONSE, false).set(nc.distance), true); return false; } else if (destination == nc.nodeId) { // Check if sender requests an ack back. if (mGetRequestAck(msg)) { // Copy message ack = msg; mSetRequestAck(ack,false); // Reply without ack flag (otherwise we would end up in an eternal loop) mSetAck(ack,true); ack.sender = nc.nodeId; ack.destination = msg.sender; sendRoute(ack); } // This message is addressed to this node if (repeaterMode && last != nc.parentNodeId) { // Message is from one of the child nodes. Add it to routing table. addChildRoute(sender, last); } if (command == C_INTERNAL) { if (type == I_FIND_PARENT_RESPONSE && !isGateway) { // We've received a reply to a FIND_PARENT message. Check if the distance is // shorter than we already have. uint8_t distance = msg.getByte(); if (distance<nc.distance-1) { // Found a neighbor closer to GW than previously found nc.distance = distance + 1; nc.parentNodeId = msg.sender; eeprom_write_byte((uint8_t*)EEPROM_PARENT_NODE_ID_ADDRESS, nc.parentNodeId); eeprom_write_byte((uint8_t*)EEPROM_DISTANCE_ADDRESS, nc.distance); debug(PSTR("new parent=%d, d=%d\n"), nc.parentNodeId, nc.distance); } return false; } else if (sender == GATEWAY_ADDRESS) { bool isMetric; if (type == I_REBOOT) { wdt_enable(WDTO_15MS); for (;;); } else if (type == I_ID_RESPONSE) { if (nc.nodeId == AUTO) { nc.nodeId = msg.getByte(); // Write id to EEPROM if (nc.nodeId == AUTO) { // sensor net gateway will return max id if all sensor id are taken debug(PSTR("full\n")); while (1); // Wait here. Nothing else we can do... } else { RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId)); eeprom_write_byte((uint8_t*)EEPROM_NODE_ID_ADDRESS, nc.nodeId); } debug(PSTR("id=%d\n"), nc.nodeId); } } else if (type == I_CONFIG) { // Pick up configuration from controller (currently only metric/imperial) // and store it in eeprom if changed isMetric = msg.getByte() == 'M' ; if (cc.isMetric != isMetric) { cc.isMetric = isMetric; eeprom_write_byte((uint8_t*)EEPROM_CONTROLLER_CONFIG_ADDRESS, isMetric); //eeprom_write_block((const void*)&cc, (uint8_t*)EEPROM_CONTROLLER_CONFIG_ADDRESS, sizeof(ControllerConfig)); } } else if (type == I_CHILDREN) { if (repeaterMode && msg.getByte() == 'C') { // Clears child relay data for this node debug(PSTR("rd=clear\n")); for (uint8_t i=0;i< sizeof(childNodeTable); i++) { removeChildRoute(i); } sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_CHILDREN,false).set("")); } } else if (type == I_TIME) { if (timeCallback != NULL) { // Deliver time to callback timeCallback(msg.getULong()); } } return false; } } // Call incoming message callback if available if (msgCallback != NULL) { msgCallback(msg); } // Return true if message was addressed for this node... return true; } else if (repeaterMode && pipe == CURRENT_NODE_PIPE) { // We should try to relay this message to another node uint8_t route = getChildRoute(msg.destination); if (route>0 && route<255) { // This message should be forwarded to a child node. If we send message // to this nodes pipe then all children will receive it because the are // all listening to this nodes pipe. // // +----B // -A // +----C------D // // We're node C, Message comes from A and has destination D // // lookup route in table and send message there sendWrite(route, msg); } else { // A message comes from a child node and we have no // route for it. // // +----B // -A // +----C------D <-- Message comes from D // // We're node C // // Message should be passed to node A (this nodes relay) // This message should be routed back towards sensor net gateway sendWrite(nc.parentNodeId, msg); // Add this child to our "routing table" if it not already exist addChildRoute(sender, last); } } return false; }
void FtpServer::sendCatWrite( const char * s ) { sendCat( s ); sendWrite(); }
void FtpServer::sendWrite( const char * s ) { sendBegin( s ); sendWrite(); }
void SMPCache::doWrite(MemRequest *mreq) { PAddr addr = mreq->getPAddr(); Line *l = cache->writeLine(addr); //LINE exists in cache #ifdef TLS if (l && !l->isLocked()) { if (mreq->isDataReq()==true){ //Check for Epoch match //If Epoch mismatch -read miss, invalidate line if (l->getEpoch()!=mreq->getEpoch()) { l=0; if(!l && mreq->getMemOperation() == MemWrite) { mreq->mutateWriteToRead(); } if (!mutExclBuffer->issue(addr)) { mutExclBuffer->addEntry(addr, sendWriteCB::create(this, mreq), sendReadCB::create(this, mreq)); return; } invalidateLineTLS(mreq); mutExclBuffer->retire(addr); epochMissW.inc(); } //WRITE HIT----------------------- else { //Broadcast write hit on bus- if If others exposed is set if (l->getCacheFlags()->getOE()) { (l->getCacheFlags())->setWordWM(getOffsetInLine(addr)); if(mreq->getMemOperation() == MemWrite) { mreq->mutateWriteToRead(); } writeHitProp.inc();//write hit but broadcast writeHit.inc();//Propagated hits still counted if (!mutExclBuffer->issue(addr)) { mutExclBuffer->addEntry(addr, sendWriteCB::create(this, mreq), sendWriteCB::create(this, mreq)); return; } sendWrite(mreq); return; } //Dont broadcast else { writeHit.inc(); outsReq->retire(addr); (l->getCacheFlags())->setWordWM(getOffsetInLine(addr)); mreq->goUp(hitDelay); return; } } } else{ writeHit.inc(); outsReq->retire(addr); mreq->goUp(hitDelay); return; } } #else if (l && l->canBeWritten()) { writeHit.inc(); outsReq->retire(addr); mreq->goUp(hitDelay); return; } #endif //LINE LOCKED RETRY if (l && l->isLocked()) { writeRetry.inc(); doWriteCB::scheduleAbs(nextSlot(), this, mreq); return; } GI(l, !l->isLocked()); // this should never happen unless this is highest level because L2 // is inclusive; there is only one case in which this could happen when // SMPCache is used as an L2: // 1) line is written in L1 and scheduled to go down to L2 // 2) line is invalidated in both L1 and L2 // 3) doWrite in L2 is executed after line is invalidated if(!l && mreq->getMemOperation() == MemWrite) { mreq->mutateWriteToRead(); } writeMiss.inc(); if (!mutExclBuffer->issue(addr)) { mutExclBuffer->addEntry(addr, sendWriteCB::create(this, mreq), sendWriteCB::create(this, mreq)); return; } sendWrite(mreq); }