You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have this CANopen node that boots twice during an update. Here is the relevant code:
print(f"Awaiting first bootup {time.ctime()}")
node.nmt.wait_for_bootup(20)
print(f"First bootup found! {time.ctime()}")
print(f"Awaiting second bootup {time.ctime()}")
node.nmt.wait_for_bootup(20)
print(f"Second bootup found! {time.ctime()}")
Waiting for the first bootup message always works exactly as expected. Waiting for the second one fails randomly. What is weird is that the second boot message is definitely there:
Awaiting first bootup Mon Feb 24 09:13:03 2025
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 0
First bootup found! Mon Feb 24 09:13:03 2025
Awaiting second bootup Mon Feb 24 09:13:03 2025
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 0
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
DEBUG:canopen.nmt:Received heartbeat can-id 1804, state is 127
But it gets ignored, somehow? Eventually the second wait_for_bootup times out.
As said, sometimes this works, but most often it does not seem to work.
The text was updated successfully, but these errors were encountered:
(Time between boot and heartbeat is almost 10 seconds).
Just speculating here: I think that the relevant condition (node.nmt.state_update) gets notified twice with so little time in between that wait_for_bootup never gets the chance to check if self._state_received was ever zero.
The check for self._state_received == 0 happens after the condition has been released, thus the next PRE-OP heartbeat could already have been processed (which sets the attribute back to 127). Try moving the check within the with self.state_update: block, see if that fixes the issue.
The suggestion by acolomb does not solve the issue.
Adding a new debug statement on line 167 shows that in case two messages come in really close together, the notification does not lead to code execution in wait_for_bootup.
So I believe that self.state_update.notify_all() does not guarantee that all listeners get CPU time immediately, and therefore another CAN message could be handled first, so that _state_received updates twice without wait_for_bootup ever getting CPU time. So I think a separate condition for just boot messages would be required to solve this.
jackodirks
changed the title
Node boots twice, second boot message cannot be waited for.
node.nmt.wait_for_bootup misses boot message if a bootmessage is immidiately followed by another heartbeat message
Feb 27, 2025
CANopen version 2.3.0
I have this CANopen node that boots twice during an update. Here is the relevant code:
Waiting for the first bootup message always works exactly as expected. Waiting for the second one fails randomly. What is weird is that the second boot message is definitely there:
But it gets ignored, somehow? Eventually the second wait_for_bootup times out.
As said, sometimes this works, but most often it does not seem to work.
The text was updated successfully, but these errors were encountered: