ChanServ changed the topic of #rust-embedded to: Welcome to the Rust Embedded IRC channel! Bridged to and logged at, code of conduct at
<NickStevens[m]> In the case of something to be read by a lay-person you are right. Use half-round. I was trying to have a discussion with you because there are legitimate uses for other rounding methods. But I think you assume I'm somehow attacking you, which I reall am not!
<dirbaio[m]> hence I said if you can round (aka "half-round") then you should
<NickStevens[m]> s/reall/really/
<dirbaio[m]> if you can
<NickStevens[m]> Hence what you meant is half-round if you can. Scrolling back what you actually said is very different. You pointed out that my fixed point suggestion did not half-round, it took the floor. I 100% agree, that is a limitation of that admittedly-simple solution, and had you said just that I would have agreed an moved on. You then laughed for suggesting there are other methods of rounding. I was asking you to listen to me and
<NickStevens[m]> you wanted to disengage. We got to an agreement eventually but it felt like an argument to you, for what was only a technical discussion. Please be better than that! The Rust community is better than that!
<dirbaio[m]> you started the argument with "citation needed"
<dirbaio[m]> > You then laughed for suggesting there are other methods of rounding
<dirbaio[m]> No, I did not, that's your interpretation
<NickStevens[m]> dirbaio[m]: I'm really sorry it read as an argument then! I really meant it as a joke and included a 😉 to indicate that.
<NickStevens[m]> dirbaio[m]: > <> > You then laughed for suggesting there are other methods of rounding... (full message at <>)
<NickStevens[m]> * Your message got split between my reply. It looked like you were replying to my comment about "I want to understand" with 😂. This is totally my misunderstanding.
<dirbaio[m]> the "citation needed" came across as a bit snarky to me, as in "but actually there's exceptions"
<dirbaio[m]> as a reply to my message which was stating "in general it's better to round"
<dirbaio[m]> of course to all "in general X" there's always exceptions
<dirbaio[m]> so I got a bit annoyed and overreacted, I'm sorry about that :(
<NickStevens[m]> Ditto, I'm sorry too. This is why I kept pressing, I really thought we were just talking past each other and I think we were. I'm glad we've got it straightened out!
<NickStevens[m]> I'll do better on how I react to things like that too, it was too much like how I'd reply to a friend who'd know I was joking.
dsvsdveg[m] has joined #rust-embedded
<dsvsdveg[m]> i'm looking to write a library for a sensor, the sensor is MAX30100, there is a C lib for it, what are your advice for it guys?
djdisodo[m] has quit [Quit: Idle timeout reached: 172800s]
kenny has quit [Ping timeout: 256 seconds]
kenny has joined #rust-embedded
<barafael[m]> <dsvsdveg[m]> "i'm looking to write a library..." <- fyi in case you have not seen it
crabbedhaloablut has quit []
crabbedhaloablut has joined #rust-embedded
thejpster[m] has joined #rust-embedded
<thejpster[m]> boo - beta broke my build:
<thejpster[m]> (beta now complains about my use of static mut ...)
<thejpster[m]> and the crate has deny(warnings) set, and it's a path dependency. So really I was asking for trouble.
ryan-summers[m] has joined #rust-embedded
<ryan-summers[m]> I actually just hit this with a usb-device example and the quick fix was to wrap the static mut in an UnsafeCell
<ryan-summers[m]> Then you can just use UnsafeCell::get_mut() instead of referencing the buffer directly because UnsafeCell handles the synchronization of the underlying data properly
IlPalazzo-ojiisa has joined #rust-embedded
<dirbaio[m]> > because UnsafeCell handles the synchronization of the underlying data properly
<dirbaio[m]> no it doesn't. `static mut X: u32` and `static X: UnsafeCell<u32>` are exactly equivalent, they both do no synchronization at all.
<dirbaio[m]> they're equally unsafe/dangerous
<Lumpio-> _well achtually_ UnsafeCell does give you some etra powers - for example getting an immutable reference to that "static mut" and then changing the data would be undefined behavior, but having a immutable reference to the UnsafeCell and changing what's inside it is ok
ivmarkov[m] has joined #rust-embedded
<ivmarkov[m]> But then what's the point of using UnsafeCell in the first place? I think it is all about interior mutability after all...
<thejpster[m]> dirbaio: except one gives you a warning and one does not...
<thejpster[m]> but yes, UnsafeCell requires you to play human borrow checker
<ivmarkov[m]> Lumpio-: You can't change what is inside by using immutable ref only.
<ryan-summers[m]> Hmm indeed if its unsafe but doesn't warn, that seems problematic
<ryan-summers[m]> The links for that warning indicated that a synchronization primitive like UnsafeCell would make this all safe
<Lumpio-> ivmarkov[m]: You can change what's inside an UnsafeCell with an immutable reference. That's the entire point of UnsafeCell.
<dirbaio[m]> unsafecell is not a synchronization primitive! :D
<Lumpio-> ryan-summers[m]: What's unsafe but doesn't warn..?
<ivmarkov[m]> ivmarkov[m]: You need to do it via raw mut ptr, which is unsafe.
<dirbaio[m]> it's a "hey compiler I know what I'm doing, please trust me". it doesn't actually do anything.
<ryan-summers[m]> If you use UnsafeCell::get_mut() on nightly, it doesn't warn about a static mut reference
<ivmarkov[m]> Lumpio-: Nope.
<ryan-summers[m]> Not sure if it can though tbh?
<dirbaio[m]> it's 100% on you to ensure you never have two `&mut`s to that memory at the same time, or you get UB
<ryan-summers[m]> s/though/thoug/
<dirbaio[m]> both with static mut and with static UnsafeCell
<Lumpio-> ryan-summers[m]: That should be fine because get_mut takes &mut self
<dirbaio[m]> they're exactly equivalent
<dirbaio[m]> and both are unsafe
<dirbaio[m]> so they require unsafe{}
<ivmarkov[m]> ryan-summers[m]: But you need mut to the unsafecell itself which kind of makes it a moot point.
<dirbaio[m]> the reason they're adding this extra warning to static mut is to get people to stop using static mut
<ryan-summers[m]> Yeah but then if you make it a static mut UnsafeCell, you can call UnsafeCell::get_mut with no compiler warning like you'd get without the cell
<ryan-summers[m]> No unsafe was required
<Lumpio-> really
<ryan-summers[m]> * ~~No unsafe was required~~ This was a lie
<ivmarkov[m]> ivmarkov[m]: At least not in a safe way.
<dirbaio[m]> static mut UnsafeCell is pointless, you have 2 "sources of mutability" there. if you're using UnsafeCell you should use just static
<ryan-summers[m]> No, my bad, the initial access of the static mut did need unsafe. Dario is right here
<ryan-summers[m]> What's the best way to deal with this then honestly?
<dirbaio[m]> static UnsafeCell
<ryan-summers[m]> I don't want to know/care about all the lifetime reference aliasing shenanigans. I just want to use static mut buffers
<ryan-summers[m]> But then how do you turn an i.e. `static UnsafeCell` into a `&mut [u8]`?
<ryan-summers[m]> * But then how do you turn an i.e. `static UnsafeCell<[u8; N>` into a `&mut [u8]`?
<Lumpio-> .get() as *mut u8
<ryan-summers[m]> * But then how do you turn an i.e. `static UnsafeCell<[u8; N]>` into a `&mut [u8]`?
<Lumpio-> .get() as *mut u8 as &mut u8 ?
<ryan-summers[m]> Isn't that the exact same issue though?
<ryan-summers[m]> I.e. that's the same aliasing issue that they're avoiding. You're just working around their warning
<dirbaio[m]> `unsafe { &mut *STATIC.get() }`
<ryan-summers[m]> Is that not doing exactly what this warning is telling us not to do?
<Lumpio-> That is ok to do - as long as you never have that &mut exist twice at the same time
<dirbaio[m]> yes
<dirbaio[m]> that's my point
<dirbaio[m]> the warning is to steer users away from static mut
<Lumpio-> The warning is telling you to be _really careful_, not to not do it.
<dirbaio[m]> because it's deemed too easy to misuse
<Lumpio-> Although it would be preferable to not do it at all
<ryan-summers[m]> Gotcha, so if we can guarantee there's only ever one reference, we're a-ok?
<dirbaio[m]> and it's too easy for Rust newcomers to end up using static mut becuase it's the "obvious" way to do global mutable state
<Lumpio-> Yes but how are you gonna guarantee that heh
<ryan-summers[m]> Yeah ikr. I was thinking option wrapping like a singleton?
<Lumpio-> I know what you're working on, do you have a generally usable Mutex or something available for that
<ryan-summers[m]> In end applications that's fine because you can usually guarantee that, given that you only do setup once
<dirbaio[m]> there's talks about removing static mut entirely
<dirbaio[m]> * there's talks about removing static mut entirely, even
<ryan-summers[m]> Lumpio-: my specific use case right now is for the `usb_device` test class, so it's not that big of a deal. Just curious what the preferred approach would be
<Lumpio-> yeah static UnsafeCell ought to be enough for everyone
<dirbaio[m]> and yeah UnsafeCell is equally bad, but since it's harder to find and more "scary sounding" they're hoping it's less likely to trap Rust novices
<Lumpio-> Yes I saw it because it pings me for every PR...
<ryan-summers[m]> Heh sorry, you can unsubscribe
diondokter[m] has joined #rust-embedded
<diondokter[m]> Lumpio-: It's much more annoying to use though and the workaround is just as unsafe
<dirbaio[m]> diondokter[m]: yeah I don't like the change either 🤷
<Lumpio-> No no I'm just curious to see what's going on
<Lumpio-> I tried avoiding the "forced user supplied buffer" in there for the longest time heh
<ryan-summers[m]> Yeah but honestly I don't know if there's a better way. Open to other ideas too
<Lumpio-> Because it's yet another rigmarole to get a device going
<dirbaio[m]> I do agree it'd be better if static mut didn't exist because it's a trap and you can already do it with static UnsafeCell... but now that it already exists, removing is quite the unnecessary churn :(
<ryan-summers[m]> But it's worked well for me on an MQTT client and smoltcp seems to do well with it
<Lumpio-> But I could never come up with a good way to have some kind of buffer by default but allow supplying a larger one when needed...
<ryan-summers[m]> Alright so the tl;dr here is change nothing and keep being as unsafe as we always have been, since we're embedded and we Know What We're Doing (tm)
<Lumpio-> Was there already a general solution for "DMA buffers" somewhere?
<Lumpio-> I.e. global buffers that need to live across functions and somehow still be safely accessible
<ryan-summers[m]> Actually, given that this is all equally unsafe, is there a difference between using `&mut *UnsafeCell::get()` and `unsafe { UnsafeCell::get_mut() }`?
<Lumpio-> Because this could use a similar thing
<Lumpio-> ryan-summers[m]: Yes, get_mut requires &mut self to begin with, and then you need a "static mut UnsafeCell" which is weird
<Lumpio-> get takes only &self so it can be done without a mutable reference to the UnsafeCell itself
<ryan-summers[m]> Fair
<Lumpio-> The "get_mut(&mut self, ...)" pattern for potentially shared data is pretty common, stuff like Rc and RefCell have it - because the &mut self already guarantees that there's only one reference
<dirbaio[m]> ryan-summers[m]: you can't call `get_mut` on a static
<dirbaio[m]> * on a (non-mut) static
<ryan-summers[m]> I meant if the UnsafeCell was mut, but was correctly pointed out that we should make it non-mut
<dirbaio[m]> if you do use static mut UnsafeCell then they are equivalent ... I think
<dirbaio[m]> it's odd that the lint doesn't trigger for `.get_mut()` , it's supposed to trigger when you take references to the static mut, and doing `STATIC_MUT.get_mut()` definitely takes a refernece (the `&mut self` for the UnsafeCell method call...)
<Lumpio-> What lint are you talking about?
<Lumpio-> I don't see any warnings using a static mut inside an unsafe{} block
<Lumpio-> hum
starblue has quit [Ping timeout: 252 seconds]
<ryan-summers[m]> Huh, why is a static mut UnsafeCell Sync but a static UnsafeCell is not?
<ryan-summers[m]> That seems... odd?
<Lumpio-> oh
<Lumpio-> dirbaio[m] your playground is on nightly
<dirbaio[m]> > why is a static mut UnsafeCell Sync
<dirbaio[m]> it's not, it's just that `static mut` doesn't require `Send/``Sync`
vollbrecht[m] has joined #rust-embedded
<Lumpio-> No warning on stable
<dirbaio[m]> s//``/`/`/
starblue has joined #rust-embedded
<ryan-summers[m]> Ahh okay. Yeah these lints are all beta/nightly right now
<dirbaio[m]> yeah they introduced it recently
<ryan-summers[m]> But will be coming out soon
<dirbaio[m]> honestly IMO if they're going to do this they should just remove static mut entirely
<Lumpio-> Ban static mut in edition = "2024" crates
<dirbaio[m]> yeah
<dirbaio[m]> there's been lots of dicussion :D
<dirbaio[m]> * of dicussion on this :D
explodingwaffle1 has joined #rust-embedded
<explodingwaffle1> it's already a hard error in edition 2024 (which you can also do on playground)
<Lumpio-> ooh
<dirbaio[m]> but i'm not sure if it's going to happen
<dirbaio[m]> I think the "disallow just references to static mut" lint is a compromise because outright removing static mut was controversial
<ryan-summers[m]> Update: Can't use `static UnsafeCell<[u8; 256]>` because `[u8; 256]` does not impl `Sized` for some reason
<explodingwaffle1> does seem like a lot of churn. not like you can cargo fix it
<dirbaio[m]> ryan-summers[m]: lol? it definitely does
<ryan-summers[m]> ... Even though a [u8; 256] definitely has a known size
<ryan-summers[m]> I believe the Sync error is coming from
<ryan-summers[m]> Maybe its something else? Because indeed that buffer type should impl Sized
<dirbaio[m]> it's complaining it's not sync
<explodingwaffle1> ?Sized means Sized or !Sized. basically what you need is
<ryan-summers[m]> Yeah, but why is it not
<dirbaio[m]> nightly-only though 😭
<dirbaio[m]> UnsafeCell is never Sync
<ryan-summers[m]> But it's saying that it has to be. Thus is it not possible to have a static UnsafeCell at all?
<dirbaio[m]> SyncUnsafeCell is Sync, but in an "unchecked" way
<dirbaio[m]> it's even more "yolo just trust me" than UnsafeCell :D
<ryan-summers[m]> So a static UnsafeCell cannot exist then I think?
<ryan-summers[m]> Because it's never Sync, but static has to be Sync
<explodingwaffle1> (syncunsafecell isn't magic, you could just copy paste it if you need it on stable. there's probably a crate for it)
<ryan-summers[m]> Given that,I don't know how I could ever do this without a static mut then without the new nightly syncunsafecell?
<ryan-summers[m]> Like.... is this even possible with edition 2024 rust currently?
<ryan-summers[m]> I'm not sure it is, which seems problematic
<dirbaio[m]> yeah you have to write your own SyncUnsafeCell
<ryan-summers[m]> Well that sucks
<dirbaio[m]> it does :(
<ryan-summers[m]> I guess I'll leave it as a static mut UnsafeCell for now and we can wait for SyncUnsafeCell to stabilize
<ryan-summers[m]> Anyways thanks for the discussion. Sounds like there's definitely some more work on the "Remove static mut" front before its usable for embedded
JamesMunns[m] has joined #rust-embedded
<JamesMunns[m]> <dirbaio[m]> "yeah you have to write your..." <- btw I'm building some tools for this at
<JamesMunns[m]> yes - you need a wrapper type that unsafe impl Sync for MySyncUnsafeCell
<JamesMunns[m]> idk, I really feel like I should write a blog post, or docs, or something about this. `static mut` is really footgunny (more so than UnsafeCell IMO), but this is one of those things that:... (full message at <>)
<ryan-summers[m]> Yeah but the crux right now is that there's no way to avoid this issue on stable rust without a custom type
<ryan-summers[m]> But it feels like this is something core should have, and not some random crate to solve the problem
IlPalazzo-ojiisa has quit [Remote host closed the connection]
<JamesMunns[m]> "solve the problem" - IMO, there is no one "fixes it" type, like yeah `SyncUnsafeCell` would be easier to reach for, but doesn't help you with the actual thing you need to be careful about, which is actually synchronizing access.
<ryan-summers[m]> In our case we have no synchronization problems since these are just static buffers we're handing to driver constructors
<JamesMunns[m]> idk, I do think that SyncUnsafeCell should exist, or something.
IlPalazzo-ojiisa has joined #rust-embedded
IlPalazzo-ojiisa has quit [Quit: Leaving.]
kenny has quit [Quit: WeeChat 4.2.1]
ello has quit [Ping timeout: 256 seconds]
kenny has joined #rust-embedded
ello has joined #rust-embedded
kenny has quit [Quit: WeeChat 4.2.1]
kenny has joined #rust-embedded
<thejpster[m]> you could just get the linker to allocate some space and give you a symbol with an address that happens to match the start of your region.
<thejpster[m]> I think James Munns 's panic-into-a-ram-buffer crate does this?
<JamesMunns[m]> (using this at all within Rust itself IMO is sort of sketch)
<JamesMunns[m]> I don't actually like how I implemented panic-persist anymore, and it's on my list to rewrite it with grounded.
<thejpster[m]> ah ha ha, I quoted it as a "good example" just the other day :/
<JamesMunns[m]> like, I'd rather have the compiler alloc the space (which lets me name the static and get size and stuff "in band")
<JamesMunns[m]> thejpster[m]: it's not the worst, but there were some things that were questionably sound IIRC
<thejpster[m]> I wonder if those static mut externals will get the ban hammer like non-external values
<thejpster[m]> DmaBuffer<u8, 256> should give you a sync mutable static buff that only lets you access the contents via a pointer.
<thejpster[m]> In fact, scratch the u8. I don't see why you'd want any other kind.
<JamesMunns[m]> also one definite hole in panic persist is you could do something like:... (full message at <>)
<JamesMunns[m]> in which you are writing back to the buffer you are borrowing from
<JamesMunns[m]> (in the next version, I'll just make you copy the contents out)
<thejpster[m]> maybe `static BUFFER: [AtomicU8; 256]` is an option.
<JamesMunns[m]> atomicu8 is just `UnsafeCell<u8>` under the hood
<JamesMunns[m]> like it works, but it's indirect.
<thejpster[m]> yeah, but it's sync ;)
<JamesMunns[m]> anyway, I'll shut up and stop arguing. I have opinions about static mut (and various linker shenanigans) that I think have been suggested and are Not Great for various reasons, no time to write them, and I feel like I should just let people do what they want instead of nagging until I can make a reasonable case about it.
<thejpster[m]> feels like a great unconf topic
<thejpster[m]> lock all the people in a room and don't let them out until there's a blog post describing best practice, signed by N - 2 occupants
<JamesMunns[m]> So until then, I'll just suggest grounded, say that I would appreciate comments on, and be quiet about it until I get a chance to distill my thoughts on it.
<JamesMunns[m]> thejpster[m]: I'll be there, if anyone wants to schedule me for that (and are willing to let me talk their ears off)
<JamesMunns[m]> s//`/, s/,/`,/, s/#issuecomment-1912273750//
<thejpster[m]> OK, that's quite nice - any bypasses the annoying const init problem with arrays of U8
<JamesMunns[m]> And a helper trait for defining your own const initializer values:
<JamesMunns[m]> (that's the ConstInit bound)
IlPalazzo-ojiisa has joined #rust-embedded
<thejpster[m]> ok, grounded mostly helped here:
<thejpster[m]> My biggest issue was the third-party type I want to share not being Sync. So I put it in a wrapper and made the wrapper sync.
<thejpster[m]> I can see why the Radio HAL wants to ensure the clock object lives forever (so the clocks cannot be de-initialised), but it's ugly as hell.
Abhishek_ has quit [Read error: Connection reset by peer]
Abhishek_ has joined #rust-embedded
IlPalazzo-ojiisa has quit [Remote host closed the connection]
<JamesMunns[m]> I might be able to relax the T: Sync bound to T: Send, like you would for a mutex. Unsure
Guest7282 has left #rust-embedded [Error from remote client]
ragarnoy[m] has joined #rust-embedded
<ragarnoy[m]> Hey! just open sourced a rust embedded library for radar sensor interfacing, made a post about it with details, I'm looking for feedback !
IlPalazzo-ojiisa has joined #rust-embedded