Open bensands opened 11 months ago
I have written a python script to test the block file transfer and remove our application and west's updater from the equation. The python script can be used with CANopenDemo (https://github.com/CANopenNode/CANopenDemo/tree/master). To run the test, do the following:
make
in CANopenDemo/demo)./demoLinuxDevice can0 -i 4
python3 canblock.py can1 4
(The interface name should be different from above but the node_id should be the same.)The script will send 64 KBytes from the sender interface to the reciever interface. I timed this transfer varying the sender and reciever between NeoVI channels and USB CAN adapters and had the following results:
canblock.py:
# Test script for CANopen block transfer
import canopen
import sys
if len(sys.argv) < 3:
print("Usage: python3 canblock.py interface node_id")
exit()
interface = sys.argv[1]
node_id = sys.argv[2]
# copy this file from CANopenDemo/demo/demoDevice.eds
eds_file = 'demoDevice.eds'
net = canopen.Network()
net.connect(channel=interface, bustype='socketcan')
node = net.add_node(int(node_id), eds_file)
bytes_to_send = 1024 * 64
chunk_size = 1024
# domainDemo expects a repeating sequence of bytes from 0 to 255
data = bytes([i for i in range(256)] * (chunk_size // 256))
sent = 0;
outfile = node.sdo[0x2122].open('wb', size=bytes_to_send)
while sent < bytes_to_send:
if bytes_to_send - sent < chunk_size:
chunk_size = bytes_to_send - sent
outfile.write(data[:chunk_size])
sent += chunk_size
outfile.close()
Hello @bensands, thanks for your detailed report and example! Apologies for the delayed response. Using your sample script I was able to confirm the behavior as reported. Messages are sent at the correct bit rate but with a time delta of about 4 milliseconds between frames. I did a deep dive on the performance of the kernel driver and icsscand; removing the CANOpen library from the equation and using either canutils (e.g. cangen vcan0 -g 0.15 -D 11223344DEADBEEF -L 8
) or PythonCAN I can confirm ~150 microseconds between frames is achievable. I have not yet identified what in the CANOpen library or its interface with our SocketCAN layer is causing this delay.
Thanks for the update, @kjohannes-intrepidcs. I would add that due to the results we had with the USB CAN device, it is probably not an issue inherent to CANopen itself but rather, as you say, the interface between CANopen and socketCAN.
I am updating device firmware over CAN. Devices are running canopennode stack. On the sender side we are using zephyr/west's firmware update tool (i.e.
west flash -r canopen ...
) which under the hood uses CANopen for python's block transfer (https://canopen.readthedocs.io/en/stable/sdo.html)Using the neoVI Fire 3, icsscand, and Intrepid socketcan kernel module, we are sending a 192 Kbyte file in about 4 minutes. For a point of comparison, we have a USB to CAN adapter (https://www.amazon.com/dp/B0CDGGBZDT) and the same file transfer takes 40 seconds.
Also of note, we have verified on an oscilloscope that the bitrate is 1Mbps but there are long gaps between the messages.