-
Notifications
You must be signed in to change notification settings - Fork 214
Description
The Goal
I am trying to write a file from my Windows device to an embedded controller via CANopen. To transfer the file I am using the CiA301 defined Block transfers as implemented in this stack. I have created a script to write to the bus, making use of the block download example from the documentation.
FIRMWARE_PATH = './notebooks/test.txt'
FILESIZE = os.path.getsize(FIRMWARE_PATH)
BLOCK_SIZE = 127
print(FILESIZE) # Size = 20473 bytes
with open(FIRMWARE_PATH, 'rb') as infile, \
interface._node.sdo.open(index=0x2000, subindex=0x2, mode='wb', buffering=BLOCK_SIZE,
size=FILESIZE, block_transfer=True) as outfile:
# Iteratively transfer data without having to read all into memory
while True:
data = infile.read(BLOCK_SIZE)
if not data:
break
outfile.write(data)
The Problem
Running this code correctly starts a block transfer resulting in correct data on the bus (This has been validated using PCAN-View). After transferring 1 ore sometimes a few block of data, an error gets thrown on the python side resulting in ending the transfer.
INFO:canopen.sdo.client:Initiating block download for 0x2000:2
DEBUG:canopen.sdo.client:Expected size of data is 20473 bytes
DEBUG:can.pcan:Data: bytearray(b'\xc6\x00 \x02\xf9O\x00\x00')
DEBUG:can.pcan:Type: <class 'bytearray'>
DEBUG:canopen.sdo.client:Server requested a block size of 127
...
ERROR:canopen.sdo.client:Block transfer was not finished
DEBUG:canopen.sdo.client:Ending block transfer...
DEBUG:can.pcan:Data: bytearray(b'\xdd\x00\x00\x00\x00\x00\x00\x00')
DEBUG:can.pcan:Type: <class 'bytearray'>
Traceback (most recent call last):
File "C:\...\notebooks\test.py", line 32, in <module>
outfile.write(data)
BlockingIOError: [Errno 0] write could not complete without blocking
During handling of the above exception, another exception occurred:
BlockingIOError: [Errno 0] write could not complete without blocking
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\...\notebooks\test.py", line 23, in <module>
with open(FIRMWARE_PATH, 'rb') as infile, \
File "C:\...\.env\lib\site-packages\canopen\sdo\client.py", line 790, in close
raise SdoCommunicationError("Block download unsuccessful")
canopen.sdo.exceptions.SdoCommunicationError: Block download unsuccessful
A BlockingIOError gets thrown resulting in the transfer to be aborted. I sadly enough do not have any other CANopen devices supporting block transfers to fully rule out the embedded side, but the responses from the device follow the CANopen specification. Transferring of small files (2 lines of text) does seem to work, bigger files result in this error (An EDS has been used for this test).
Any ideas what could be the issue, what I am doing wrong or what could be a solution?