1 module simpletest; 2 3 import base; 4 5 enum MODEL_REG = 100; 6 7 struct Model 8 { 9 int value; 10 int[18] arr; 11 bool d1, d2, d3; 12 } 13 14 class FMaster : Fiber 15 { 16 Model model1, model2; 17 18 ulong dev; 19 ModbusRTUMaster mb; 20 21 this(ulong dev, string port, string mode) 22 { 23 this.dev = dev; 24 mb = new ModbusRTUMaster(port, mode); 25 super(&run); 26 } 27 28 bool complite; 29 30 void run() 31 { 32 // one big query 33 model1 = (cast(Model[])(mb.readInputRegisters(dev, MODEL_REG, Model.sizeof/2)))[0]; 34 35 // many query by one register 36 foreach (i; 0 .. Model.sizeof/2) 37 (cast(ushort[])((cast(void*)&model2)[0..Model.sizeof]))[i] = 38 (cast(ushort[])(mb.readInputRegisters(dev, cast(ushort)(MODEL_REG+i), ushort(1))))[0]; 39 40 complite = true; 41 } 42 } 43 44 class FSlave : Fiber 45 { 46 Model model; 47 48 ModbusRTUSlave mb; 49 50 ushort[] table() @property 51 { return cast(ushort[])cast(void[])[model]; } 52 53 this(ulong dev, string port, string mode) 54 { 55 mb = new ModbusRTUSlave(dev, port, mode); 56 57 mb.func[ModbusRTUSlave.FuncCode.readInputRegisters] = (m) 58 { 59 auto ftus = mb.parseMessageFirstTwoUshorts(m); 60 auto start = ftus[0]; 61 auto count = ftus[1]; 62 63 if (count == 0 || count > 125) return mb.illegalDataValue; 64 if (count > table.length) return mb.illegalDataValue; 65 if (start >= MODEL_REG + table.length || start < MODEL_REG) 66 return mb.illegalDataAddress; 67 68 return mb.packResult(cast(ubyte)(count*2), 69 table[start-MODEL_REG..start-MODEL_REG+count]); 70 }; 71 72 model.value = cast(int)uniform(-100, 100); 73 foreach (i, ref v; model.arr) 74 v = cast(int)uniform(-200, 200); 75 76 super(&run); 77 } 78 79 void run() 80 { 81 while (1) 82 { 83 mb.iterate; 84 yield; 85 } 86 } 87 } 88 89 void simpleTest(string[2] ports) 90 { 91 auto dev = 42; 92 auto mode = "9600:8N1"; 93 94 auto slave = new FSlave(dev, ports[0], mode); 95 auto master = new FMaster(dev, ports[1], mode); 96 97 bool work = true; 98 size_t steps; 99 100 while (work) 101 { 102 if (master.state != Fiber.State.TERM) master.call; 103 if (slave.state != Fiber.State.TERM) slave.call; 104 105 Thread.sleep(1.msecs); 106 107 steps++; 108 if (master.complite) 109 { 110 enforce(master.model1 == slave.model, 111 format("diff models 1: \nm: %s \ns: %s", master.model1, slave.model)); 112 enforce(master.model2 == slave.model, 113 format("diff models 2: \nm: %s \ns: %s", master.model2, slave.model)); 114 115 work = false; 116 writeln("loop steps: ", steps); 117 } 118 } 119 }