ChanServ changed the topic of #rust-embedded to: Welcome to the Rust Embedded IRC channel! Bridged to #rust-embedded:matrix.org and logged at https://libera.irclog.whitequark.org/rust-embedded, code of conduct at https://www.rust-lang.org/conduct.html
spinfast[m] has quit [Quit: Idle timeout reached: 172800s]
kenny has quit [Quit: WeeChat 4.2.1]
IlPalazzo-ojiis1 has quit [Quit: Leaving.]
kenny has joined #rust-embedded
jr-oss has quit [Quit: ZNC 1.7.2+deb3 - https://znc.in]
jr-oss has joined #rust-embedded
AtleoS has joined #rust-embedded
f0rte[m] has quit [Quit: Idle timeout reached: 172800s]
starblue has quit [Ping timeout: 256 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 272 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 256 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 256 seconds]
starblue has joined #rust-embedded
HumanG33k has quit [Ping timeout: 256 seconds]
HumanG33k has joined #rust-embedded
starblue has quit [Ping timeout: 255 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 256 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 246 seconds]
crabbedhaloablut has quit []
starblue has joined #rust-embedded
crabbedhaloablut has joined #rust-embedded
badyjoke[m] has joined #rust-embedded
<badyjoke[m]> Hello, I was wondering in a generated pac using svd2rust, why some write-only register only give write_with_zero method and not write ?
<badyjoke[m]> * Hello, I was wondering in a generated pac using svd2rust, why some write-only registers only give write_with_zero method and not write ?
starblue has quit [Ping timeout: 268 seconds]
starblue has joined #rust-embedded
<JamesMunns[m]> Note that write takes the reset value, and then makes your changes on top of that (resetting all other values!)
<JamesMunns[m]> If you only want to change one field of many, you probably want `modify`, not `write`
<JamesMunns[m]> Write with zero starts with zero instead, usually because the reset value is unknown.
<JamesMunns[m]> (imo we should rename these "read, modify or rmw, and overwrite" to be more clear)
<diondokter[m]> Hey all, there's this page https://docs.rust-embedded.org/embedonomicon/main.html#life-before-main describes how you can get the values from your linker script in your program. And our bootloader has been doing the same thing.... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/oLGOJGysvgOgWXlyvflIfHOi>)
<diondokter[m]> Made a PR to embedonomicon: https://github.com/rust-embedded/embedonomicon/pull/91
crabbedhaloablut has quit []
crabbedhaloablut has joined #rust-embedded
<thejpster[m]> I’m going to build this and check it works
starblue has quit [Ping timeout: 252 seconds]
starblue has joined #rust-embedded
Guest7282 has left #rust-embedded [Error from remote client]
<uliano[m]> <dirbaio[m]> "with let mco = unsafe { periphe..." <- Again about peripherals assignment.
<uliano[m]> I am wondering how to have, say an output pin, useable by an #[interrupt] context. The pin should then be kinda static global, which kind? (I'm learning and alot confused on some aspects) and how to "initialize" it (split from peripherals and assign the pin to the global)?
<adamgreig[m]> <diondokter[m]> "Made a PR to embedonomicon..." <- Does this work despite it taking &mut to __sbss etc just below?
<diondokter[m]> Oh whoops! Didn't notice that
<diondokter[m]> No
<diondokter[m]> I'll update
<diondokter[m]> But like... What's the proper thing to do here. Because this is all very hacky
<JamesMunns[m]> Writing through to a (non mut) static that isn't an unsafe cell is UB. Writing beyond the range of a single u8 is UB
<JamesMunns[m]> I know that this has been like this forever, but it is pretty conclusively UB.
<diondokter[m]> Yeah
<JamesMunns[m]> The real cmrt doesn't even do this anymore
<diondokter[m]> Like, it was decided that all this should be asm
<JamesMunns[m]> it uses asm
<JamesMunns[m]> and IIRC we DID see miscompilations for this pattern, which is why we switched to asm.
<JamesMunns[m]> so - imo we should yeet it from the embeddonomicon
<JamesMunns[m]> and if embassy-boot does this - it needs to be fixed.
<diondokter[m]> It doesn't do the init like this. It uses cortex-m-rt. But it does take the addresses of linker script defined areas this way
<diondokter[m]> That's also what my question was about
<JamesMunns[m]> I have a pattern I like better, lemme see if I can find it somewhere public for you
<diondokter[m]> I'd love that!
starblue has quit [Ping timeout: 272 seconds]
<JamesMunns[m]> GroundedArrayCell is basically `UnsafeCell<MaybeUninit<[u8; N]>>`, with some helpers
<JamesMunns[m]> it gives you a ptr and len
<diondokter[m]> Right
<diondokter[m]> How does it know that MAX_LEN?
<JamesMunns[m]> it's a const
<diondokter[m]> I see how it get placed right
<JamesMunns[m]> just like const MAX_LEN: usize = ...;
<diondokter[m]> Well, but then you risk running out of sync with the linker script
<JamesMunns[m]> if you make it too big linking will fail
<JamesMunns[m]> if it's too small, oh well, still safe.
<JamesMunns[m]> you can't make linker constants available as consts, and afaik the linker can't use variables defined in source
<JamesMunns[m]> so this is the Best Approach I have.
starblue has joined #rust-embedded
<diondokter[m]> JamesMunns[m]: For the bootloader yes, but if you e.g. swap two partitions they better be of the proper length
<JamesMunns[m]> ¯\_(ツ)_/¯ dunno the failure mode you're describing - make the const the same in source, it gets checked in source
<JamesMunns[m]> if either linker section is too small, you get an overflow linker error
<diondokter[m]> Hmmm... Maybe it works...
<diondokter[m]> But thanks for sharing!
<diondokter[m]> It is way less UB prone at least
<JamesMunns[m]> There's not much to GroundedUnsafeCell, you could write your own without using the grounded crate, but you don't have to.
<JamesMunns[m]> (and there's definitely no magic)
<diondokter[m]> What's always been unclear to me is whether this is valid:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/QymVqseadvdEFbifpjcSYzGl>)
<JamesMunns[m]> no
<JamesMunns[m]> officially UB
<JamesMunns[m]> u32 has `2^32 + 1` values, the +1 value is "poision"
<diondokter[m]> Hmmm
<JamesMunns[m]> this is "the abstract machine is not how your CPU works"
<diondokter[m]> Sure
<JamesMunns[m]> until Rust provides "freeze"
<JamesMunns[m]> which turns "poison" into "whatever"
<JamesMunns[m]> (sort of, don't read too much into a rough explanation)
<adamgreig[m]> hmm
<diondokter[m]> What if a previous execution of the program initted it? Like you init, reset the cpu and then read it from like a static?
<adamgreig[m]> what's wrong with putting a variable in the linker script and referring to it from rust as a static?
<adamgreig[m]> not for writing through, but for getting lengths and such if you wanted that?
<JamesMunns[m]> adamgreig[m]: you can't specify an array len with a static, only a const
<adamgreig[m]> 4so the problem is you can only get a pointer to the first address?
<adamgreig[m]> s/4so/so/
<JamesMunns[m]> diondokter[m]: this gets into weird territory, for this I do a fence to read, but thats inside an unsafecell, not on a random maybeuninit
<JamesMunns[m]> adamgreig[m]: rust can't get the size of the "object" from the linker.
<JamesMunns[m]> because linking happens after compilation.
<adamgreig[m]> it knows the type of the static you declared, which has a size
<JamesMunns[m]> adamgreig[m]: I don't know how to do what you are describing. if you can show me a PoC of defining the size of an object in the linker and using that size in Rust source, I would be very interested.
<JamesMunns[m]> diondokter I use this same trick to pass messages across reset
<diondokter[m]> Right
<JamesMunns[m]> but that's me making an ABI contract, which can be fulfilled within an unsafecell.
<JamesMunns[m]> unsafecell means "someone spooky somewhere else (e.g. another "thread") may be allowed to mess with this data at any time, make no assumptions about whether it is valid or not"
<JamesMunns[m]> `MaybeUninit::<u32>::assume_init()` declares a new variable, which the compiler knows no other thread has ever had a chance to do spooky things to.
<JamesMunns[m]> it is objectively UB, as far as I know today.
<JamesMunns[m]> A `static UnsafeCell<MaybeUninit<u32>>` is different.
<diondokter[m]> Ok, so it's unsafecell to the rescue
<diondokter[m]> Got it
<JamesMunns[m]> well, UC+MU, but yes. that's why GroundedCell(Array) is like that :)
<diondokter[m]> Ha yeah :P
<adamgreig[m]> James Munns: so for example, if I have some config region set aside in flash by the linker script for storing some read-only config, and I want to read that flash in my firmware
<adamgreig[m]> option one: I can put a *const u32 initialised to some constant like 0x08010000 in my firmware directly and read it, not unlike accessing MMIO, which is presumably fine?
<adamgreig[m]> option two: that, but I use slice::from_raw_parts to get a &[u32] which I read. it's not initialised by rust, so perhaps UB?
<JamesMunns[m]> afaik option one has no provenance, which I'm honestly not sure what the recommendation is today, "from escaped provenance"? idk. it's not defined behavior, idk if it's definitely UB
<JamesMunns[m]> adamgreig[m]: again, you don't have provenance, so reading it is sketch, but when you make the slice you are promising it is valid
<adamgreig[m]> option three: I use a `bla = ORIGIN(CONFIG)` in linker script, put `static BLA: u32` and `&BLA as *const u32` in my firmware to get the address as a raw pointer
<JamesMunns[m]> you defined a variable with provenance of 4 bytes, so if you read more than 4 that is ub
<adamgreig[m]> so the first case is "provenance from an integer cast to a pointer" and the second is "provenance from a single static that had a known size and now we're reading beyond it"?
<JamesMunns[m]> (note: I'm not saying this won't work, but as far as I know what I say is UB is UB under the current established provenance rules)
<JamesMunns[m]> idk if I can compare which one is "more ub", I think that's like comparing infinities
<JamesMunns[m]> I think all the cases you said are UB, if you consider provenance
<JamesMunns[m]> *probably* the optimizer will say "idk where you got that pointer from, make no assumptions about it", and probably will just work
<adamgreig[m]> it seems unsatisfying to say "well you simply can't read from flash", right?
<JamesMunns[m]> but officially it is undefined behavior for various readings
<adamgreig[m]> generally the HALs just allow this and so forth
<JamesMunns[m]> you need to use the "use escaped provenance" to establish the flash exists outside the rust abstract machine
<adamgreig[m]> does it become OK if I have static FOO: MyLargeReprCStruct instead? now it has a size I won't read beyond
<JamesMunns[m]> or you need to use a static like I do to introduce the provenance I establish
<JamesMunns[m]> yes, afaik, you are promising as a platform abi that struct will exist and be initialized at the start of execution
<JamesMunns[m]> you might need to setup xip before you start rust to be really sound
<adamgreig[m]> but exposed provenance is only part of the strict provenance "experiment" which is non-normative and more strict than rust's actual rules, right?
<JamesMunns[m]> tbh I'm not sure rust has agreed it HAS provenance at all yet
<JamesMunns[m]> officially
<JamesMunns[m]> ah jk that got merged: https://github.com/rust-lang/rfcs/pull/3559
<diondokter[m]> Well, even if Rust didn't the likely llvm has
<diondokter[m]> s/the/then/
<adamgreig[m]> having provenance is inherent, having a well described set of rules isn't, but strict provenance is still just a hypothetical set of future rules afaik
<JamesMunns[m]> adamgreig[m]: ehhhhh it's not necessarily inherent. but practically is
<JamesMunns[m]> anyway, I think we're on the same page
<JamesMunns[m]> I think what you described is in a grey "not surely defined" area
<JamesMunns[m]> it's not strictly excluded (yet)
<adamgreig[m]> yea, I think that's the frustration
<adamgreig[m]> it's not clearly UB, it's not clearly not UB
<adamgreig[m]> in practice it works fine because it's not clearly not UB, I think
<adamgreig[m]> but it sure would be nice to have a sensible way to do these commonly-needed things
<JamesMunns[m]> it's up to whether LLVM misinterprets what you meant, which might change over time
<adamgreig[m]> and the nomicon is definitely in need of change
<JamesMunns[m]> adamgreig[m]: hello yes this is why I wrote groundedcell and I believe it is solidly defined behavior.
<adamgreig[m]> yea, but can it help with this?
<JamesMunns[m]> yes
<diondokter[m]> So the only sure methods are for a slice of memory in e.g. flash is:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/GTIIMkkyNyhygLBJFsySNfXq>)
<adamgreig[m]> where "this" is "there's an extern variable in memory somewhere which is the start of a config struct, and I want to read it"?
<JamesMunns[m]> `GroundedCell<YourType>` at the MMIO location
<adamgreig[m]> but how do I place it there?
<JamesMunns[m]> you get a ptr, don't turn that into a reference until after you set up XIP
<JamesMunns[m]> linker script placement, like the examples before.
<diondokter[m]> * So the only sure methods for a slice of memory in e.g. flash are:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/omCkFKffqQxsohjumLqzrEhi>)
<adamgreig[m]> diondokter: doing everything with pointers is perhaps not viable if the first pointer didn't have a large enough provenance, depending on whether you try to abide by the strict provenance rules...
<adamgreig[m]> JamesMunns[m]: aah got it, OK
<JamesMunns[m]> wanna cover the whole MMIO range? do that with a grounded array cell of u8 too, then tag out the parts you know where stuff is
<diondokter[m]> adamgreig[m]: Well, what's the provenance of `0x12345678 as *mut u8`?
<JamesMunns[m]> you could have a 2GiB uninit grounded array cell, then pull out the 128 bytes out of that using the pointer you get from ptr_len() of the cell.
<JamesMunns[m]> diondokter[m]: none, that's why its UB
<adamgreig[m]> diondokter: that is indeed the question :P
<diondokter[m]> Ok, but then like all PACs are UB?
<JamesMunns[m]> you are "magicking" up a pointer with no associated provenance
<adamgreig[m]> under some interpretations it's "all of memory" and under strict provenance it's not
<JamesMunns[m]> to some degree, a bit, tho imo the volatile ops probably diffuse most of the risk
<JamesMunns[m]> adamgreig[m]: thank you, that's exactly what I wanted to link
<adamgreig[m]> I'm not sure it is, that issue seems clear it is OK and is just debating how to make an API for it under strict provenance
<adamgreig[m]> * it is "to some degree" UB, that
<adamgreig[m]> ie "This is perfectly fine for Rust as long as that memory is entirely disjoint from all the memory that Rust understands (static globals, stack allocations, heap allocations). Basically we can think of there being a single hard-coded provenance for "all the memory that is disjoint from the Abstract Machine", and that is the provenance we would like to use for these pointers created from hard-coded addresses"
<adamgreig[m]> but you'll note the issue is still open 😅
<JamesMunns[m]> that's the intent of what they want to get to, not what the rules are today
<JamesMunns[m]> the rules of that today are "eh...?"
<adamgreig[m]> are you sure it's not just what they want to get to for the strict provenance concept?
<JamesMunns[m]> IMO it works today because it's all with volatile access and llvm wont fuck with volatile access.
<adamgreig[m]> my interpretation was that the current rules say memory outside the AM has a provenance and the question is how to build that into SP
starblue has quit [Ping timeout: 256 seconds]
<JamesMunns[m]> adamgreig[m]: maybe, I haven't re-read that issue in a couple months.
<adamgreig[m]> I don't think it can be the case that "this is UB until we have a new method in SP that marks it as allowed", because SP is opt-in extra-strict, I understood "today it's OK because it's outside the AM, but how do we make it still OK with SP?"
<adamgreig[m]> i.e. LLVM won't mess with it because it's an address outside LLVM's set of known memory, not just because it's also volatile?
<JamesMunns[m]> <JamesMunns[m]> "it's up to whether LLVM misinter..." <- this is my opinion
<JamesMunns[m]> and it is in unsafe land, which means rust's interpretation is allowed to change
<adamgreig[m]> but I wouldn't want to then hold a `&` to it, sooo
<JamesMunns[m]> anyway, happy to chat at rustnl, I really have to run, hope that code and my opinions were helpful.
<adamgreig[m]> huh, rust makes no guarantees that something that's sound but unsafe today will remain sound tomorrow?
starblue has joined #rust-embedded
<adamgreig[m]> yea same, I got dragged in more than I expected
<adamgreig[m]> I'm sure this will come up at rustnl :P
<diondokter[m]> JamesMunns[m]: Ooh! I'll put it on the list
<JamesMunns[m]> I don't think we know that is "sound" today. we know it works today.
<JamesMunns[m]> diondokter[m]: it is
<diondokter[m]> Oh haha
<adamgreig[m]> it was pretty much the first thing on the list, hah
<JamesMunns[m]> (ub is not guaranteed to not work, it can sometimes work)
<adamgreig[m]> ah sure, but if it's not UB today it hopefully can't become UB tomorrow
<JamesMunns[m]> wishes, fishes, etc.
<adamgreig[m]> certainly not just because it's in unsafe land
<diondokter[m]> Yeah, because like... How do we build a bootloader, right now without UB. That's something that's not super clear right now
<adamgreig[m]> hmm, I take that back, if it's neither UB nor DB today then maybe it can go either way tomorrow!
<JamesMunns[m]> diondokter[m]: imo you can, using the primitives I've included above.
<diondokter[m]> JamesMunns[m]: Yeah, that's at least one way yeah
<JamesMunns[m]> that's a snippet of my bootloader for the rp2040, which I believe is sound.
<JamesMunns[m]> adamgreig[m]: yes, agree with this! the between land can be argued either way. but until its codified it may go the other way any day.
starblue has quit [Ping timeout: 268 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 264 seconds]
starblue has joined #rust-embedded
AtleoS has quit [Ping timeout: 268 seconds]
AtleoS has joined #rust-embedded
starblue has quit [Ping timeout: 255 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 256 seconds]
starblue has joined #rust-embedded
IlPalazzo-ojiisa has joined #rust-embedded
starblue has quit [Ping timeout: 255 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 246 seconds]
starblue has joined #rust-embedded
ryan-summers[m] has quit [Quit: Idle timeout reached: 172800s]
JomerDev[m] has joined #rust-embedded
<JomerDev[m]> Does anybody else have the issue with vscde and rust-analyzer that r-a seems to break after encountering pio_proc::pio_asm!? I get no more hints after that line nor can it show me the properties of any structure
jannic[m] has quit [Quit: Idle timeout reached: 172800s]
SimonJohansson[m has quit [Quit: Idle timeout reached: 172800s]
Guest7282 has joined #rust-embedded
starblue has quit [Ping timeout: 260 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 246 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 255 seconds]
starblue has joined #rust-embedded
newam[m] has quit [Quit: Idle timeout reached: 172800s]
starblue has quit [Ping timeout: 256 seconds]
starblue has joined #rust-embedded
AtleoS has quit [Quit: AtleoS]
AtleoS has joined #rust-embedded
AtleoS has quit [Changing host]
AtleoS has joined #rust-embedded
posborne[m] has quit [Quit: Idle timeout reached: 172800s]
starblue has quit [Ping timeout: 268 seconds]
bartmassey[m] has quit [Quit: Idle timeout reached: 172800s]
starblue has joined #rust-embedded
TomB[m] has quit [Quit: Idle timeout reached: 172800s]
starblue has quit [Ping timeout: 268 seconds]
starblue has joined #rust-embedded
therealprof[m] has quit [Quit: Idle timeout reached: 172800s]
jamwaffles[m] has quit [Quit: Idle timeout reached: 172800s]
starblue has quit [Ping timeout: 268 seconds]
eldruin[m] has quit [Quit: Idle timeout reached: 172800s]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 268 seconds]
wyager[m] has quit [Quit: Idle timeout reached: 172800s]
starblue has joined #rust-embedded
<JomerDev[m]> ^ I found that rust-analyzer and the language server in vscode don't like workspaces where one member uses std and others don't
<dirbaio[m]> ah yep, that never works 🥲
<JomerDev[m]> Yeah, but the error messages are all over the place so it's hard to diagnose. I got suspicious when it complained that StdError wasn't implemented for Error on a no_std environment
starblue has quit [Ping timeout: 268 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 256 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 268 seconds]
starblue has joined #rust-embedded
starblue has quit [Ping timeout: 255 seconds]
starblue has joined #rust-embedded
dne has quit [Remote host closed the connection]
dne has joined #rust-embedded
starblue has quit [Ping timeout: 255 seconds]
starblue has joined #rust-embedded