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

Adds local loopback to TractionThrottle. #756

Merged
merged 7 commits into from
Jan 27, 2024

Conversation

balazsracz
Copy link
Collaborator

This PR improves behavior when there is more than one TractionThrottle in the same openlcb::node_. Specifically, when these are assigned to the same dst_ locomotive, the Train Node will never send back echoes of the packets. This means that the simultaneous updates are missing.

This PR makes all TractionThrottle objects lined up in a linked list upon creation. When a locomotive control commands (speed, estop, fn) is sent out, a local loopback will walk the linked list and identify if there are any other tractionthrottle objects assigned to the same loco. If so, the message will be handed over to it for update callbacks.

This PR improves behavior when there is more than one TractionThrottle in the
same openlcb::node_. Specifically, when these are assigned to the same dst_
locomotive, the Train Node will never send back echoes of the packets. This
means that the simultaneous updates are missing.

This PR makes all TractionThrottle objects lined up in a linked list upon creation.
When a locomotive control commands (speed, estop, fn) is sent out, a local
loopback will walk the linked list and identify if there are any other
tractionthrottle objects assigned to the same loco.
If so, the message will be handed over to it for update callbacks.
@balazsracz balazsracz marked this pull request as draft December 21, 2023 20:12
Ensures that the listener link doesn't get prematurely removed.
When more than one throttle is listening to the same train node,
any throttle would remove the listener link, leaving the others without
a registration. Now only the last throttle remaining will remove the link.
@balazsracz balazsracz marked this pull request as ready for review December 22, 2023 17:25
@balazsracz balazsracz requested a review from bakerstu December 22, 2023 17:25
{
{
// finds next instance that's interesting
AtomicHolder h(LinkedObject<TractionThrottle>::head_mu());
Copy link
Owner

Choose a reason for hiding this comment

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

I'm not crazy about holding an atomic section for the loop through of an unbounded list. Is there an existing mutex we could use instead? What about a task scheduler lock instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Under linux an Atomic is actually a mutex.
Under freertos it is a critical section, which means that (on an M3/M4) only priority zero interrupts can go through.
So the important question is how many iterations are there here and how long do they take.

  • For almost all devices there are at most two iterations. Throttles typically have one or two such objects.
  • For command stations there can be up to 64 such objects. (63 for NCE, 31 for XNet). Definitely not unbounded, because each tractionthrottle is about 100 bytes or more.

One iteration is just a pointer chasing and comparing some memory bytes. I expect it to be say 0.5 to 1 usec (few dozen instructions).
As a result, I expect a non-p0 interrupt jitter of about 0.05 to 0.1 millisecond to be caused by this.

Non-P0 interrutps are things like CAN-bus (1 msec per interrupt) or UART (where we have a FIFO , unless in NCE, where the interrupt is one per msec as well).

It's not super practical to replace this with a mutex or a scheduler lock:

  • LinkedObject<> is used elsewhere, if we want to replace the locking, we need to copy the code or impact every other use as well (examples are Executor<> and StateFlowWithQueue<>)
  • scheduler lock doesn't exist in linux. We don't have an abstraction for it. It's also unclear what it would do in a multi-core ESP32.
  • Another alternative might be to jump to the main executor for sending outgoing packets, but this is also not exciting, because it would probably break all unit tests. It also doesn't guarantee that the links don't change if an object gets constructed or deleted on another thread.

@balazsracz balazsracz merged commit 5c1f88a into master Jan 27, 2024
4 checks passed
@balazsracz balazsracz deleted the bracz-throttle-local-update branch January 27, 2024 16:07
balazsracz added a commit that referenced this pull request Feb 1, 2024
* master:
  Adds support for Offset(n) attribute in the CDI  (#765)
  Adds local loopback to TractionThrottle. (#756)
balazsracz added a commit that referenced this pull request Feb 1, 2024
* bracz-accy-packet-with-pom:
  Adds support for Offset(n) attribute in the CDI  (#765)
  Adds local loopback to TractionThrottle. (#756)
balazsracz added a commit that referenced this pull request Feb 2, 2024
* master:
  Fixes file comment.
  Adds an application (hub_test) for testing the throughput of a hub or a CAN-bus (#762)
  Adds a helper function to decode a 14-bit 9.2.1.1 address into address type and raw address. (#766)
  Fix broken test.
  Accessory packet refactoring and POM support (#764)
  Adds support for Offset(n) attribute in the CDI  (#765)
  Adds local loopback to TractionThrottle. (#756)
  Fix test flakiness.
  Fix compile error on FdUtils under freertos.
balazsracz added a commit that referenced this pull request Feb 4, 2024
* master:
  Upintegrate changes from the OpenMRNIDF repository (#771)
  Adds support for DCC extended accessories  (#769)
  Fix incorrect consumer identified message being emitted by dcc accy producer. (#768)
  Avoids rendering hidden segments. (#767)
  Adds trailing zero to the cdi XML file written to the filesystem. (#777)
  Fix target subdirectory name (#775)
  Fixes file comment.
  Adds an application (hub_test) for testing the throughput of a hub or a CAN-bus (#762)
  Adds a helper function to decode a 14-bit 9.2.1.1 address into address type and raw address. (#766)
  Fix broken test.
  Accessory packet refactoring and POM support (#764)
  Adds support for Offset(n) attribute in the CDI  (#765)
  Adds local loopback to TractionThrottle. (#756)
  Fix test flakiness.
  Fix compile error on FdUtils under freertos.
balazsracz added a commit that referenced this pull request Feb 4, 2024
* bracz-idf-downintegrate:
  Upintegrate changes from the OpenMRNIDF repository (#771)
  Fix comments.
  Adds support for DCC extended accessories  (#769)
  Fix incorrect consumer identified message being emitted by dcc accy producer. (#768)
  Avoids rendering hidden segments. (#767)
  Adds trailing zero to the cdi XML file written to the filesystem. (#777)
  Fix target subdirectory name (#775)
  Fixes file comment.
  Adds an application (hub_test) for testing the throughput of a hub or a CAN-bus (#762)
  Adds a helper function to decode a 14-bit 9.2.1.1 address into address type and raw address. (#766)
  Fix broken test.
  Accessory packet refactoring and POM support (#764)
  Adds support for Offset(n) attribute in the CDI  (#765)
  Adds local loopback to TractionThrottle. (#756)
  Fix test flakiness.
  Fix compile error on FdUtils under freertos.
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

Successfully merging this pull request may close these issues.

2 participants