//调用前应对地址数组排序(是否加锁?),先一整块PDU读取到 缓存中,然后再逐个从缓存中 读取到各变量地址中 public static ItemData <Storage>[] PLCReadMultiple(this IPLCDriver plc, ICache cache, DeviceAddress[] addrsArr) { if (addrsArr == null || cache == null || addrsArr.Length == 0) { return(null); } int len = addrsArr.Length; //读取的 变量地址的个数 ItemData <Storage>[] items = new ItemData <Storage> [len]; //需要填充的列表 int offset = 0; long now = DateTime.Now.ToFileTime(); List <PDUArea> areas = cache.AssignFromPDU(plc.PDU, addrsArr); foreach (PDUArea area in areas) { byte[] rcvBytes = plc.ReadBytes(area.Start, (ushort)area.Len); Buffer.BlockCopy(rcvBytes, 0, cache.Cache, offset, rcvBytes.Length); offset += rcvBytes.Length / cache.ByteCount; } for (int i = 0; i < len; i++) { switch (addrsArr[i].VarType) { case DataType.BOOL: items[i].Value.Boolean = cache.ReadBit(addrsArr[i]).Value; break; case DataType.BYTE: items[i].Value.Byte = cache.ReadByte(addrsArr[i]).Value; break; case DataType.WORD: items[i].Value.Word = cache.ReadUInt16(addrsArr[i]).Value; break; case DataType.SHORT: items[i].Value.Int16 = cache.ReadInt16(addrsArr[i]).Value; break; case DataType.DWORD: items[i].Value.DWord = cache.ReadUInt32(addrsArr[i]).Value; break; case DataType.INT: items[i].Value.Int32 = cache.ReadInt32(addrsArr[i]).Value; break; case DataType.FLOAT: items[i].Value.Single = cache.ReadFloat(addrsArr[i]).Value; break; case DataType.STR: var item = cache.ReadString(addrsArr[i], addrsArr[i].DataSize); break; } items[i].Quality = QUALITIES.QUALITY_GOOD; items[i].TimeStamp = now; } return(items); }
public TagListGroup(short id, string name, int updateRate, int size, bool active, IPLCDriver plcReader) { this._id = id; this._updateRate = updateRate; this._isActive = active; this._reader = plcReader; this._name = name; this._server = _reader.Parent; }
public static int PLCWriteMultiple(this IPLCDriver plc, ICache cache, DeviceAddress[] addrArr, object[] buffer, int limit) { if (cache == null || addrArr == null || buffer == null || addrArr.Length != buffer.Length) { return(-1); } if (addrArr.Length == 1) { return(plc.WriteValue(addrArr[0], buffer[0])); } lock (plc) //不锁定会有并发冲突问题;锁定也不能保障绝对安全,如有人现场操作会导致数据刷新 { List <PDUArea> areas = cache.AssignFromPDU(plc.PDU, addrArr); int offset = 0; foreach (PDUArea area in areas) { byte[] rcvBytes = plc.ReadBytes(area.Start, (ushort)area.Len); if (rcvBytes == null) { return(-1); } Buffer.BlockCopy(rcvBytes, 0, cache.Cache, offset, rcvBytes.Length); offset += rcvBytes.Length / cache.ByteCount; } DeviceAddress start = addrArr[0]; int startIndex = 0; int endIndex = 0; while (endIndex < addrArr.Length) { if (start.Area != addrArr[endIndex].Area || start.DBNumber != addrArr[endIndex].DBNumber || endIndex - startIndex >= limit) { for (int i = startIndex; i < endIndex; i++) { cache.WriteValue(addrArr[i], buffer[i]); } int c1 = start.CacheIndex; int c2 = addrArr[endIndex - 1].CacheIndex; byte[] bytes = new byte[cache.ByteCount * (c2 - c1 + 1)]; Buffer.BlockCopy(cache.Cache, c1, bytes, 0, bytes.Length); if (plc.WriteBytes(start, bytes) < 0) { return(-1); } start = addrArr[endIndex]; startIndex = endIndex; } endIndex++; } } return(0); }
public PLCGroup(short id, string name, int updateRate, bool active, IPLCDriver plcReader) { this._id = id; this._name = name; this._updateRate = updateRate; this._isActive = active; this._plcReader = plcReader; this._server = _plcReader.Parent; this._changedList = new List <int>(); this._cacheReader = new ByteCacheReader(); this._timer = new Timer(); }
public NetBytePLCGroup(short id, string name, int updateRate, bool active, IPLCDriver plcReader) { this._id = id; this._name = name; this._updateRate = updateRate; this._isActive = active; this._plcReader = plcReader; this._server = _plcReader.Parent; this._timer = new Timer(); this._changedList = new List <int>(); //this._cacheReader = new NetByteCacheReader();//这个是网络字节序,big endian this._cacheReader = new ByteCacheReader();//这个是小端字节序,little endian }