Comments (4)
Not sure what rooting means but effectively you're creating a global shared state but rather than letting it hang freely in the breeze you're attaching it to a context which is nice. There're many use-cases for this and it'd be really great if a sane method was also available in cortex-rt. I fully understand why static mut
is unsafe and discouraged in regular applications but in case of MCUs the case is a little different since due to interrupts there's really no single point of control where you could pass the necessary handles from.
The only halfway sane way I can handle this it at the moment is something like this:
pub struct PWMCache {
bitmask: [u32; 256],
}
pub fn pwmcache() -> &'static mut PWMCache {
static mut SINGLETON: PWMCache = PWMCache::new();
unsafe { &mut SINGLETON }
}
That way one can also control access to the data but it would be nice to have a generic way of declaring global resources (also for cortex-m-rt 😉).
from rtic.
Not sure what rooting means
Ah, it's just that in this proposal I suggest placing the data that will never be freed in one of the first stack frames or near the "root" of the call stack. It may not be the best name though.
effectively you're creating a global shared state but rather than letting it hang freely in the breeze you're attaching it to a context which is nice.
That's not the intention of this RFC though. The goal here is being able to safely create &'static mut
references -- it doesn't really matter if they are allocated on the stack or on .bss / .data (static
variables).
Safe creation of &'static mut
s opens a new possibility in APIs because &'static mut
is very close to owning the value minus worrying about destructors ever running. Also you can store these references in static
variables.
The idea of "scoping" static
variables or constraining them to certain execution contexts is a core idea of the RTFM framework (it was one of the hard lessons learned between v1 and v2: global visibility is bad).
There're many use-cases for this and it'd be really great if a sane method was also available in cortex-rt.
But the result would be RTFM, no? If you need to share state between execution contexts then you may need to locking -- whether or where locking is required has to be computed from the priorities and that's what RTFM does. If you don't need sharing then you already have interrupt / exception local variables (which effectively add state to your handler) via the interrupt! and exception! macros of the cortex-m-rt device crate. Or is the problem with interrupt local variables due to const eval (const fn)? If that's the case then some runtime initialization like what's proposed here would make sense in cortex-m-rt / svd2rust.
pub fn pwmcache() -> &'static mut PWMCache {
This is still very dangerous. If you ever call pwmcache
more than once then you risk running into UB due to mutable aliasing -- the problem may not be so obvious as calling pwmcache
twice within a function foo
; you'll also run into problems if foo
calls pwmcache
and, for example, a function bar
calls foo
twice.
from rtic.
Safe creation of &'static muts opens a new possibility in APIs because &'static mut is very close to owning the value minus worrying about destructors ever running. Also you can store these references in static variables.
Right. ;)
If you need to share state between execution contexts then you may need to locking -- whether or where locking is required has to be computed from the priorities and that's what RTFM does.
No, I don't need any locking; There's exactly one reader and one writer and the storage is a simple array of integral types. The reason I want to share it is that the values are recalculated on much slower cadence (and only after an update of the value they're calculated from) than I need to output them. I could probably use rtfm but that complicates a lot of things without any obvious benefit.
Or is the problem with interrupt local variables due to const eval (const fn)? If that's the case then some runtime initialization like what's proposed here would make sense in cortex-m-rt / svd2rust.
There're many problems I have with that. I find the macros rather unflexible since I can't use them in in my initialisation code, can't do any any conditional (non-constant) initialisation (e.g. a random value) and can't use fancy datatypes e.g. arrays.
This is still very dangerous. If you ever call pwmcache more than once then you risk running into UB due to mutable aliasing -- the problem may not be so obvious as calling pwmcache twice within a function foo; you'll also run into problems if foo calls pwmcache and, for example, a function bar calls foo twice.
I'm afraid I don't understand how that could be a problem since this is really only an abstraction to get rid of the nasty unsafe {}s everywhere in contrast to simply defining a global static mut. The generated code not only looks fine and does exactly what it's supposed to. But if there's a better way to get a fixed chunk of shared RAM I'd be certainly happy to change that. 😉
from rtic.
Closing in favor of #59
from rtic.
Related Issues (20)
- `docs.rs` page for `rtic` v2.1.1 is not available
- broken usage example for i2c sharing HOT 2
- Software/Hardware Task interfaction with RTIC v2 HOT 2
- How to invoke code before RTIC main part. HOT 1
- Docs: Examples are broken and not showing HOT 3
- `atomic-polyfill` is deprecated
- rtic_monotonics 2.0 not in crates.io??? HOT 5
- Consider adding a hook to run code at the beginning of the entry point HOT 3
- SPI devices on shared bus (embedded-hal-bus) HOT 3
- Locked Status with Multiple Shared Resources HOT 2
- Software tasks and the stack HOT 2
- Support for embedded_alloc
- Call to SCB::sys_reset() results in locked up core. HOT 3
- rtic-monotonic on stm32 TIM20 or TIM17 HOT 1
- How to get the time stamp in a RTIC Rust Embedded application HOT 1
- Proplems while setting up rtic 2.1.1 HOT 2
- Multicore Support HOT 3
- How can I share the spawn handle? HOT 1
- rtic-monotonic panics HOT 9
- Cannot use higher priority tasks on STM32G030 with Embassy HAL
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rtic.