44More details.
55"""
66
7- import time
8- from typing import Union
7+ #from typing import Union
98
109from PyQt5 .QtCore import QSharedMemory
1110
1211from ctypes import *
1312import struct
1413
15- class CControlBlock (Structure ):
16- _fields_ = [("flags" , c_ulong ),
17- ("count0x" , c_ulong ),
18- ("count1x" , c_ulong ),
19- ("count3x" , c_ulong ),
20- ("count4x" , c_ulong ),
21- ("cycle" , c_ulong ),
22- ("pycycle" , c_ulong )]
14+ MB_DATAORDER_DEFAULT = - 1
15+ MB_DATAORDER_LITTLEENDIAN = 0
16+ MB_DATAORDER_BIGENDIAN = 1
17+
18+ MB_REGISTERORDER_DEFAULT = - 1
19+ MB_REGISTERORDER_R0R1R2R3 = 0
20+ MB_REGISTERORDER_R3R2R1R0 = 1
21+ MB_REGISTERORDER_R1R0R3R2 = 2
22+ MB_REGISTERORDER_R2R3R0R1 = 3
23+
24+ class CDeviceBlock (Structure ):
25+ _fields_ = [("flags" , c_ulong ),
26+ ("cycle" , c_ulong ),
27+ ("count0x" , c_ulong ),
28+ ("count1x" , c_ulong ),
29+ ("count3x" , c_ulong ),
30+ ("count4x" , c_ulong ),
31+ ("exceptionStatusRef" , c_ulong ),
32+ ("byteOrder" , c_long ),
33+ ("registerOrder" , c_long ),
34+ ("stoDeviceName" , c_ulong ),
35+ ("stringTableSize" , c_ulong )]
36+
37+ class CPythonBlock (Structure ):
38+ _fields_ = [("pycycle" , c_ulong )]
2339
2440class CMemoryBlockHeader (Structure ):
25- _fields_ = [("changeCounter" , c_ulong ),
26- ("changeByteOffset" , c_ulong ),
27- ("changeByteCount" , c_ulong ),
28- ("dummy" , c_ulong )]
29-
30-
31- class _MemoryControlBlock :
32- def __init__ (self , memid :str ):
33- shm = QSharedMemory (memid )
41+ _fields_ = [("changeCounter" , c_ulong ),
42+ ("changeByteOffset" , c_ulong ),
43+ ("changeByteCount" , c_ulong ),
44+ ("dummy" , c_ulong )]
45+
46+
47+ class _MbDevice :
48+ def __init__ (self , memidprefix :str ):
49+ memid_device = memidprefix + ".device"
50+ memid_python = memidprefix + ".python"
51+ memid_mem0x = memidprefix + ".mem0x"
52+ memid_mem1x = memidprefix + ".mem1x"
53+ memid_mem3x = memidprefix + ".mem3x"
54+ memid_mem4x = memidprefix + ".mem4x"
55+ shm = QSharedMemory (memid_device )
3456 res = shm .attach ()
3557 if not res :
36- raise RuntimeError (f"Cannot attach to Shared Memory with id = '{ memid } '" )
58+ raise RuntimeError (f"Cannot attach to Shared Memory with id = '{ memid_device } '" )
3759 qptr = shm .data ()
3860 size = shm .size ()
3961 memptr = c_void_p (qptr .__int__ ())
40- pcontrol = cast (memptr , POINTER (CControlBlock ))
62+ pcontrol = cast (memptr , POINTER (CDeviceBlock ))
4163 self ._shm = shm
4264 self ._pcontrol = pcontrol
4365 self ._control = pcontrol .contents
66+ self ._shm .lock ()
67+ self ._count0x = int (self ._control .count0x )
68+ self ._count1x = int (self ._control .count1x )
69+ self ._count3x = int (self ._control .count3x )
70+ self ._count4x = int (self ._control .count4x )
71+ self ._excstatusref = int (self ._control .exceptionStatusRef )
72+ self ._byteorder = int (self ._control .byteOrder )
73+ self ._registerorder = int (self ._control .registerOrder )
74+ self ._strtablesize = int (self ._control .stringTableSize )
75+ stoDeviceName = int (self ._control .stoDeviceName )
76+ self ._pmemstrtable = cast (byref (pcontrol [1 ]),POINTER (c_ubyte * 1 ))
77+ self ._name = self ._getstring (stoDeviceName )
78+ self ._shm .unlock ()
79+ # submodules
80+ self ._python = _MemoryPythonBlock (memid_python )
81+ self ._mem0x = _MemoryBlockBits (memid_mem0x , self ._count0x )
82+ self ._mem1x = _MemoryBlockBits (memid_mem1x , self ._count1x )
83+ self ._mem3x = _MemoryBlockRegs (memid_mem3x , self ._count3x )
84+ self ._mem4x = _MemoryBlockRegs (memid_mem4x , self ._count4x )
85+ # Exception status
86+ memtype = self ._excstatusref // 10000
87+ self ._excoffset = (self ._excstatusref % 10000 ) - 1
88+ if memtype == 0 :
89+ self ._excmem = self ._mem0x
90+ elif memtype == 1 :
91+ self ._excmem = self ._mem1x
92+ elif memtype == 3 :
93+ self ._excmem = self ._mem3x
94+ elif memtype == 4 :
95+ self ._excmem = self ._mem4x
96+ else :
97+ self ._excmem = self ._mem0x
98+ self ._excoffset = 0
4499
45100 def __del__ (self ):
46101 try :
47102 self ._shm .detach ()
48103 except RuntimeError :
49104 pass
50105
106+ def _getstring (self , offset :int )-> str :
107+ c = 0
108+ while self ._pmemstrtable [offset + c ][0 ] != 0 :
109+ c += 1
110+ bs = bytes (cast (self ._pmemstrtable [offset ], POINTER (c_ubyte * c ))[0 ])
111+ return bs .decode ('utf-8' )
112+
113+ def getname (self )-> str :
114+ return self ._name
115+
51116 def getflags (self ):
52117 self ._shm .lock ()
53118 r = self ._control .flags
54119 self ._shm .unlock ()
55120 return r
56121
122+ def getcycle (self ):
123+ self ._shm .lock ()
124+ r = self ._control .cycle
125+ self ._shm .unlock ()
126+ return r
127+
57128 def getcount0x (self ):
58129 self ._shm .lock ()
59130 r = self ._control .count0x
@@ -78,21 +149,69 @@ def getcount4x(self):
78149 self ._shm .unlock ()
79150 return r
80151
81- def getcycle (self ):
82- self ._shm .lock ()
83- r = self ._control .cycle
84- self ._shm .unlock ()
85- return r
152+ def getexcstatus (self )-> int :
153+ return self ._excmem .getuint8 (self ._excoffset )
154+
155+ def setexcstatus (self , value :int )-> None :
156+ self ._excmem .setuint8 (self ._excoffset , value )
157+
158+ def getbyteorder (self ):
159+ return self ._byteorder
160+
161+ def getregisterorder (self ):
162+ return self ._registerorder
163+
164+ def getpycycle (self ):
165+ return self ._python .getpycycle ()
166+
167+ def _incpycycle (self ):
168+ return self ._python .incpycycle ()
169+
170+ def getmem0x (self ):
171+ return self ._mem0x
172+
173+ def getmem1x (self ):
174+ return self ._mem1x
175+
176+ def getmem3x (self ):
177+ return self ._mem3x
178+
179+ def getmem4x (self ):
180+ return self ._mem4x
181+
182+
183+ class _MemoryPythonBlock :
184+ def __init__ (self , memid :str ):
185+ shm = QSharedMemory (memid )
186+ res = shm .attach ()
187+ if not res :
188+ raise RuntimeError (f"Cannot attach to Shared Memory with id = '{ memid } '" )
189+ qptr = shm .data ()
190+ self ._memsize = shm .size ()
191+ memptr = c_void_p (qptr .__int__ ())
192+ pcontrol = cast (memptr , POINTER (CPythonBlock ))
193+ self ._shm = shm
194+ self ._pcontrol = pcontrol
195+ self ._control = pcontrol .contents
196+ self ._cyclecounter = 0
197+
198+ def __del__ (self ):
199+ try :
200+ self ._shm .detach ()
201+ except RuntimeError :
202+ pass
203+
86204
87205 def getpycycle (self ):
88206 self ._shm .lock ()
89207 r = self ._control .pycycle
90208 self ._shm .unlock ()
91209 return r
92210
93- def setpycycle (self , value ):
211+ def incpycycle (self ):
212+ self ._cyclecounter += 1
94213 self ._shm .lock ()
95- self ._control .pycycle = value
214+ self ._control .pycycle = self . _cyclecounter
96215 self ._shm .unlock ()
97216
98217
@@ -115,7 +234,7 @@ def __init__(self, memid:str, bytecount:int):
115234 ptrhead = cast (memptr , POINTER (CMemoryBlockHeader ))
116235 self ._head = ptrhead [0 ]
117236 self ._pmembytes = cast (byref (ptrhead [1 ]),POINTER (c_ubyte * 1 ))
118- self ._pmaskbytes = cast (byref (cast (byref (ptrhead [1 ]),POINTER (c_byte * cbytes ))[1 ]),POINTER (c_ubyte * 1 ))
237+ self ._pmaskbytes = cast (byref (cast (byref (ptrhead [1 ]),POINTER (c_byte * cbytes ))[1 ]),POINTER (c_ubyte * 1 ))
119238
120239 def __del__ (self ):
121240 try :
@@ -172,7 +291,7 @@ def getbytearray(self, byteoffset:int, count:int)->bytearray:
172291 """
173292 return self ._getbytes (byteoffset , count , bytearray )
174293
175- def setbytes (self , byteoffset :int , value :Union [bytes , bytearray ])-> None :
294+ def setbytes (self , byteoffset :int , value :type [bytes | bytearray ])-> None :
176295 """
177296 @details
178297 Function set `value` (`bytes` or `bytearray`) array object into device memory
@@ -245,7 +364,7 @@ def getbitbytes(self, bitoffset:int, bitcount:int)->bytes:
245364 """
246365 return bytes (self .getbitbytearray (bitoffset , bitcount ))
247366
248- def setbitbytes (self , bitoffset :int , bitcount :int , value :Union [bytes , bytearray ])-> None :
367+ def setbitbytes (self , bitoffset :int , bitcount :int , value :type [bytes | bytearray ])-> None :
249368 """
250369 @details
251370 Function set `value` (`bytes` or `bytearray`) array object into device memory
0 commit comments