9
9
from queue import Queue , Empty
10
10
import threading
11
11
from serial .tools import list_ports
12
+ import platform
12
13
from can import BusABC , CanProtocol , Message , typechecking
13
14
14
15
from ..exceptions import (
29
30
serial = None
30
31
31
32
33
+ HAS_EVENTS = False
34
+
35
+ try :
36
+ from _overlapped import CreateEvent
37
+ from _winapi import WaitForSingleObject
38
+
39
+ HAS_EVENTS = True
40
+ except ImportError :
41
+ WaitForSingleObject = None
42
+ HAS_EVENTS = False
43
+
44
+
32
45
class slcanBus (BusABC ):
33
46
"""
34
47
slcan interface
@@ -49,6 +62,7 @@ class slcanBus(BusABC):
49
62
}
50
63
51
64
_SLEEP_AFTER_SERIAL_OPEN = 2 # in seconds
65
+ _POLL_INTERVAL = 0.001
52
66
53
67
_OK = b"\r "
54
68
_ERROR = b"\a "
@@ -61,6 +75,8 @@ def __init__(
61
75
ttyBaudrate : int = 115200 ,
62
76
bitrate : Optional [int ] = None ,
63
77
btr : Optional [str ] = None ,
78
+ poll_interval : float = _POLL_INTERVAL ,
79
+ receive_own_messages : bool = False ,
64
80
sleep_after_open : float = _SLEEP_AFTER_SERIAL_OPEN ,
65
81
rtscts : bool = False ,
66
82
listen_only : bool = False ,
@@ -77,6 +93,8 @@ def __init__(
77
93
Bitrate in bit/s
78
94
:param btr:
79
95
BTR register value to set custom can speed
96
+ :param receive_own_messages:
97
+ See :class:`can.BusABC`.
80
98
:param poll_interval:
81
99
Poll interval in seconds when reading messages
82
100
:param sleep_after_open:
@@ -94,6 +112,8 @@ def __init__(
94
112
:raise CanInitializationError: if the underlying serial connection could not be established
95
113
"""
96
114
self ._listen_only = listen_only
115
+ self .poll_interval = poll_interval
116
+ self .receive_own_messages = receive_own_messages
97
117
98
118
if serial is None :
99
119
raise CanInterfaceNotImplementedError ("The serial module is not installed" )
@@ -126,17 +146,18 @@ def __init__(
126
146
self .set_bitrate_reg (btr )
127
147
self .open ()
128
148
149
+ self ._timestamp_offset = time .time () - time .perf_counter ()
150
+ self .queue_read = Queue ()
151
+ self .event_read = threading .Event ()
152
+ self ._recv_event = CreateEvent (None , 0 , 0 , None ) if HAS_EVENTS else None
153
+ threading .Thread (None , target = self ._read_can_thread , args = (self .event_read ,)).start ()
129
154
super ().__init__ (
130
155
channel ,
131
156
ttyBaudrate = 115200 ,
132
157
bitrate = None ,
133
158
rtscts = False ,
134
159
** kwargs ,
135
160
)
136
- self ._timestamp_offset = time .time () - time .perf_counter ()
137
- self .queue_read = Queue ()
138
- self .event_read = threading .Event ()
139
- threading .Thread (None , target = self ._read_can_thread , args = (self .event_read ,)).start ()
140
161
141
162
def set_bitrate (self , bitrate : int ) -> None :
142
163
"""
@@ -190,12 +211,15 @@ def _recv_internal(self, timeout: Optional[float]):
190
211
except Empty :
191
212
return None , False
192
213
193
- def _read_can_thread (self , event_recv_send_batch_zlg ):
194
- while not event_recv_send_batch_zlg .is_set ():
214
+ def _read_can_thread (self , event_read ):
215
+ while not event_read .is_set ():
195
216
msgs = self ._read_can ()
196
217
for i in msgs :
197
218
self .queue_read .put (i )
198
- time .sleep (0.005 )
219
+ if HAS_EVENTS :
220
+ WaitForSingleObject (self ._recv_event , int (self .poll_interval * 1000 ))
221
+ else :
222
+ time .sleep (self .poll_interval )
199
223
200
224
def _read_can (self ) -> List [Message ]:
201
225
canId = None
@@ -274,6 +298,10 @@ def send(self, msg: Message, timeout: Optional[float] = None) -> None:
274
298
else :
275
299
sendStr = f"t{ msg .arbitration_id :03X} { msg .dlc :d} "
276
300
sendStr += msg .data .hex ().upper ()
301
+ if self .receive_own_messages :
302
+ msg .is_rx = False
303
+ msg .timestamp = self ._timestamp_offset + time .perf_counter () # Better than nothing...
304
+ self .queue_read .put (msg )
277
305
self ._write (sendStr )
278
306
279
307
def shutdown (self ) -> None :
0 commit comments