Skip to content

SDO Block Transfer fails with "Unknown SDO command specified" error #599

Description

@dhugoexe

SDO Block Transfer fails with "Unknown SDO command specified" error

Hi everyone, I'm trying to send a binary file over SDO Block Transfer. I've created a Python SDO client that sends to an SDO server (ESP32-based CANopen node).

Environment

  • Python canopen version: 2.3.0
  • Platform: Windows
  • CAN Interface: PCAN USB

Issue Description

The block transfer fails with error Code 0x05040001, Unknown SDO command specified. The server logs show a sequence error during the transfer.

Code to Reproduce

import canopen
print(canopen.__version__)
import os

filename = 'data/data.bin'
network = canopen.Network()
node = canopen.BaseNode402(10, "path_to_od.eds")
network.add_node(node)
network.connect(interface='pcan', channel='PCAN_USBBUS1', bitrate=125000)

filesize = os.path.getsize(filename)
print(f"File size: {filesize} bytes")

try:
   # Send file size
   filesize_bytes = filesize.to_bytes(4, byteorder='little', signed=False)
   node.sdo.download(0x2005, 2, filesize_bytes)
   
   # Send file data using block transfer
   with open(filename, 'rb') as infile, \
        node.sdo[0x2005][3].open('wb', size=filesize, block_transfer=True) as outfile:
       while True:
           data = infile.read(1024)
           if not data:
               break
           outfile.write(data)
   
   print("Block transfer successful!")
   
except Exception as e:
   print(f"Block transfer failed: {e}")
   
network.disconnect()

Error output

Block transfer failed: Code 0x05040001, Unknown SDO command specified

ESP32 Logs

I (41404) CO_driver: CANRX id: 0x60a, dlc: 8, data: [35 5 32 2 244 0 0 0]
I (41413) CO_driver: CANRX id: 0x60a, dlc: 8, data: [198 5 32 3 244 0 0 0]
I (41422) CO_driver: CANRX id: 0x60a, dlc: 8, data: [1 0 0 0 0 49 57 55]
I (41423) CO_driver: CANRX id: 0x60a, dlc: 8, data: [2 48 45 48 49 45 48 49]
I (41425) CO_driver: CANRX id: 0x60a, dlc: 8, data: [3 84 48 48 58 48 49 58]
I (41431) CO_driver: CANRX id: 0x60a, dlc: 8, data: [4 53 50 0 0 0 0 0]
I (41438) CO_driver: CANRX id: 0x60a, dlc: 8, data: [5 0 0 0 0 0 0 0]
I (41444) CO_driver: CANRX id: 0x60a, dlc: 8, data: [6 0 115 121 115 116 101 109]
I (41451) CO_driver: CANRX id: 0x60a, dlc: 8, data: [7 0 0 0 0 0 0 0]
I (41457) CO_driver: CANRX id: 0x60a, dlc: 8, data: [8 0 0 0 0 0 0 0]
I (41463) CO_driver: CANRX id: 0x60a, dlc: 8, data: [11 50 53 45 48 54 45 50]
I (41470) CO_SDO: sub-block, rx WRONG: sequno=0B, previous=08
I (41476) CO_driver: CANRX id: 0x60a, dlc: 8, data: [17 0 0 0 0 0 0 0]
I (41482) CO_driver: CANRX id: 0x60a, dlc: 8, data: [23 0 0 0 0 0 0 0]
I (41488) CO_driver: CANRX id: 0x60a, dlc: 8, data: [31 128 63 0 0 224 64 0]
I (41498) CO_driver: CANRX id: 0x60a, dlc: 8, data: [197 81 178 0 0 0 0 0]

CO_SDO: sub-block, rx WRONG: sequno=0B, previous=08 -> Maybe a packet lost ?

EDS Configuration

[2005]
ParameterName=File transfert
ObjectType=0x9
SubNumber=0x5

[2005sub0]
ParameterName=Highest sub-index supported
ObjectType=0x7
DataType=0x0005
AccessType=ro
DefaultValue=0x04
PDOMapping=0

[2005sub1]
ParameterName=File name
ObjectType=0x7
DataType=0x0009
AccessType=rw
DefaultValue=0
PDOMapping=0

[2005sub2]
ParameterName=File size
ObjectType=0x7
DataType=0x0007
AccessType=rw
DefaultValue=0
PDOMapping=0

[2005sub3]
ParameterName=File data
ObjectType=0x7
DataType=0x000F
AccessType=rw
HighLimit=65536
LowLimit=0
DefaultValue=
PDOMapping=0

[2005sub4]
ParameterName=Transfert status
ObjectType=0x7
DataType=0x0005
AccessType=ro
DefaultValue=0
PDOMapping=0

Questions

  1. Is my Python code correct for SDO block transfer?
  2. Could this be a configuration issue on the ESP32 server side?
  3. Is SDO block transfer fully supported in the Python canopen library? I've seen that the feature might not work correctly on every implementation.

Thanks in advance for any help!

Activity

  1. acolomb commented on Jul 8, 2025

    @acolomb
    Member
    1. Your SDO client code looks correct from a quick glance.
    2. Could be a misconfiguration, or simply the ESP32 not keeping up with incoming CAN messages? That would be my first guess, as the two sequence numbers are missing. Have you check using an independent CAN adapter / analyzer what messages are sent on the bus?
    3. It should be fully supported on the client side, i.e. when the library talks to an SDO server. The server part (using the canopen.node.LocalNode class) does not yet support SDO block transfer, see ongoing work in Server sdo block upload (based on v2.3.0) #559.
  2. ericbaril72 commented on Jul 9, 2025

    @ericbaril72

    Most likely your ESP32.
    I used all transfer modes at one point or another and often had similar issues.

    2 suggestions:

    • use a separate logger
      -> not a logging class within your python code
      -> not via your test/embedded node.

      I often used pcan-view to log those tests.
      Oddly, a WHILE loop without time.sleep would often miss some packets… even with fairly low bus load and baudrate.

    once you have proper LOG…

    • change the delay constants between 2 packets and delay to timeout used by the stack to check if the ESP32 might have some long response or timeouts

    Programming a Curtis VFD via can bootloader proved successful a while ago after increasing one of the delay constants.

    Goodluck

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions