Skip to content

Commit d32c01c

Browse files
committed
Implement multi rate sending for socketcan native. Extend cyclic example.
Closes #58
1 parent 9c75724 commit d32c01c

File tree

2 files changed

+56
-15
lines changed

2 files changed

+56
-15
lines changed

can/interfaces/socketcan_native.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,15 @@ def create_bcm_socket(channel):
126126
return s
127127

128128

129-
class CyclicSendTask(CyclicSendTaskABC):
129+
class SocketCanBCMBase(object):
130+
"""Mixin to add a BCM socket"""
131+
132+
def __init__(self, channel, *args, **kwargs):
133+
self.bcm_socket = create_bcm_socket(channel)
134+
super(SocketCanBCMBase, self).__init__(channel, *args, **kwargs)
135+
136+
137+
class CyclicSendTask(SocketCanBCMBase, CyclicSendTaskABC):
130138

131139
def __init__(self, channel, message, period):
132140
"""
@@ -135,8 +143,7 @@ def __init__(self, channel, message, period):
135143
:param message: The message to be sent periodically.
136144
:param period: The rate in seconds at which to send the message.
137145
"""
138-
super(CyclicSendTask,self).__init__(channel, message, period)
139-
self.bcm_socket = create_bcm_socket(channel)
146+
super(CyclicSendTask, self).__init__(channel, message, period)
140147
self._tx_setup(message)
141148
self.message = message
142149

@@ -169,6 +176,29 @@ def start(self):
169176
self._tx_setup(self.message)
170177

171178

179+
class MultiRateCyclicSendTask(CyclicSendTask):
180+
181+
"""Exposes more of the full power of the TX_SETUP opcode.
182+
183+
Transmits a message `count` times at `initial_period` then
184+
continues to transmit message at `subsequent_period`.
185+
"""
186+
187+
def __init__(self, channel, message, count, initial_period, subsequent_period):
188+
super(MultiRateCyclicSendTask, self).__init__(channel, message, subsequent_period)
189+
190+
# Create a low level packed frame to pass to the kernel
191+
frame = build_can_frame(self.can_id, message.data)
192+
header = build_bcm_transmit_header(
193+
self.can_id,
194+
count,
195+
initial_period,
196+
subsequent_period)
197+
198+
log.info("Sending BCM TX_SETUP command")
199+
self.bcm_socket.send(header + frame)
200+
201+
172202
def createSocket(can_protocol=None):
173203
"""Creates a CAN socket. The socket can be BCM or RAW. The socket will
174204
be returned unbound to any interface.

examples/cyclic.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,40 @@
2020

2121

2222
def test_simple_periodic_send():
23-
print("Trying to send a message...")
24-
msg = can.Message(arbitration_id=0x0cf02200, data=[0, 1, 3, 1, 4, 1])
25-
task = can.send_periodic('vcan0', msg, 0.020)
23+
print("Starting to send a message every 200ms. Initial data is zeros")
24+
msg = can.Message(arbitration_id=0x0cf02200, data=[0, 0, 0, 0, 0, 0])
25+
task = can.send_periodic('vcan0', msg, 0.20)
2626
time.sleep(2)
27+
task.stop()
28+
print("stopped cyclic send")
2729

28-
print("Trying to change data")
29-
msg.data[0] = 99
30+
31+
def test_periodic_send_with_modifying_data():
32+
print("Starting to send a message every 200ms. Initial data is ones")
33+
msg = can.Message(arbitration_id=0x0cf02200, data=[1, 1, 1, 1])
34+
task = can.send_periodic('vcan0', msg, 0.20)
35+
time.sleep(2)
36+
print("Changing data of running task to begin with 99")
37+
msg.data[0] = 0x99
3038
task.modify_data(msg)
3139
time.sleep(2)
3240

3341
task.stop()
3442
print("stopped cyclic send")
35-
43+
print("Changing data of stopped task to single ff byte")
44+
msg.data = bytearray([0xff])
45+
task.modify_data(msg)
3646
time.sleep(1)
37-
task.start()
3847
print("starting again")
48+
task.start()
3949
time.sleep(1)
50+
task.stop()
4051
print("done")
4152

4253

4354
def test_dual_rate_periodic_send():
4455
"""Send a message 10 times at 1ms intervals, then continue to send every 500ms"""
45-
msg = can.Message(arbitration_id=0x0c112200, data=[0, 1, 2, 3, 4, 5])
56+
msg = can.Message(arbitration_id=0x123, data=[0, 1, 2, 3, 4, 5])
4657
print("Creating cyclic task to send message 10 times at 1ms, then every 500ms")
4758
task = can.interface.MultiRateCyclicSendTask('vcan0', msg, 10, 0.001, 0.50)
4859
time.sleep(2)
@@ -60,6 +71,7 @@ def test_dual_rate_periodic_send():
6071
task.start()
6172
print("starting again")
6273
time.sleep(2)
74+
task.stop()
6375
print("done")
6476

6577

@@ -68,12 +80,11 @@ def test_dual_rate_periodic_send():
6880
for interface in {'socketcan_ctypes', 'socketcan_native'}:
6981
print("Carrying out cyclic tests with {} interface".format(interface))
7082
can.rc['interface'] = interface
83+
7184
test_simple_periodic_send()
7285

86+
test_periodic_send_with_modifying_data()
7387

74-
for interface in {'socketcan_ctypes', }:
75-
print("Carrying out cyclic tests with {} interface".format(interface))
88+
print("Carrying out multirate cyclic test for {} interface".format(interface))
7689
can.rc['interface'] = interface
7790
test_dual_rate_periodic_send()
78-
79-
print("socketcan_native doesn't yet support MultiRate Cyclic Tasks")

0 commit comments

Comments
 (0)