<firefrommoonligh>
This is doing the mutex syntax under the hood
<firefrommoonligh>
(Or RTIC)
innegatives_ has quit [Quit: Connection closed for inactivity]
GenTooMan has quit [Read error: Connection reset by peer]
cybernaut has joined #rust-embedded
GabeR[m] has quit [Quit: Idle timeout reached: 172800s]
ryan-summers[m] has joined #rust-embedded
<ryan-summers[m]>
[This PR](https://github.com/stm32-rs/stm32h7xx-hal/pull/483) brought it to my attention that apparently rustc is looking to deprecate `static mut` usage? Seems like this may impact embedded?
<ryan-summers[m]>
It looks like just static mut references for now, but seeing that almost all frameworks use static muts underneath for storage, seems like it would impact us a lot. Is the general recommendation to instead use MaybeUninit cells and friends?
<JamesMunns[m]>
(I'm strongly of the opinion that `static mut` is a footgun in many cases, especially recommending it to beginners). The `grounded` crate is my work towards "don't just tell people what NOT to do, tell them what to do instead)
<ryan-summers[m]>
Yeah because MaybeUninit seems like a horrible recommendation for newcomers. Even I have difficulty parsing it
<JamesMunns[m]>
idk, I see it sort of like "simple vs easy", or "why does Rust have so many string types", or whatever
<JamesMunns[m]>
we can recommend they use static mut, and that looks easier
<JamesMunns[m]>
but like, getting static mut usage right is not trivial. especially for static muts that aren't like scope hidden in a module, or within a function.
<ryan-summers[m]>
Yeah I don't disagree
<JamesMunns[m]>
You have to guarantee so much is EXACTLY correct, no re-entrance, no aliasing, etc.
<ryan-summers[m]>
They're tricky and easy to cause UB
<JamesMunns[m]>
but yeah, having better data structures, like embassy's StaticCell, and better building blocks, I'm hoping to make it not painful
romancardenas[m] has quit [Quit: Idle timeout reached: 172800s]
IlPalazzo-ojiisa has joined #rust-embedded
<thejpster[m]>
James Munns: That looks like a place I could put my irqstate types? I was thinking of spinning them off into a crate.
<thejpster[m]>
Also, is it even possible to rewrite the cortex-m macros to not use static mut?
<JamesMunns[m]>
yes, anything you can do with static mut you can do with other types
<JamesMunns[m]>
(that being said, macro-hidden static muts are generally fine)
<JamesMunns[m]>
or rather: with review, they can be :D
<JamesMunns[m]>
thejpster[m]: Open to PRs! Happy to discuss if you have any specific questions. Hoping to keep that crate generally arch-agnostic.
<JamesMunns[m]>
tho container types that work with critical-section deps are totally cool
<thejpster[m]>
Not if the compiler removes them
<JamesMunns[m]>
thejpster[m]: I'm not sure what you're saying. a `GroundedCell` can be used anywhere a `static mut` would be.
<JamesMunns[m]>
and really, an UnsafeCell - though that isn't Sync, so you need a wrapper type like GroundedCell to be able to unsafe impl Sync for ...
<thejpster[m]>
It was a response to
<thejpster[m]>
> (that being said, macro-hidden static muts are generally fine)
<thejpster[m]>
they may not be generally fine if the compiler takes them away
<thejpster[m]>
I was just checking we do actually have a mechanism we can use to replace the macro-hidden static mut in cortex-m if we have to
<JamesMunns[m]>
I was responding to "is it even possible to rewrite the cortex-m macros to not use static mut"
<JamesMunns[m]>
if the compiler doesn't take away the static muts today, it wouldn't take away the unsafecell alternatives
<thejpster[m]>
i guess unsafecell and an unsafe conversion to a mut reference is the general replacement for statuc mut
<JamesMunns[m]>
Yes, ideally with some kind of synchronization, rather than "I pinkie promise this is legit"
<JamesMunns[m]>
like, it could be macro-transform or cortex-m-rt knowledge like it is today, or it could be mutexes/once-checks for user code
<cr1901>
FOr a second I started panicking, thinking they're gonna deprecate &MY_STATIC lol
<Ecco>
Now, for example, in "rcc.cr().modify(|v|", where is "modify" implemented?
<thejpster[m]>
I like yoshua's posts today about patterns in Rust and about how you can have an API that is either run-time checked or compile-time checked, depending on the caller.
<thejpster[m]>
i typed "modify" in the search box, lokl
<thejpster[m]>
s/lokl/lol/
dne has quit [Remote host closed the connection]
<Ecco>
Damn
* Ecco
really feels like an idiot now
<Ecco>
Thanks tho
dne has joined #rust-embedded
<firefrommoonligh>
If static mut goes away, what's the best way to handle DMA buffers, ie making sure they don't drop while a peripheral is writing them?
<firefrommoonligh>
I also am a fan of them for inserting debug statements at a reasonable rates in a high-rate function, with a counter
<firefrommoonligh>
s/with/as/
<firefrommoonligh>
So the console isn't spamming at 8kHz or whatever, I use a ratio of that
<dirbaio[m]>
you can always replace `static mut FOO: T` with `static FOO: UnsafeCell<T>`
<dirbaio[m]>
they're 100% equivalent
<dirbaio[m]>
* (well you have to wrap the UnsafeCell in something with unsafe impl Send+Sync)
<dirbaio[m]>
they're 100% equivalent
<dirbaio[m]>
* (well, you also have to wrap the UnsafeCell in something with unsafe impl Send+Sync)
<dirbaio[m]>
removing static mut doesn't take away any functionality, just convenience
<dirbaio[m]>
you can still write the same thing, it's just now longer
<dirbaio[m]>
and still equally unsafe
<dirbaio[m]>
¯\_(ツ)_/¯
<firefrommoonligh>
Thx for the info
<firefrommoonligh>
Maybe macro time if this happens
nohit has quit [Ping timeout: 268 seconds]
chrysn[m] has quit [Quit: Idle timeout reached: 172800s]
nohit has joined #rust-embedded
<thejpster[m]>
yeah, you can replace `static mut FOO: T` with `struct DodgyCell(T); unsafe impl<T> Send for DodgyCell<T> {} static FOO: DodgyCell = DodgyCell(T);`. It's definitely more typing.
<JamesMunns[m]>
<thejpster[m]> "yeah, you can replace `static..." <- Fwiw this is going to be called RacyUnsafeCell or SyncUnsafeCell in the stdlib
<JamesMunns[m]>
Also, please, please don't push or suggest people to just find and replace like that. It's still marginally better, IF you don't make long lived references from it.
<JamesMunns[m]>
Holding multiple `&UnsafeCell<T>`s is sound, while just holding a single & when you make a simultaneous &mut is immediate ub
xiretza[cis] has quit [Quit: Idle timeout reached: 172800s]
<thejpster[m]>
James Munns: sent you some PRs for grounded. I proposed adding CI, which ran when I merged it into my fork, but won't run when I PR it against your upstream. I guess because arbitrarily running code on someone's repo is bad?
<thejpster[m]>
I can't think of a good module name for the Global and Local types.
<firefrommoonligh>
<thejpster[m]> "yeah, you can replace `static..." <- Dear ChatGPT: Please write a macro to simplify this syntax. The API to call it should be `access_dodgy(variable_name)`
<firefrommoonligh>
And yea - I'm not doing anything until this is removed. This was the first I'd heard of that...
<firefrommoonligh>
I'm just looking for a way to do DMA with a guarantee the buf won't drop while a periph is writing to it
<firefrommoonligh>
*Also FFI things like CMSIS DSP filter state where the API uses pointers
marmrt[m] has quit [Quit: Idle timeout reached: 172800s]
swaits[m] has quit [Quit: Idle timeout reached: 172800s]
<JamesMunns[m]>
So, you need something like `Box`, that when forgotten, leaks the memory permanently, so the now "out of control" DMA is fine to write to the leaked memory with no visible side effects.
<JamesMunns[m]>
or, you take the approach that embassy (and others, to be fair) take, and say "we don't consider `forget`-ing a DMA transfer to be safe".
<JamesMunns[m]>
though in that case, you do still want to guard access to your source/dest memory with some kind of "stop DMA on drop" guard.
<firefrommoonligh>
I appreciate the info! What would that look like in practice?
<JamesMunns[m]>
You can look at embassy's various DMA abstractions, but generally you'd impl Drop for some DmaTransaction entity
<firefrommoonligh>
Also, for anyone know knows, what is the chance static mut is being removed?
<Shell>
this reminds me of io_uring in Rust, heh
<JamesMunns[m]>
firefrommoonligh: I mean, at the MOST aggressive it gets deprecated in 2024, and removed in 2027
<JamesMunns[m]>
Shell: yeah, same thing, actually
<firefrommoonligh>
Oh! I will cease and desist
<firefrommoonligh>
That is a lot of time in the future, so happy to keep using it
<JamesMunns[m]>
I think they are adding deprecation warnings
<JamesMunns[m]>
so you might get some of those. I don' think they can remove remove it until 2027 tho.
<JamesMunns[m]>
maybe they are calling it deprecated in 2021 edition, hard error in 2024 edition?
<thejpster[m]>
we've got 12 months to fix cortex-m-rt then.
FreeKill[m] has joined #rust-embedded
<FreeKill[m]>
Hello - I'm getting caught out with defmt right from the get go, with a link error = note: rust-lld: error: undefined symbol: _defmt_timestamp
<FreeKill[m]>
is that familiar? I'm compiling for an stm32f072 with defmt and defmt_rtt
<FreeKill[m]>
also getting address overlap warnings with the .text section
<FreeKill[m]>
>>> .defmt.{"package":"f072-usb","tag":"defmt_info","data":"Poll!","disambiguator":"14953186050799278861","crate_name":"f072_usb"} range is [0x80000C0, 0x80000C0]
<FreeKill[m]>
>>> .text range is [0x80000C0, 0x801B84B]
<thejpster[m]>
does cargo tree show duplicate versions?
<FreeKill[m]>
Er it shows it once as a direct dependency and once via defmt_rtt, but they're both the same version
<FreeKill[m]>
Neeeeeeeeeeeeeeever mind, dumb typo
<FreeKill[m]>
"link-arg=Tdefmt.x" instead of "link-arg=-Tdefmt.x" ... :'(
<firefrommoonligh>
Btw, there was a breaking change in a recent rust version about ptr casting
<firefrommoonligh>
You can tag the lines in question with an allow, or use UnsafeCell
stuw1 has quit [Ping timeout: 246 seconds]
stuw1 has joined #rust-embedded
<JamesMunns[m]>
<firefrommoonligh> "Btw, there was a breaking change..." <- can you link what you're talking about?
stuw1 has quit [Ping timeout: 252 seconds]
stuw1 has joined #rust-embedded
pbsds has quit [Ping timeout: 276 seconds]
pbsds has joined #rust-embedded
notgull has joined #rust-embedded
jessebraham[m] has joined #rust-embedded
<jessebraham[m]>
I've had a few people ask me now, haven't seen anything myself. But I'll ask anyway, is there any work going on to support Zigbee that I've missed?
cybernaut has quit [Quit: Leaving]
GenTooMan has joined #rust-embedded
notgull has quit [Ping timeout: 264 seconds]
notgull has joined #rust-embedded
reitermarkus[m] has quit [Quit: Idle timeout reached: 172800s]
sashin has joined #rust-embedded
sashin has quit [Remote host closed the connection]
sashin has joined #rust-embedded
vollbrecht[m] has quit [Quit: Idle timeout reached: 172800s]
holo[m] has quit [Quit: Idle timeout reached: 172800s]
notgull has quit [Ping timeout: 260 seconds]
<PhilMarkgraf[m]>
<dirbaio[m]> "no, you can't :(..." <- That is unfortunate. -- Thank you for the answer, though. It is good knowing.
adamgreig[m] has quit [Quit: Idle timeout reached: 172800s]
bumblebee[m] has quit [Quit: Idle timeout reached: 172800s]
barnabyw[m] has quit [Quit: Idle timeout reached: 172800s]
cgc17[m] has quit [Quit: Idle timeout reached: 172800s]
<JomerDev[m]>
Hello. I'm looking for a bit of help with an issue on the rp2040 where I don't really know how to debug/progress further.
<JomerDev[m]>
I'm trying to combine defmt-serial with embassy's uart over usb. Since all the uart methods are async but defmt-serial needs a sync method I pass the sender of a pipe, very similar to embassy's usb logger. However the rp2040 crashes on the first call to sender.try_write. I assume it's a mutex issue but I don't know how to get something better than the call stack with the rpi probe nor what to try to fix it
<dirbaio[m]>
do you have your full code uploaded in some repo?
<JomerDev[m]>
Sure, give me a second to push the latest changes
<dirbaio[m]>
the + 'static doesn't fix it, that just means it can live for 'static, but you have to store it somewhere for it to actually live forever
<dirbaio[m]>
and it's not storing it anywhere beyond the local var in fn defmt_serial()
<dirbaio[m]>
you'd have to take a `&'static mut impl Writer`, and then store *two* pointers in global variables: one to the closure and one to the writer.
<JomerDev[m]>
If I store the writer in a global variable, can't I just not have the closure and use the writer directly?
<dirbaio[m]>
or use alloc to put it in a Box or something
<dirbaio[m]>
ah yeah
<dirbaio[m]>
in your case you know the actual type (`Writer<M, N>`) so you can just store that
<dirbaio[m]>
that's easier, yes
<dirbaio[m]>
in the defmt-serial case it doesn't know the type (it takes an impl Writer, which can be any type impleenting Write) so it's harder
<dirbaio[m]>
might be good to file an issue in defmt-serial too
<JomerDev[m]>
Will do
<holo[m]>
<dirbaio[m]> "holo: try using the actual HAL i..." <- > <@dirbaio:matrix.org> holo: try using the actual HAL i2c type:
<holo[m]>
<dirbaio[m]> "or I2C1 if you're using I2C1" <- ahh ok capital C but now i have exactly same errors what with previous syntax: https://pastebin.com/PeKArfZ4
<dirbaio[m]>
and make sure I2c refers to the actual driver struct
<dirbaio[m]>
I2c can refer to the embedded-hal trait I2c, or the embassy-rp struct I2c
<dirbaio[m]>
you want the struct I2c so it's an actual full type
<dirbaio[m]>
don't use dyn
<dirbaio[m]>
no generics
<dirbaio[m]>
s//embassy-rp `/, s//`/
<Ecco>
I'm writing a Rust wrapper around a C library. The C library provides me with a function pointer that it wants me to call in an interrupt. I think the only sane way is to store this pointer in the .data segment (i.e., in a global variable). But then using a "static mut" means it's unsafe. What would be the proper way to make this safe?
<holo[m]>
<dirbaio[m]> "no generics" <- so i should not use this trait from this crate: use embedded_hal_async::i2c::I2c; but something else?
<Ecco>
Everything on top of that I need to discover :)
<dirbaio[m]>
AtomicPtr is somewhat cursed to store function pointers, you have to unsafely cast them
<holo[m]>
dirbaio[m]: i took it from examples, let me try to look at it
<holo[m]>
s/it/this one/
<Ecco>
Yes, indeed, the cast back would be unsafe
<Ecco>
But supposedly with Ordering::Relaxed they just don't really generate any runtime code
<Ecco>
Out of curiosity, what runtime cost would critical_section::Mutex<Cell<Option<fn(whatever have ?
<dirbaio[m]>
Cell is zero-cost
<dirbaio[m]>
Option is zero-RAM-cost because fn() is not allowed to be null
<dirbaio[m]>
but it still has to do the null check when reading it
<dirbaio[m]>
and Mutex does a few instructions on entry and exit to disable/reenable interrupts
<Ecco>
yes, I wanted to use Option anyway
<dirbaio[m]>
so it does have some cost but it's quite small
<Ecco>
ok, so Mutex will, on every single call, disable/renable interurpts?
<dirbaio[m]>
yeah
<Ecco>
ok, interesting. Thank you so much for taking your time to explain all this
<dirbaio[m]>
so yes, AtomicPtr will be a bit faster
<Ecco>
It's kind of sub-optimal for my use-case tho
<Ecco>
ok :)
<dirbaio[m]>
if you reaaaally need the speed it might be worth the extra unsafe, but you probably don't
<Ecco>
Indeed, I don't
<Ecco>
I'm just curious how this will behave tho
<Ecco>
because I'm going to read the function from an interrupt handler
<Ecco>
so I'm not quite sure what's going to happen if interrupts are disabled *within* the handler
<dirbaio[m]>
it's allowed, it'll prevent other interrupts from firing while running that interrupt handler
<GrantM11235[m]>
You should probably copy the fnptr out of the mutex and unlock it before you call the fnptr
<dirbaio[m]>
(this can happen if the other interrupt has a higher priority than the currently-handled one)
<Ecco>
ok, makes perfect sense
<Ecco>
GrantM11235[m]: Not sure what you meant :)
<GrantM11235[m]>
something like `let maybe_fn: Option<fn()> = critical_section::with(|cs| mutex.borrow(cs).get());`
<GrantM11235[m]>
That ensures that the critical section is as short as possible, so you won't delay any higher priority interrupts for too long
<Ecco>
oooooh
<Ecco>
got it
<Ecco>
I wonder if it wouldn't be easier to just try and code something on top of AtomicPtr tho
<JomerDev[m]>
dirbaio: It seems to work now, no more crashes, thank you! I had to make the pipe static mut too and use unsafe to split it sadly. And I'm not sure if the serial connection is set up correctly, but thats a different problem
<Ecco>
sure, *some* unsafe call would be required
<dirbaio[m]>
JomerDev[m]: if you want to avoid that unsafe, you can put the pipe in a StaticCell
<JomerDev[m]>
Thank you!
<JomerDev[m]>
Also, maybe I said no more crashes too soon 😅