Skip to content

Commit

Permalink
Fix SDO writes of empty strings (#551)
Browse files Browse the repository at this point in the history
Previously, when attempting a write of "" to a VISIBLE_STRING, the
expedited SDO request would not be sent and the transaction would
timeout.  To resolve this, if the transaction size is known to be 0, a
segmented transfer is used.
  • Loading branch information
willson556 authored Jan 5, 2025
1 parent ffbd10f commit ae71853
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
2 changes: 1 addition & 1 deletion canopen/sdo/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ def __init__(self, sdo_client, index, subindex=0, size=None, force_segment=False
self._exp_header = None
self._done = False

if size is None or size > 4 or force_segment:
if size is None or size < 1 or size > 4 or force_segment:
# Initiate segmented download
request = bytearray(8)
command = REQUEST_DOWNLOAD
Expand Down
17 changes: 17 additions & 0 deletions test/test_sdo.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ def _send_message(self, can_id, data, remote=False):
while self.data and self.data[0][0] == RX:
self.network.notify(0x582, self.data.pop(0)[1], 0.0)

self.message_sent = True

def setUp(self):
network = canopen.Network()
network.NOTIFIER_SHUTDOWN_TIMEOUT = 0.0
Expand All @@ -76,6 +78,8 @@ def setUp(self):
node.sdo.RESPONSE_TIMEOUT = 0.01
self.network = network

self.message_sent = False

def test_expedited_upload(self):
self.data = [
(TX, b'\x40\x18\x10\x01\x00\x00\x00\x00'),
Expand All @@ -91,6 +95,7 @@ def test_expedited_upload(self):
]
trans_type = self.network[2].sdo[0x1400]['Transmission type RPDO 1'].raw
self.assertEqual(trans_type, 254)
self.assertTrue(self.message_sent)

def test_size_not_specified(self):
self.data = [
Expand All @@ -100,13 +105,15 @@ def test_size_not_specified(self):
# Make sure the size of the data is 1 byte
data = self.network[2].sdo.upload(0x1400, 2)
self.assertEqual(data, b'\xfe')
self.assertTrue(self.message_sent)

def test_expedited_download(self):
self.data = [
(TX, b'\x2b\x17\x10\x00\xa0\x0f\x00\x00'),
(RX, b'\x60\x17\x10\x00\x00\x00\x00\x00')
]
self.network[2].sdo[0x1017].raw = 4000
self.assertTrue(self.message_sent)

def test_segmented_upload(self):
self.data = [
Expand Down Expand Up @@ -153,6 +160,16 @@ def test_block_download(self):
'wb', size=len(data), block_transfer=True) as fp:
fp.write(data)

def test_segmented_download_zero_length(self):
self.data = [
(TX, b'\x21\x00\x20\x00\x00\x00\x00\x00'),
(RX, b'\x60\x00\x20\x00\x00\x00\x00\x00'),
(TX, b'\x0F\x00\x00\x00\x00\x00\x00\x00'),
(RX, b'\x20\x00\x00\x00\x00\x00\x00\x00'),
]
self.network[2].sdo[0x2000].raw = ""
self.assertTrue(self.message_sent)

def test_block_upload(self):
self.data = [
(TX, b'\xa4\x08\x10\x00\x7f\x00\x00\x00'),
Expand Down

0 comments on commit ae71853

Please sign in to comment.