Skip to content

task + async misc #67

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

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft

task + async misc #67

wants to merge 19 commits into from

Conversation

d3zd3z
Copy link
Collaborator

@d3zd3z d3zd3z commented Mar 7, 2025

Create a new proc-macro-based way of declaring threads in Zephyr. Instead of the weird kobj_define macro, provide a zephyr::thread macro that can decorate an ordinary Rust function to become a builder for a ReadyThread that can just be started. Threads can also now be reused after they exit.

This allows something like:

#[zephyr::thread(stack_size = 2048)]
fn mythread(name: &'static str, index: usize) {
    // Body
}

and somewhere in the code, you just call it, which returns a handle that can be used to start the thread.

let joiner = mythread("thename", 42).start();
...
joiner.join();  // Wait for thread to exit, if desired.

There is still some things to clean up, hence the draft, but I wanted to get some exposure.

@d3zd3z
Copy link
Collaborator Author

d3zd3z commented Apr 7, 2025

I'd like to start getting this ready for review. But, there is a question of how much this should be split apart. There are a few cherry-picked changes that are to be merged, so we'll at least wait for those to go in.

@d3zd3z d3zd3z force-pushed the tasks branch 2 times, most recently from 2657f67 to f90442b Compare April 8, 2025 22:02
@d3zd3z d3zd3z requested review from Ablu, teburd and cfriedt and removed request for Ablu April 8, 2025 22:02
d3zd3z added 5 commits April 9, 2025 09:48
These are macros in Zephyr, so write explicit wrappers for them, that
bindgen will be able to directly use.

Signed-off-by: David Brown <[email protected]>
There is a fairly fundamental incompatibility between Zephyr spin locks
and the Critical Section specification.  Zephyr spin locks do not allow
nesting from within a single spin lock.  The critical section API only
has an `acquire` and `release` entry, and provides no way (such as a
stack frame) to have a unique context for different invocation places.

Unfortunately, this means we cannot use spin locks for critical
sections.

Instead, this change implements critical sections using irq locking.
The implementation of these macros on Zephyr does try to make them SMP
safe, with a simple atomic lock, but there is still something preventing
the riscv SMP from working.

Also, these entries cannot be called from user mode.  There are various
other reasons we don't support usermode, so at this time, just have a
compile time assertion that usermode is not enabled in the build.  If it
is needed, we will have to come up with another way to implement this.

Signed-off-by: David Brown <[email protected]>
Implement a proc macro that allows a declaration like:

```rust
fn mythread(arg: usize, arg2: &'static Thing) { .. }
```

With this change, creation of threads, with arbitrary "Send" arguments
can be done without needing allocation.  The macros reserves a static
area alongside the `k_thread` structure to use for handing the threads
over.

This creates a function `mythread` with the given args that returns a
ReadyThread.  This has a `start()` method which will begin execution of
the thread.  This results in a RunningThread, which has a join method
that can be used to wait for termination.

Signed-off-by: David Brown <[email protected]>
Move away from the `kobj_define` task declaration to use the new
`#[zephyr::thread]` to define these.  This allows for a more natural
declaration where the thread just looks like an attribute added to a
regular function declaration.

This also eliminates the static Mutex, as the Mutex now has a
constructor that avoids allocation (it is still put in an Arc, though).

Signed-off-by: David Brown <[email protected]>
To help with debugging, try to give created Zephyr threads a readable
name.  Currently, this is based off of the name of the function used in
the declaration of the thread.

Signed-off-by: David Brown <[email protected]>
@d3zd3z d3zd3z changed the title New Proc-macro thread declaration task + async misc Apr 10, 2025
@d3zd3z d3zd3z marked this pull request as draft April 10, 2025 19:18
@d3zd3z d3zd3z force-pushed the tasks branch 3 times, most recently from c0b5b21 to cef1d3a Compare April 14, 2025 22:46
d3zd3z added 8 commits April 17, 2025 15:31
Don't require that the two time bases be the same.  This allows
applications to work using the default embassy-time base of 1MHz.  There
is a performance cost to the conversion (which depends on the exact
ratios).  If the time bases are the same (which would be common for an
application build for a single target), then no conversion is needed.

Signed-off-by: David Brown <[email protected]>
Don't generate instance access code for DT nodes that aren't actually
enabled.

Signed-off-by: David Brown <[email protected]>
Add a short readme to explain some of the difficulties with level
triggered interrupts (notably, most STM32 devices do not support level
triggered interrupts).

Signed-off-by: David Brown <[email protected]>
Make some small changes to try testing this on stm32.  This change can
be discarded.

Signed-off-by: David Brown <[email protected]>
d3zd3z added 6 commits April 17, 2025 15:31
A version mismatch here causes compilation errors due to other crates
depending on this specific version.

Signed-off-by: David Brown <[email protected]>
Instead of allocating work queues, and hoping they don't get freed,
instead move to a static declaration.  This is facilitated by a macro
`define_work_queue` that makes it easy to declare these at the top
level.

Signed-off-by: David Brown <[email protected]>
The docgen target seems to try building the docs before the generated
headers are present.  Work around this by making a full build first, and
then generating the docs.

Signed-off-by: David Brown <[email protected]>
The work-queue-based Future has been removed, so also removed the
documentation that was describing it.

Signed-off-by: David Brown <[email protected]>
Fix various broken links in documentation comments.

Signed-off-by: David Brown <[email protected]>
The Serde "tag" rules was being used for enums, which results in enums
being generated in a somewhat awkward format.  Remove this, and change
the syntax of the dt-rust.yaml file to match.  This typically results in
changes like:

    - type: instance
      value:
        raw:
	  type: myself

to be simplified to just:

    - !Instance
      raw: !Myself

Signed-off-by: David Brown <[email protected]>
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.

1 participant