<nickez[m]>
James Munns: I'm trying to use GroundedArrayCell to store some callbacks, but rustc complains that `dyn Fn() + 'static` doesn't implement `Sync`. Am I not using `grounded` correctly?
<nickez[m]>
* to use `GroundedArrayCell, * GroundedArrayCell` to
<nickez[m]>
nickez[m]: My callback type is `Box<dyn Fn()>`
<JamesMunns[m]>
So: you're probably not holding it wrong, I just need to relax the bounds as they are overly strict
chrysn[m] has joined #rust-embedded
<chrysn[m]>
To those interested in embedded friendly serializations (Postcard, defmt, Brief, CBOR): I've updated my "shoot-out" scratchpad at https://pad.riot-os.org/bg3i8ko6Qnya2003vDDMag?both with what I know (which is CBOR and a bit of defmt). If you are interested and have some time, would you care to add case-study examples where your format shines, show how the existing ones would be done with yours, and have a glance at the others?
<chrysn[m]>
(Again, don't let Matrix fool you into thinking this is a big comparison: the title is revised in the document, but the preview doesn't catch that)
<nickez[m]>
<nickez[m]> "My callback type is `Box<dyn Fn(..." <- I just had to add the `+ Synd` bound to the definitions
<nickez[m]>
<JamesMunns[m]> "So: you're probably not holding..." <- I fixed it by adding `+ Sync` bounds to my callback type
RobertJrdens[m] has joined #rust-embedded
<RobertJrdens[m]>
<chrysn[m]> "To those interested in embedded..." <- For that "extensible map"/schema/optional/compatibility scenario, you may want to look at `miniconf` as well (shameless plug). With any of the key formats and any of the serde formats. There are some examples/integration tests/doctests that show it.
<chrysn[m]>
How does that use numeric keys with serde? That has been a longstanding issue with all CBOR libraries that want to produce compact maps but use serde derives.
<chrysn[m]>
That's not what I meant. You wrote "any of the key formats", and the key format I'm interested in is what in CBOR would be `{0: "x", 3: 42}` that should populate a `struct S { #[n(0)] name: String, #[n(1)] description: Option<String>, #[n(3)] count: usize }`. minicbor does that, and it matches typical CBOR approaches of not lugging strings around, but I haven't managed to do this with anything serde based.
<RobertJrdens[m]>
"Any of the key" formats implemented in miniconf. The example above serializes into a (homogeneous typed) map of integer keys and postcard value pairs for each leaf.
<RobertJrdens[m]>
It's not trying to replace cbor.
<chrysn[m]>
So as a whole, do I get this right that what this does is to enable JSONPath style access into a struct?
<chrysn[m]>
So, if I added support for minicbor, would this allow me to use `miniconf::minicbor::get(&my_s, "/3")` to get the 42 either out of the struct or out of the serialized stream?
<chrysn[m]>
Or would I query `get(&my_s, "/count")`, or could I transform the latter at build time into an interned form of the former?
<JamesMunns[m]>
I'm guessing minicbor doesn't have any mechanisms for guaranteeing that the client and server agree on the dictionary?
<JamesMunns[m]>
Just "it is a given you have shared it correctly and it never changes"?
<RobertJrdens[m]>
Yes. Among several other Key types it supports JSONPath. If you want cbor as payload format, I guess with minicbor-serde, you can use it straigt away.
<RobertJrdens[m]>
Some possible Key for that count field would be. /count or [2] or whatever Packed decides for you.
* chrysn[m]
ponders what it'd mean for a struct to have both its serde and its minicbor derive around (where the minicbor derive would be used for serialization) … the combined info might suffice to recreate some CDDL schema at build time
<JamesMunns[m]>
JamesMunns[m]: (I ask because *postcard* doesn't either, but *postcard-rpc*/poststation is working on verifying this with schema hashes.
<JamesMunns[m]>
> <@jamesmunns:beeper.com> I'm guessing minicbor doesn't have any mechanisms for guaranteeing that the client and server agree on the dictionary?
<JamesMunns[m]>
* (I ask because _postcard_ doesn't either, but _postcard-rpc_/poststation is working on verifying this with schema hashes.)
<JamesMunns[m]>
For example, the "packed dictionary" in postcard-rpc could be an enum that has a Display impl using the fields of the enum variants for formatting, and postcard-rpc's schema hashes WOULD detect if you ever added/removed/changed elements in the dictionary.
<chrysn[m]>
In the struct case it's not so much a dictionary but a specified format – like, SenML specifies that the -1 means "base version", and it doesn't care whether the struct is named b_ver, base_version or baseversion.
<chrysn[m]>
It does have a mechanism for self-describing that data is of some know format, so that both sides agree that it's SenML (in that case that would be 1668546929([… senml data…]))
<JamesMunns[m]>
dirbaio[m]: Isn't this "you need to use the right critical section for your platform"?
<JamesMunns[m]>
I thought the std impl used a real mutex
<dirbaio[m]>
no, the bug is the CS token
<dirbaio[m]>
* CS token is Send/Sync
<dirbaio[m]>
you can lock a CS in thread A, send a copy of the token to thread B, and use it toaccess a non-Sync thing concurrently from both threads
<dirbaio[m]>
even if the impl you're using is the right one
<dirbaio[m]>
because the cs impl only matters for how you acquire the token
<dirbaio[m]>
once you got a token you can do mischief with it like sending it to another thread because it's incorrectly Send, and the impl can't see/prevent that
<JamesMunns[m]>
ahhhh
<dirbaio[m]>
welp
<JamesMunns[m]>
Does it break everything if we make the CS token !Send?
<dirbaio[m]>
it feels like it'd only break code that was already unsound
<JamesMunns[m]>
IMO that's a breaking change but one for soundness (and likely not break any sound code), so imo it's acceptable to change
<dirbaio[m]>
definitely yeah...
<JamesMunns[m]>
(and not do a version update)
<dirbaio[m]>
release 1.2.0, yank all earlier versions
<Ralph[m]>
since a lot of crates seem to depend on b-m 1.0 it would probably make sense to release 1.1 which pulls in c-s, this way they all get the fix, the deprecation notice is published and the ecosystem is less fractures (between b-m and c-s)?
<dirbaio[m]>
bm1.0 barely got any adoption
<dirbaio[m]>
everything is still on bm0.2
<dirbaio[m]>
and b0.2 uses `&'a CriticalSection` instead of `CriticalSection<'a>`, so we can't do reexport tricks
<Ralph[m]>
dirbaio[m]: the first few pages of the reverse dependencies mainly show 1.0, though?
<dirbaio[m]>
hmm stm32-rs pacs and hals
<dirbaio[m]>
it's unused lol
<dirbaio[m]>
it's just in cargo.toml, but not used from rust code
<dirbaio[m]>
seems it's unused too in the hals, at least f4, h7
<dirbaio[m]>
xtensa-lx just reexports CriticalSection
<dirbaio[m]>
xtensa-lx-rt, completely unused
<dirbaio[m]>
* xtensa-lx does use it to implement interrupt::free()
<dirbaio[m]>
avr-device does use it to implement interrupt::free()
<dirbaio[m]>
I honestly think we should yank it to make people move to critical-section
<dirbaio[m]>
* yank it entirely to make
<Ralph[m]>
dirbaio[m]: it _might_ still make sense to release 1.1.0 with the c-s reference in there mainly to have it in the README (where it's currently missing!) also on crates.io. after that you can yank it (incl. the new 1.1) but then people will see the message on crates.io. otherwise they'll just see that it's yanked but don't see what the alternative is
<dirbaio[m]>
i've merged pending PRs
<dirbaio[m]>
the miri thing on std is actually another soundness fix :D
<Ralph[m]>
now i'm considering buying one because i think it might make tinkering with peripherals easier as i avoid the roundtrip via the microcontroller (=> better debugging support in the IDEs as the application runs locally, faster iterations as it doesn't need to upload the binary every time, etc.). or am i imagining this too easy and should just stick to grabbing one of my MCUs? 🤔
<Ralph[m]>
i'm also wondering if this would be a sensible solution to easily add some GPIO pins to a small embedded computer (rather than buying an industrial mainboard with built-in GPIO pins)? might even be cheaper?
<JamesMunns[m]>
It's reasonable, there are tools like the Tigard that do this
<JamesMunns[m]>
I'm releasing an updated version of it based on postcard-rpc and my `poststation` project later this month, that will support the RP2040.
<JamesMunns[m]>
Same idea: "do embedded things from your desktop and do the actual protocol stuff remotely"
<dirbaio[m]>
I've played a bit with these. one problem I ran into is they don't support all SPI modes (iirc there's a fancier version that does)
<ivmarkov[m]>
<JamesMunns[m]> "Yeah, it's useful if you can..." <- Would just using ft232h result un lower latency, as - I would assume - the any-protocol-over-usb is in hardware?
<ivmarkov[m]>
* Would just using ft232h result in lower latency, as - I would assume - the any-protocol-over-usb is in hardware?
<ivmarkov[m]>
(I have a few of those lying around, was wondering if I should give these a whirl with the linux ftdi support)
<ivmarkov[m]>
* Would just using ft232h result in lower latency, as - I would assume - the any-protocol-over-usb is in hardware? (As opposed to doing it with an MCU in software, that is)
<thejpster[m]>
a thread in which the theoretical purity of the Rust project runs hard up against the fact that the LEON 3 stores plug and play data between 0xFFFF_0000 and 0xFFFF_FFFF.
<jannic[m]>
Tomorrow on this channel: Some architecture storing things at 0x0.
<dirbaio[m]>
like, the reset vector? 🙃
whitequark[cis] has joined #rust-embedded
<whitequark[cis]>
<thejpster[m]> "a thread in which the theoretica..." <- the answer is, as usual, "use inline assembly to read it", same as with PACs
<whitequark[cis]>
I don't get the aversion to that though
<whitequark[cis]>
using arch-specific stuff to access arch-specific data or registers feels fine to me
<dirbaio[m]>
in this case it should be ok to use raw pointers and volatile read? making sure you never overflow the pointer over the end of the address space
<dirbaio[m]>
or is there something special cursed about the last byte of the address space or something?
<whitequark[cis]>
dirbaio[m]: true, though as Amanieu mentions, volatile is poorly defined in and of itself, so I've been trying to avoid it
<whitequark[cis]>
it will work fine here
<thejpster[m]>
the last byte is cursed because you have to move the pointer one past it during a memcpy
<whitequark[cis]>
it's just that nobody can really clearly answer what it does
<dirbaio[m]>
maybe even regular reads are ok if the data is readonly
<whitequark[cis]>
and I prefer knowing what my operations mean
<thejpster[m]>
I have no aversion to doing special magic here. I have an aversion to going back to C people and saying "hey, the code you fly in space is UB and you need to fix it or you can't use Rust on your platform"
<thejpster[m]>
because "fine, we won't use Rust" is an entirely plausible answer
<dirbaio[m]>
thejpster[m]: but that's because of the memcpy implementation incrementing one too much, not something inherent to rust opsem (?)
<whitequark[cis]>
thejpster[m]: but it *is* UB, isn't it?
<dirbaio[m]>
like you could implement your own memcpy without that bug
<whitequark[cis]>
* but it *is* doing UB, isn't it?
<thejpster[m]>
well yes except the people who designed the CPU also ship the C compiler. So arguably the compiler they ship defines the behaviour they expect.
<thejpster[m]>
I think the problem is that a memcpy that avoids the bug has less performance
<dirbaio[m]>
which says "the memory range of the given size starting at the pointer must all be within the bounds of a single allocated object"
<dirbaio[m]>
so according to this, (0xFFFF_FFFC as *const u32).read_volatile() and .read() would also be Ub
<dirbaio[m]>
* so according to this, (0xFFFF_FFFC as *const u32).read_volatile() and .read() would also be UB
<dirbaio[m]>
lol
<dirbaio[m]>
because the safety contract for .read() also reuqires the "allocated object" thing
<thejpster[m]>
tell that to the CPU designers who keep putting stuff there
<dirbaio[m]>
so the last byte of the address space really is cursed, wow
<dirbaio[m]>
you really have to use inline asm in this case :D
<whitequark[cis]>
thejpster[m]: I would!
cr1901 has quit [Read error: Connection reset by peer]
cr1901 has joined #rust-embedded
huayra1[m] has joined #rust-embedded
<huayra1[m]>
<jannic[m]> "Tomorrow on this channel: Some..." <- it's left undefined in C because some architectures *do* store things there. most don't though and just put a null page
rafael[m] has joined #rust-embedded
<rafael[m]>
first time touching a rc receiver... are they always so sensitive? Or have i finally picked a component too cheap? I had to add a 47uF capacitor to my dc-dc converter to reduce ripple before it the rc receiver even started to work. Now i find it propagates some sort of bounce to my pin when high, which i did not expect... And reception range is terrible. Okay, no antenna on this thing, so maybe that can be excused. So, are these
<rafael[m]>
guys always such divas?
<rafael[m]>
not at all related to Rust... sorry... [the last message can be safely ignored 🙂]