protected override void EvaluateAction(CommAction action) { base.EvaluateAction(action); }
public virtual byte[] SDOUpLoad(UInt16 index, byte subIndex) { byte[] result = null; SDOUpload upload = new SDOUpload(index, subIndex); this.pendingAction = upload; this.ScheduleAction(this.pendingAction); this.commEvent.Reset(); bool actionResult = this.commEvent.WaitOne(500); if (false != actionResult) { result = upload.Data; } return (result); }
public virtual void Update() { CommStates processedState; do { processedState = this.commState; switch (this.commState) { case CommStates.idle: { lock (this) { if (this.actionQueue.Count != 0) { this.action = (CommAction)this.actionQueue.Dequeue(); } } if (null != this.action) { this.commAttemptCount = 0; this.commState = CommStates.tx; //Tracer.WriteHigh(TraceGroup.CANBUS, "", "action start"); } break; } case CommStates.tx: { this.commAttemptCount++; if (this.commAttemptCount <= this.action.RetryAttemptLimit) { int cobId = 0; byte[] frameData = this.action.GetTransmitFrame(ref cobId, this.NodeId); if (null != frameData) { bool txResult = this.Transmit(cobId, frameData); if (false != txResult) { this.action.TransmitComplete(); bool responseNeeded = this.action.ResponseNeeded(); if (false != responseNeeded) { //Tracer.WriteHigh(TraceGroup.CANBUS, "", "tx pending"); this.commTimeLimit = DateTime.Now.AddMilliseconds(this.action.RetryTime); this.commState = CommStates.rxWait; } else { this.EvaluateAction(this.action); this.action = null; this.commState = CommStates.idle; } } else { Tracer.WriteHigh(TraceGroup.CANBUS, "", "tx fail"); this.commTimeLimit = DateTime.Now.AddMilliseconds(this.TransmitFailureHoldoffTime); this.commState = CommStates.txWait; } } else { this.action = null; this.commState = CommStates.idle; } } else { this.Fault("comm failure"); this.action = null; } break; } case CommStates.txWait: { if (DateTime.Now > this.commTimeLimit) { this.commState = CommStates.tx; } break; } case CommStates.rxWait: { if (false != this.action.Done) { this.EvaluateAction(this.action); if (false != this.action.Aborted) { this.Fault("comm abort"); } this.action = null; this.commState = CommStates.idle; } else if (false != this.action.Transmit) { this.commAttemptCount = 0; this.commState = CommStates.tx; } else if (DateTime.Now > this.commTimeLimit) { this.commState = CommStates.tx; Tracer.WriteHigh(TraceGroup.CANBUS, "", "response timeout"); } break; } case CommStates.error: { break; } } } while (processedState != this.commState); if (null == this.FaultReason) { if ((false != this.consumerHeartbeatActive) && (DateTime.Now > this.consumerHeartbeatTimeLimit)) { this.Fault("heartbeat missing"); } } #region Download Process if (false != this.downloadActive) { string downloadResult = null; bool downloadComplete = false; if (null != this.FaultReason) { downloadComplete = true; downloadResult = "Device faulted: " + this.FaultReason; } else if (false != this.downloadCancel) { downloadComplete = true; downloadResult = "Cancelled"; } else if (DownloadSteps.start == this.downloadStep) { if (File.Exists(this.downloadFile) != false) { FileStream fs = File.Open(this.downloadFile, FileMode.Open); BinaryReader br = new BinaryReader(fs); this.downloadImagePosition = 0; this.downloadImageSize = (UInt32)fs.Length; this.downloadData = br.ReadBytes((int)this.downloadImageSize); br.Close(); br.Dispose(); fs.Close(); fs.Dispose(); this.receiveBootupHeartbeart = false; this.downloadAction = new NetworkRequest(0x80, this.NodeId); bool result = this.ScheduleAction(this.downloadAction); if (false != result) { this.downloadTimeLimit = DateTime.Now.AddMilliseconds(700); this.downloadStep = DownloadSteps.waitReset; } else { downloadResult = "Unable to schedule reset."; downloadComplete = true; } } else { downloadResult = "Unable to open file."; downloadComplete = true; } } else if (DownloadSteps.waitReset == this.downloadStep) { if ((null == this.downloadAction) && (false != this.receiveBootupHeartbeart)) { this.downloadTimeLimit = DateTime.Now.AddMilliseconds(500); this.downloadStep = DownloadSteps.waitBootStart; } else if (DateTime.Now > this.downloadTimeLimit) { this.downloadTimeLimit = DateTime.Now.AddMilliseconds(500); this.downloadStep = DownloadSteps.waitBootStart; } } else if (DownloadSteps.waitBootStart == this.downloadStep) { if (DateTime.Now > this.downloadTimeLimit) { this.downloadAction = new SDODownload(0x1F50, 1, this.downloadData, 0, this.downloadData.Length); bool result = this.ScheduleAction(this.downloadAction, 5000, 1); if (false != result) { this.downloadStep = DownloadSteps.waitFirmwareDownload; } else { downloadResult = "Unable to schedule download."; downloadComplete = true; } } } else if (DownloadSteps.waitFirmwareDownload == this.downloadStep) { if (null != this.downloadAction) { this.downloadImagePosition = ((SDODownload)this.downloadAction).SentCount; } else { this.downloadImagePosition = this.downloadImageSize; this.downloadAction = new SDODownload(0x1F51, 1, 1, 1); bool result = this.ScheduleAction(this.downloadAction); if (false != result) { this.downloadTimeLimit = DateTime.Now.AddSeconds(2); this.downloadStep = DownloadSteps.waitStartRequest; } else { downloadResult = "Unable to schedule start."; downloadComplete = true; } } } else if (DownloadSteps.waitStartRequest == this.downloadStep) { if (null == this.downloadAction) { downloadResult = null; downloadComplete = true; } } else { downloadResult = "Unknown step."; downloadComplete = true; } if (false != downloadComplete) { this.downloadData = null; this.downloadActive = false; this.downloadCompleteHandler(downloadResult); } } #endregion }
protected virtual void EvaluateAction(CommAction action) { if (this.pendingAction == action) { this.pendingAction = null; this.commEvent.Set(); } else if (this.downloadAction == action) { this.downloadAction = null; } }
public virtual bool SDODownload(UInt16 index, byte subIndex, byte[] data) { SDODownload download = new SDODownload(index, subIndex, data, 0, data.Length); this.pendingAction = download; this.ScheduleAction(this.pendingAction); this.commEvent.Reset(); bool actionResult = this.commEvent.WaitOne(500); return (actionResult); }
/// <summary> /// Sets RPDO eanble. Functional while in device pre-operational state. /// </summary> /// <param name="pdo">RPDO to set, 1..4</param> /// <param name="enabled">boolean, true to enable, false to disable</param> /// <returns>true when successful</returns> protected bool SetRPDOEnable(byte pdo, bool enabled) { bool result = false; if ((pdo >= 1) && (pdo <= 4)) { UInt32 cobId = (UInt32)((pdo * 0x100) + 0x100 + this.NodeId); if (false == enabled) { cobId += 0x80000000; } UInt16 index = this.GetRPDOParameterAddress(pdo); this.pendingAction = new SDODownload(index, 1, 4, cobId); result = this.ExchangeCommAction(this.pendingAction); } return (result); }
/// <summary> /// Sets RPDO transmission type. Functional while in device pre-operational state. /// </summary> /// <param name="pdo">TPDO to set, 1..4</param> /// <param name="typeValue">value to program into transmission type object</param> /// <returns>true when successful</returns> protected bool SetRPDOType(byte pdo, byte typeValue) { UInt16 index = this.GetRPDOParameterAddress(pdo); this.pendingAction = new SDODownload(index, 2, 1, typeValue); bool result = this.ExchangeCommAction(this.pendingAction); return (result); }
/// <summary> /// Sets RPDO mapping. Functional while in device pre-operational state. /// </summary> /// <param name="pdo">RPDO to set, 1..4</param> /// <param name="map">map to set, 1..8</param> /// <param name="index">index to map</param> /// <param name="subIndex">sub index to to map</param> /// <param name="octetCount">number of bytes to map</param> /// <returns>true when successful</returns> protected bool SetRPDOMap(byte pdo, byte map, UInt16 index, byte subIndex, byte octetCount) { UInt16 mapIndex = this.GetRPDOMapAddress(pdo); UInt32 mapDefinition = (UInt32)((index << 16) | (subIndex << 8) | (octetCount * 8)); this.pendingAction = new SDODownload(mapIndex, map, 4, mapDefinition); bool result = this.ExchangeCommAction(this.pendingAction); return (result); }
/// <summary> /// Sets RPDO connection object id. Functional while in device pre-operational state. /// </summary> /// <param name="pdo">TPDO to set, 1..4</param> /// <param name="typeValue">value to program into transmission type object</param> /// <returns>true when successful</returns> protected bool SetRPDOCobId(byte pdo, UInt32 cobId) { UInt16 index = this.GetRPDOParameterAddress(pdo); this.pendingAction = new SDODownload(index, 1, 4, cobId); bool result = this.ExchangeCommAction(this.pendingAction); return (result); }
/// <summary> /// Sets RPDO mapping count. Functional while in device pre-operational state. /// </summary> /// <param name="pdo">RPDO to set, 1..4</param> /// <param name="count">number of mappings</param> /// <returns>true when successful</returns> protected bool SetRPDOMapCount(byte pdo, UInt32 count) { UInt16 mapIndex = this.GetRPDOMapAddress(pdo); this.pendingAction = new SDODownload(mapIndex, 0, 1, count); bool result = this.ExchangeCommAction(this.pendingAction); return (result); }
/// <summary> /// Sets TPDO event time. Functional while in device pre-operational state. /// </summary> /// <param name="pdo">TPDO to set, 1..4</param> /// <param name="mS">number of milliseconds required for time event</param> /// <returns>true when successful</returns> protected bool SetTPDOEventTime(byte pdo, UInt32 mS) { UInt16 index = this.GetTPDOParameterAddress(pdo); this.pendingAction = new SDODownload(index, 5, 2, mS); bool result = this.ExchangeCommAction(this.pendingAction); return (result); }
protected bool ExchangeCommAction(CommAction action, int timeout = 200, int attemptLimit = 2) { bool result = false; if (null == this.FaultReason) { this.pendingAction = action; this.ScheduleAction(action, timeout, attemptLimit); int exchangeLimit = (timeout * attemptLimit) + 50; result = this.commEvent.WaitOne(exchangeLimit); if (false != result) { if (false != action.Aborted) { result = false; } } else { Tracer.WriteHigh(TraceGroup.CANBUS, "", "exchange failure"); } } return (result); }
protected bool ScheduleAction(CommAction action, int timeout, int attemptLimit) { bool result = false; if (CommStates.error != this.commState) { lock (this) { action.RetryTime = timeout; action.RetryAttemptLimit = attemptLimit; this.actionQueue.Enqueue(action); result = true; } // this.Update(); todo how to determine calling context? } return (result); }
protected bool ScheduleAction(CommAction action) { bool result = false; if (CommStates.error != this.commState) { lock (this) { this.actionQueue.Enqueue(action); result = true; } // this.Update(); todo how to determine calling context? } return (result); }