Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug fixes, send/receive debug logs and Unsigned 24 support #267

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion canopen/pdo/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ def get_data(self):
data = data | (~((1 << self.length) - 1))
data = od_struct.pack(data)
else:
data = self.pdo_parent.data[byte_offset:byte_offset + len(self.od) // 8]
data = self.pdo_parent.data[byte_offset:byte_offset + self.length // 8]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the cached value here seems like a good idea, but it does change the semantics. That should at least be explained in the commit message.

Why not apply the same treatment in set_data()? Is there maybe some intentional reason len(self.od) and self.length are both used in these functions?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't think of any reason len (self. OD) is used here.
Somehow len (self.od) changed during the program execution and wasn't equal to self.length when get_data was called. It made the returned data to be in the wrong size. Changing it to self.length fixed the problem.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, len(self.od) returns the number of bits (rounded up to full bytes) that the object consists of according to the node's object dictionary, which is constant. While self.length starts off with the same value, it might be overridden when adding the Variable to a PDO mapping, where you can e.g. specify to map only (the lower) 16 bits of a 32 bit unsigned object. That difference is adjusted in pdo.Map.add_variable().

I agree there are some corner cases in the code that don't deal well with mapping only some bits of an object. But to fix that properly, each use within get_data() and set_data() should be reconsidered individually. Just changing one instance might fix your problem, but cause issues for other users.

By the way, my (hacky) solution so far was to adjust the ObjectDictionary instance to artificially overwrite the data_type member when using partial objects in PDO mappings. That breaks SDO access though, and doesn't cope well with signed numbers (two's complement requires changing the higher bytes as well when crossing zero).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@acolomb This one


return data

Expand Down