<thejpster[m]>
I guess I need to update this STM32/rtic project.
<thejpster[m]>
`unsafe { core::ptr::write_volatile(&self.dev.dr as *const _ as *mut u8, data) }`
<thejpster[m]>
> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
kenny has quit [Ping timeout: 244 seconds]
kenny has joined #rust-embedded
wassasin[m] has quit [Quit: Idle timeout reached: 172800s]
diondokter[m] has quit [Quit: Idle timeout reached: 172800s]
RandomExplosion[ has joined #rust-embedded
<RandomExplosion[>
Does anyone have a good example/resource of how to use no_std, no alloc serde to parse enums and structs to bytes and back again with minimal padding/fluff?
<RandomExplosion[>
i'm currently using custom to_bytes and from_bytes implementations but that gets quite tiresome and clunky as the codebase gets larger.
<JamesMunns[m]>
Does it need to be a specific format, or is it between two Rust devices?
<JamesMunns[m]>
(like, are you implementing some existing protocol, or building your own?)
<JamesMunns[m]>
If you need to implement an existing protocol, you might want to check out something like bytemuck. If you are setting up your own comms, you might want to check out postcard and postcard-rpc
<RandomExplosion[>
i'm building my own but i'm after a frame-esque protocol akin to an ethernet frame
<RandomExplosion[>
actually one osi layer up but you get the idea
<JamesMunns[m]>
fwiw, postcard-rpc is a protocol that works on the "frame" level, might work well for you :)
<RandomExplosion[>
the message format is an enum that i'd like to tag with a leading byte followed by the variant fields repr(C) style
<RandomExplosion[>
will probably be over i2c
<RandomExplosion[>
i had a look at bincode but i'm pretty sure it doesn't work without alloc
<JamesMunns[m]>
Yeah, if you definitely want to implement something manually, I'd suggest bytemuck, scroll, or a couple of other byte wrangling libraries.
<JamesMunns[m]>
fwiw: postcard-rpc does message ID tagging (instead of an enum int), which it gets from hashing the schema of the type, so you can't "accidentally" change the message type
<JamesMunns[m]>
it'll do header compression, so the minimum overhead is 3 bytes, which has the protocol version, message tag, and sequence number.
<JamesMunns[m]>
I DO plan to support I2C, but don't out of the box yet today.
<RandomExplosion[>
<JamesMunns[m]> "Yeah, if you definitely want..." <- i was hoping for an automatic solution akin to using serde_json or bincode, i'll take a look at bytemuck though
<JamesMunns[m]>
You could use just postcard, it is similar to bincode
<JamesMunns[m]>
it's not exactly repr(c) style though. It uses varints for integers, for portability reasons
<joelsa[m]>
I guess it would be straightforward, since RTT is just a dumb ringbuffer, but maybe that assumption is wrong
<joelsa[m]>
I need to benchmark a MCU with quite a lot of data. Approximately how much effort do you think it is be to create a target-side impl for RTT? Thatβd be the server/Firmware-side in postcard nomenclature I think.
<JamesMunns[m]>
<joelsa[m]> "Speaking of postcard-rpc:..." <- Not too much work :)
<JamesMunns[m]>
<joelsa[m]> "Speaking of postcard-rpc:..." <- If you want to help get that polished up and tested, I'd definitely appreciate it!
<JamesMunns[m]>
<joelsa[m]> "Speaking of postcard-rpc:..." <- I *think* there was an "off by one" error with `probe-rs`'s RTT code that was causing some issues, but is now in main: https://github.com/probe-rs/probe-rs/pull/3056
<JamesMunns[m]>
<JamesMunns[m]> "Not too much work :)..." <- you might want to use the git version of probe-rs as well for now!
<danielb[m]>
<JamesMunns[m]> "I *think* there was an "off by..." <- yeah if the RTT buffer was right at the last position in RAM, probe-rs wasn't able to use it, but that's all
<danielb[m]>
if you output a lot of data I would probably think about alternatives to RTT, it will either block if the buffer gets full, or it will overwrite data, and your use case may not be able to tolerate either
corecode[m] has quit [Quit: Idle timeout reached: 172800s]
<JamesMunns[m]>
Yeah, ideally I'd like to find a way to make writes to it async, but that will require more work
<JamesMunns[m]>
one blocker is that rtt-target doesn't return the number of bytes written, which means I can't partially write, yield, and write more, which is a bummer
<JamesMunns[m]>
I do want to eventually look at changing that, or impl'ing a different rtt target lib, if it's not changable in a non-destructive way.
<JamesMunns[m]>
I also would love to have a way to get an async notif when bytes are written TO the device, I have some silly ideas (we could sacrifice an interrupt to act as a "waker callback", and pend the interrupt from the host on write or as a flush), but again that would be a lot more work. Right now I just poll every ms
<JamesMunns[m]>
basically, I want to turn rtt into a normal-ass embedded-io-async interface, ideally π
<JamesMunns[m]>
it's not really needed for rtt-println, or defmt, which are both blocking. but would be very useful for p-rpc
<danielb[m]>
what would trigger that interrupt?
<JamesMunns[m]>
you can poke the "pend interrupt" register manually through memory ops with probe-rs
<JamesMunns[m]>
the idea would be to use it as a "host initiated callback"
<danielb[m]>
keep in mind that architectures exist other than ARM
<JamesMunns[m]>
Open to other ways to pend a waker from the host side :)
<JamesMunns[m]>
Sure, and they can fallback to polling :p
<JamesMunns[m]>
Or if you know a good way to wake a waker remotely on esp32, I'm open to that too!
<danielb[m]>
you'd have to somehow communicate to the host how to wake the waker, too - which interrupt to tickle, what code to run, etc.
<JamesMunns[m]>
Luckily, we have a whole comms interface through p-rpc!
<JamesMunns[m]>
it can start with polling, then have an endpoint that says "ask here for the interrupt to poke", and "turn off polling
<danielb[m]>
what could work is a "write your data, then call this function at this address"
<danielb[m]>
but restoring normal flow after that... :/
<JamesMunns[m]>
yeah, idk if it's more or less hacky to make probe rs "call a function"
<JamesMunns[m]>
I figured interrupt was the easiest way to get that to happen, on cortex-m at least, with the least round trips
<danielb[m]>
we do that quite a bit, but there is no normal firmware to return to
<danielb[m]>
* return to in those cases
<JamesMunns[m]>
yeah, I also don't want to block the firmware for a ton of interactive round trips, that's a lot of latency
<JamesMunns[m]>
gotta run for lunch, very open to ideas here! But also happy to get it merged in a "works but suboptimal" way, so more people can use it, and maybe one of them PRs a better way when they get irritated at it being not perfect :)
<danielb[m]>
some MCUs can only do stop-mode RTT, so there's no real way to prevent that on them
<JamesMunns[m]>
Trying not to let perfect be the enemy of good :)
<thejpster[m]>
I feel like new bare-metal targets should warrant a working group ping
astapleton[m] has joined #rust-embedded
<astapleton[m]>
<RandomExplosion[> "i was hoping for an automatic..." <- I'm using serde + postcard in a no_std environment for comms over I2C. I'm using alloc just for Vecs (and as a temporary shortcut) for a message that varies in length a lot. All the messages are defined in an enum and Postcard takes care of everything just deserializing to the correct enum variant. It was pretty easy to get up and running too.
flx has quit [Quit: WeeChat 4.4.3]
fsinger has joined #rust-embedded
fsinger is now known as flx
Koen[m] has quit [Quit: Idle timeout reached: 172800s]
judge[m] has quit [Quit: Idle timeout reached: 172800s]
mgudel[m] has quit [Quit: Idle timeout reached: 172800s]
<davidmpye[m]>
Id be interested to see what you see on scl/SDA with an oscilloscope or logic analyser
<dirbaio[m]>
(answered in https://matrix.to/#/!YoLPkieCYHGzdjUhOK:matrix.org/$u0JW0BLcFNpl81ZFi6xPHTE6q8grlnC7ktKP8nEwiP0?via=matrix.org&via=tchncs.de&via=beeper.com , it was missing MAPR write)