Skip to content
New issue

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

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

Already on GitHub? # to your account

How to support PDO COB-ID based on node ID after it has been changed by LSS? #48

Open
nattgris opened this issue Sep 20, 2021 · 6 comments

Comments

@nattgris
Copy link

I have a pre-defined PDO with a COB-ID that is defined to be based on the node ID. i.e. something like the following in the od_defaults array (much like the example slave):

	{0x1881, 1, 0x40000480 + DEFAULT_NODE_ID }, /* Enable TPDO 130 */

However, when the node ID is changed via LSS, the COB-ID of course still matches the default node ID, not the new one. I see no possible way to fix this.

I have considered patching the defaults array with the new node ID, however the new ID is not available until after the defaults have been applied.

I have also considered using my PR #46 to update the COB-ID later, in the NMT callback when going Pre-operational and the active node ID has been established. However, since this is (at least during startup) still inside the co_init() call, no client has been possible to create to be able to submit jobs to the co_main thread.

@hefloryd
Copy link
Collaborator

When state INIT_COMM is entered, the OD is first initialised with the values in od_defaults, then loaded from CO_STORE_COMM. Would it be possible to store the updated values after an LSS change? Those values should then be restored after every poweron. The od_defaults array was intended as the factory default settings, while the stores are for persistent storage.

@nattgris
Copy link
Author

That could possibly work. But AFAICT there is currently no way outside the stack to 1. know that LSS has changed the node ID, 2. adjust the COB-ID to match the new node ID or 3. manually trigger a store of the communication parameters.

PR #46 could help with the last two points, but as I noticed today while trying another trick (which almost worked), the local write functionality or any normal application API call which uses jobs cannot be used from callbacks or the stack will deadlock.

Otherwise it seemed very promising to reconfigure the PDO in the NMT callback at STATE_INIT_COMM, where the persistent node ID has just been activated and the communication parameters already loaded. It works fine during startup when the NMT callback is called in application context (which is a bit inconsistent that it does). However as soon as there is an NMT reset via the bus, the callback is called in stack context and the local write job locks up the stack thread.

@hefloryd
Copy link
Collaborator

Regardless of this issue it might be useful to add a callback for LSS changes?

In your use-case the COB-ID always follows the node ID, i.e. you can generate them once you have the node ID. Is there not also a use-case where an integrator manually selects COB-ID:s for a network? For that scenario I think you would have to load the COB-ID:s from storage.

For the deadlock issue, we should probably have an api for calling stack functions within the main thread context, i.e performing the job directly without going through the mailbox.

@nattgris
Copy link
Author

nattgris commented Oct 6, 2021

Regardless of this issue it might be useful to add a callback for LSS changes?

Perhaps, but I'm not really sure what you'd need to do there. You'll get a NMT callback anyway and with the recent changes, you can now retrieve the active Node-ID at that point. Perhaps also missing is some means to reset the LSS settings to default, since it can't be done via the normal restore object. Simpy removing the file storing the LSS data works, although a bit crude.

In your use-case the COB-ID always follows the node ID, i.e. you can generate them once you have the node ID. Is there not also a use-case where an integrator manually selects COB-ID:s for a network? For that scenario I think you would have to load the COB-ID:s from storage.

I think there is simply not enough information to know whether a stored COB-ID was "meant" to have that specific value unconditionally, or to have that value given the then-current Node-ID and that it's supposed to change with the Node ID.

I don't have enough experience with LSS to know how this is handled in the wild. It seems this would be a problem even with the default connection set. I.e. as soon as the communication parameters are stored, the stored values override the Node-ID based default COB-IDs. How can a node know if this is intended by the integrator or not?

For the deadlock issue, we should probably have an api for calling stack functions within the main thread context, i.e performing the job directly without going through the mailbox.

Yes, and then also move the initial NMT callbacks from co_init() to main thread, so the context doesn't vary. Or maybe even better if the API functions could do the right thing regardless of the calling context.

@nattgris
Copy link
Author

nattgris commented Jan 2, 2022

When state INIT_COMM is entered, the OD is first initialised with the values in od_defaults, then loaded from CO_STORE_COMM. Would it be possible to store the updated values after an LSS change? Those values should then be restored after every poweron. The od_defaults array was intended as the factory default settings, while the stores are for persistent storage.

An additional problem with this approach is that PDO COB-IDs aren't correctly loaded from storage at all (#51). At least not if the PDO is enabled by the defaults array.

@nattgris
Copy link
Author

The workaround I'm using now is to pass a message to a separate thread in the NMT PreOp callback, then from that thread perform a reconfiguration of the PDO using #46 with the current node-ID (co_node_id_get()) which is up-to-date at that point. By going through another thread, the stack lockup is avoided.

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

No branches or pull requests

2 participants