Thanks to visit codestin.com
Credit goes to github.com

Skip to content

RTR Guard Messages Not Handled in LocalNode #564

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

Open
PaulFirs opened this issue Mar 1, 2025 · 4 comments
Open

RTR Guard Messages Not Handled in LocalNode #564

PaulFirs opened this issue Mar 1, 2025 · 4 comments

Comments

@PaulFirs
Copy link

PaulFirs commented Mar 1, 2025

The LocalNode does not seem to handle RTR (Remote Transmission Request) Guard messages. Though it’s a legacy mechanism, according to the CANopen specification, nodes should respond to RTR messages for specific objects, providing a mechanism to check node liveness and data availability. In my experience with real CANopen devices, they often (but not always) respond to these RTR Guard messages.

@sveinse
Copy link
Collaborator

sveinse commented Mar 1, 2025

If not all CANopen devices support it, then I assume this is not a mandatory feature of the CANopen spec? If that's the case, then the discussion should be if our canopen library should support RTR, yes?

I skimmed through the 301 spec. There is a number of features related to RTR (which I frankly have to admit I've never noticed), but I can't seem to find any statements that it MUST be supported either.

What's your use-case for RTR with LocalNode? Remote indication on PDOs?

@PaulFirs
Copy link
Author

PaulFirs commented Mar 1, 2025

@sveinse Yes, you’re right, it’s not required. For some reason, I thought that was a given. Apologies for the confusion! My main use case for RTR with LocalNode is for quick node liveness detection. A master device can send a COB-ID 0x700 + NodeID RTR, and the LocalNode would respond with its current NMT state. This allows checking the node’s state if it doesn’t have a heartbeat configured or if the boot-up message was missed.

@acolomb
Copy link
Member

acolomb commented Mar 1, 2025

RTR must be supported in the controller if I'm not mistaken. It's a feature on a very low level. As I understand it from my learning of CAN protocols year's back: Some device starts transmitting the frame with the RTR bit set during the arbitration phase. The addressed node notices that its object is requested and then simply carries on sending the content during the data phase. So both request and response happen within the same CAN frame.

That means that the CAN controller needs to have the response data available immediately. It cannot check back with its host controller to request the data, but must react immediately in the time it takes so send a few bits. That means there is no time for this library to provide the data on request. It has to prepare the data for the CAN controller, which then handles the response internally. How that is done highly depends on the controller and its driver implementation. I doubt we can do anything about it except researching how far the underlying python-can library (and its different backends) supports the feature.

If the request and response happen in two frames, that's basically the SDO protocol, which we do implement.

@PaulFirs
Copy link
Author

PaulFirs commented Mar 1, 2025

On the lower-level side of things: python-can does handle RTR messages just fine! It sees them and passes them on like any other CAN frame. I took advantage of this and wrote my own, very crude version, to get the behavior I wanted.

class MyListener(can.Listener):
    def on_message_received(self, msg: can.Message):
        if msg.is_remote_frame:
            for node in nodes:
                if node.id == msg.arbitration_id - 0x700:
                    code = node.nmt.state
                    node.nmt.send_command(canopen.nmt.NMT_COMMANDS[code])

The interesting bit is that the canopen library is actually actively ignoring RTR messages right now. If you look in network.py, there’s a MessageListener class that specifically filters out RTR messages. https://github.com/christiansandberg/canopen/blob/5382f245d8ede61b113c6a648cb99b199667f0cd/canopen/network.py#L365-L367

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants