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

Tracking: OpenThread Support #3833

Open
16 of 22 tasks
tyler-potyondy opened this issue Feb 2, 2024 · 9 comments
Open
16 of 22 tasks

Tracking: OpenThread Support #3833

tyler-potyondy opened this issue Feb 2, 2024 · 9 comments
Labels
tracking WG-Network In the purview of the Network working group.

Comments

@tyler-potyondy
Copy link
Contributor

tyler-potyondy commented Feb 2, 2024

Overview

With #3683, Tock added support for a minimal Thread network implementation. This implementation was completed in a Thread capsule and served to demonstrate the feasibility of Tock supporting Thread networking. Given the complexities of implementing the entire Thread specification, a bespoke Tock Thread implementation is unfeasible.

Google actively manages and maintains the OpenThread project; this serves as the de facto Thread implementation. To date, all major embedded platforms that provide Thread support have implemented the protocol by porting OpenThread (typically in the form of an OpenThread library / module). Moving forward, a Tock / OpenThread port likely presents the most feasible avenue towards Tock providing a robust Thread network stack. Tock presents an added complexity to complete this port given Tock's policy preventing external dependencies. Thus far, the two options for porting OpenThread to Tock appear to be through:

  • libtock-c
  • encapsulated functions

This tracking issue will serve to provide a summary of the OpenThread libtock-c port, describe what remains to be done, and emphasize capsule features blocking the completion of this port. Beyond simplifying a Thread implementation, choosing to port OpenThread provides the added benefit of a simplified path towards Tock receiving official certification as a Thread platform (the Thread group holds a lower bar for testing if using the OpenThread stack).

Details to Port OpenThread

OpenThread provides a detailed porting guide. OpenThread specifies a platform abstract layer (PAL) which a given OpenThread platform must implement to provide support for:

  • Alarm
  • UART
  • Radio
  • Misc/Reset
  • Entropy
  • Non-volatile storage

libtock-c OpenThread

OpenThread utilizes a CMake build system. This creates immediate conflicts and challenges with the libtock-c make based build system. To work around this, we invoke the OpenThread CMake build system to create static libraries. Moreover, we specify an arm-none-eabi.cmake file so that OpenThread is compiled in a manner compatible with libtock-c / Tock. These static libraries are linked to libtock-c applications using the libtock-c external library mechanism. We are currently able to compile a libtock-c application that references OpenThread functions and successfully constructs an OpenThread instance.

Tasks to Complete

This list will likely grow as development continues. For now, this is divided into tasks that need to be completed in order to provide a fully functional Thread network and the less urgent tasks required for Thread certification.

Fully Functional Thread Network

  • Compile / link OpenThread with Tock specific compiler arguments
  • Implement libtock-c OpenThread specific build infrastructure
  • Access / call OpenThread structs and functions from a libtock-c application
  • Successfully construct Thread instance (PAL unimplemented and return "dummy" values)
  • Complete platform abstraction layer - (alarm, radio, entropy)

Thread Certified Thread Network

  • Flash Storage (persistent Thread state across power cycles)
  • UART support (this is needed as the OpenThread CLI is used for certification testing)
  • Determine policy / procedure for radio sleep state

Other Related Problems

@brghena brghena added the WG-Network In the purview of the Network working group. label Feb 5, 2024
@bradjc
Copy link
Contributor

bradjc commented Feb 6, 2024

What is

libtock-c specific OpenThread radio functionality

?

@bradjc
Copy link
Contributor

bradjc commented Feb 6, 2024

For the flash storage, what is required? How many bytes do we need to store?

@tyler-potyondy
Copy link
Contributor Author

What is

libtock-c specific OpenThread radio functionality

?

This was referring to implementing the OpenThread radio PAL in libtock-c (I was trying to draw a distinction between the capsule / libtock-c milestones). I've rephrased to hopefully make this more clear.

@tyler-potyondy
Copy link
Contributor Author

For the flash storage, what is required? How many bytes do we need to store?

I do not have an exact answer for now. Briefly checking, it appears on the order of ~24kB persistent storage is expected. @Samir-Rashid and @atar13 just began working on the flash PAL so we should have more ideas as to what is required soon. I do not expect flash functionality to be a blocker for Thread functioning as it serves to provide persistence to the Thread state across power cycles. This will however be necessary to comply with the Thread spec for any future Thread certification.

@bradjc
Copy link
Contributor

bradjc commented Feb 6, 2024

I do not have an exact answer for now. Briefly checking, it appears on the order of ~24kB persistent storage is expected.

Ok that is quite a bit. We do have https://github.com/tock/tock/blob/master/capsules/extra/src/nonvolatile_storage_driver.rs which might work for a userspace interface.

I do not expect flash functionality to be a blocker for Thread functioning as it serves to provide persistence to the Thread state across power cycles.

I don't know what this looks like in practice, but it seems like a device should be able to reboot and reconnect as expected. It would be good to avoid having to make any caveats about how things don't quite work as expected. But maybe you can't really tell as a user what happens if you don't have persistent state.

@alevy
Copy link
Member

alevy commented Mar 15, 2024

Getting close!

  • 15.4 capsule support for changing radio channel
  • 15.4 capsule RSSI getting / setting
  • ibtock-c OpenThread radio PAL

@bradjc
Copy link
Contributor

bradjc commented May 20, 2024

I think there is a fundamental mismatch with trying to use OpenThread in userspace with the capsules/extra/ieee802154/driver.rs syscall driver. That driver is built on this stack:

┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ Syscall Interface
┌──────────────────────┐
│     RadioDriver      │
└──────────────────────┘
┄┄ ieee802154::device::MacDevice ┄┄
┌──────────────────────┐
│      VirtualMac      │
└──────────────────────┘
┄┄ ieee802154::device::MacDevice ┄┄
┌──────────────────────┐
│        Framer        │
└──────────────────────┘
┄┄ ieee802154::mac::Mac ┄┄
┌──────────────────────┐
│  MAC (ex: AwakeMac)  │
└──────────────────────┘
┄┄ hil::radio::Radio ┄┄
┌──────────────────────┐
│    802.15.4 Radio    │
└──────────────────────┘

however the lower layer of OpenThread does not expect to sit on any of those layers except for the radio. For the tutorial we essentially added a raw path through those layers. However, that still doesn't allow configuring the channel. Instead, I propose:

@tyler-potyondy
Copy link
Contributor Author

I am overall in favor of this. The current 15.4 stack is not conducive to supporting OpenThread and we are forcing a square peg into a round hole so to speak. In my opinion, the two routes forward at this juncture are either:

  1. Redesign the 15.4 stack into a unified stack that is able to somehow satisfy the needs @bradjc highlights here. It is not exactly clear if it is possible to support both or if this is even an optimal design.
  2. Implement a separate 15.4 driver that offers full control of the radio as @bradjc proposes above.

I favor option two because I think this provides an easier path forward to more fully support the features OpenThread requires (sleeping / channel switching etc). These features become increasingly complicated to reason about across virtualized 15.4 access with multiple apps.

Some things to keep in mind with option two are that:

  • This will be mutually exclusive with the existing 15.4 stack .
  • This will require configuring the kernel differently to use OpenThread apps vs the current 15.4 test apps (i.e. setting a different client for the radio).

Ideally these changes should be entirely abstracted from userland. Perhaps we should only expose one 15.4 userspace driver that then will interface to the "non virtualized full control" 15.4 driver or the "virtualized stack" depending on how the kernel is configured.

┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ Syscall Interface
┌──────────────────────────────────────────────┐
│     RadioDriver                              │
└──────────────────────────────────────────────┘
(DEPENDENT ON WHICH CLIENT IS SET SELECTS ONE OF TWO "STACKS")
┌──────────────────────┐┌──────────────────────┐
│      VirtualMac      ||    802.15.4 Radio    │
└──────────────────────┘└──────────────────────┘
┌──────────────────────┐
│        Framer        │
└──────────────────────┘
┌──────────────────────┐
│  MAC (ex: AwakeMac)  │
└──────────────────────┘
┌──────────────────────┐
│    802.15.4 Radio    │
└──────────────────────┘

With this design we can then return an error to userland if the full radio control "non virtualized" design is configured and multiple apps request 15.4 access. Furthermore, we can also easily return an error to userland if things such as switching channels or setting radio transmit power etc are attempted to be set in the virtualized mutli app design.

@bradjc
Copy link
Contributor

bradjc commented May 23, 2024

Ideally these changes should be entirely abstracted from userland.

The easiest path is to have two separate SyscallDriver implementations which expose (mostly) the same interface. A more complicated approach would have a single SyscallDriver implementation that supports using either a MacDevice or a hil::radio::Radio. Unfortunately this in general is a limitation in Tock as there is not a clean way to shim layers at the SyscallDriver layer.

One thing to note is that currently the virtualization in this stack is within the kernel and not for userspace. Adding userspace virtualization would make this more complicated, as that really only applies to the in-kernel MAC stack.

While a singe userspace driver would be nice in some respects, I'm not inclined to purse that for two reasons: 1) Sending raw MAC-layer frames from userspace seems, practically speaking, a niche use case, and 2) It adds a fair bit of complexity to the implementation which is otherwise simpler to read and write as separate drivers. Note, we can keep the interface the same so userspace has only one driver and gets the errors as you describe. It's just that the correctness of that is harder to maintain over time (every change would need to be ported to both syscall drivers).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tracking WG-Network In the purview of the Network working group.
Projects
None yet
Development

No branches or pull requests

4 participants