<dngrs[m]>
<Sophie[m]> "Alright I have maybe a stupid..." <- If you don't get an answer here - there's a room dedicated to RTIC, clumsy link because I'm on mobile and element is feature limited there
<Ralph[m]>
https://rust-lang.github.io/api-guidelines/interoperability.html#c-good-err recommends that all error types implement `std::error::Error`. is it good practice to add an optional `std` feature to embedded crates and implement this if the `std` feature is enabled to give better support for platforms with `std` (embedded linux & co.)? are there examples of crates doing this (or not doing this for a particular reason)?
<Ralph[m]>
sourcebox[m]: oh, that's awesome news, thanks! seems that it'll ship with 1.81.0 which will be released in 65 days if all goes well π
IlPalazzo-ojiisa has joined #rust-embedded
cr1901 has quit [Read error: Connection reset by peer]
andresovela[m] has joined #rust-embedded
<andresovela[m]>
Hi, I'm looking for advice, maybe someone here has a good idea for me :)
<andresovela[m]>
want to force the library user to recompile the library using cargo if they want to compile an algo out. Is this possible at all?
<andresovela[m]>
I have a Rust library that I want to use in a C project. I use cbindgen to generate a header file. The Rust library has let's say features `a`, `b`, and `c`, which let's say are 3 different algorithms to do something. I'd like to compile the library once with cargo, and then be able to use it in a C project by linking the library and somehow using a compile definition to toggle the features using the C compiler, i.e. I don't
<JamesMunns[m]>
for someone that has a background in C: Rust essentially has "-ffunction-sections" and the other flags, so that dead code elimination actually happens
<JamesMunns[m]>
* other flags on by default, so
<JamesMunns[m]>
you'll need to configure your C build system to do the same, e.g. allow for dead code elimination, but Rust plays nice with this ability out of the box, so the linker can discard unused symbols.
<andresovela[m]>
For dead code elimination I assumed as much, but I generally was also interested if I could have a mechanism to cfg out code using the -DINCLUDE_X_FEATURE style in C
<JamesMunns[m]>
In Rust you do that with cfgs, but the same as C: if you change the cfg/defines, you have to recompile the lib
<diondokter[m]>
There is and that's features (and you can use environment variables as well), but those are compile time flags
<JamesMunns[m]>
so instead, you can can compile the lib with "all options enabled", then have the calling code use the parts that it needs, and let dead code elimination take care of the rest
<andresovela[m]>
Yeah makes sense
Makarov has joined #rust-embedded
Makarov29 has joined #rust-embedded
Makarov has quit [Ping timeout: 250 seconds]
Makarov29 has quit [Ping timeout: 250 seconds]
Makarov has joined #rust-embedded
mkj[m] has joined #rust-embedded
<mkj[m]>
are there any other crates around like managed? want one with a non-mut ref. (easy enough to write, but if something already exists may as well use that)
<mkj[m]>
* are there any other crates around like managed? want one with a non-mut ref. (easy enough to write, but if something already exists may as well use that). search terms are hard!
<dirbaio[m]>
> want one with a non-mut ref
<dirbaio[m]>
what do you mean by this exactly?
<mkj[m]>
as in `ManagedSlice` is `Borrowed(&'a mut [T])`, I just want `&'a [T]`
<JamesMunns[m]>
can you just use `&[T]`, `AsRef`, or `Deref` to achieve that?
<ryan-summers[m]>
Why do you need managed at all for that then? Isn't the whole point of managed to handle mutability?
<JamesMunns[m]>
Or maybe more specifically, what kind of thing are you trying to do? In case this is a little bit of an X/Y problem :)
<mkj[m]>
implementing PLDM Firmware Update protocol. one half of it runs on a PC, the other half runs on an embedded device. https://www.dmtf.org/sites/default/files/standards/documents/DSP0240_1.0.0.pdf . so to share struct definitions between the Update Agent (PC) and Firmware Device (mcu) I need some to be std with a Vec, and the other to be borrowed slices for no_std
<JamesMunns[m]>
Both `&[u8]` and `Vec<u8>` implement `AsRef<[u8]>`
<mkj[m]>
mm yep. I think I prefer lifetimes to generics though just for syntax tidiness
<JamesMunns[m]>
(or `AsRef<Component>` in your case)
<JamesMunns[m]>
mkj[m]: tbf, lifetimes ARE generics, if I'm being pedantic. But then to answer your question: No, I'm not aware of anything like managed for that!
<JamesMunns[m]>
err, `AsRef<[Component]>`, but you get the point
<JamesMunns[m]>
if you're trying to parse `Component`s from a `&[u8]` though you'll run into an issue because where do you store the slice of `Component`s?
<mkj[m]>
that's the nice bit, parsing is mostly on the std side
<mkj[m]>
vs preconstructed ones to send from the mcu
<ryan-summers[m]>
Feel free to ping me on it and it'll go into my notifications and I'll take a look at it when I have some time :) (@ryan-summers on GH)
<ryan-summers[m]>
Also true for the future
psukys has quit [Quit: bye]
Makarov95 has joined #rust-embedded
cr1901 has joined #rust-embedded
Makarov has quit [Ping timeout: 250 seconds]
shookees has joined #rust-embedded
shookees is now known as psukys
psukys has quit [Changing host]
psukys has joined #rust-embedded
<dirbaio[m]>
does anyone know what causes these errors?
<sourcebox[m]>
That looks like a missing include of stdint.h for whatever reason.
Makarov95 has quit [Ping timeout: 250 seconds]
<JamesMunns[m]>
<sourcebox[m]> "That looks like a missing..." <- yep, could be depending on implicit system includes
<sourcebox[m]>
Normally, you have to include it explicitely.
<sourcebox[m]>
E.g. cmsis_gcc.h does not include it, so probably it worked because it was included by some file before including cmsis_gcc.h. Typical pitfall with C.
<dirbaio[m]>
but the exact same thing builds on other machines :|
<JamesMunns[m]>
sourcebox[m]: man for as much as I sometimes complain about Cargo, it's so good by default.
<sourcebox[m]>
Only solution I found is being very picky about choosing the right include order.
<dirbaio[m]>
adding `#include<stdint.h>` to cmsis_gcc.h doesn't fix it
exark has quit [Quit: quit]
<dirbaio[m]>
how's that possible
<dirbaio[m]>
it must be picking up some "bad" stdint.h from somewhere
<dirbaio[m]>
that doesn't define what it should..???
<dirbaio[m]>
how do you even debug this? is there some "pls print a trace of the full paths you're including" flag?
<JamesMunns[m]>
run bindgen with strace to figure out all the include files it is touching? Or maybe there's logging you can enable?
exark has joined #rust-embedded
<sourcebox[m]>
Maybe there's some aliasing going on because e.g. with g++ you need to include `<cstdint>`.
<dirbaio[m]>
found it
<dirbaio[m]>
espup tells you to add this to .bashrc: LIBCLANG_PATH=/home/dirbaio/.rustup/toolchains/esp/xtensa-esp32-elf-clang/esp-16.0.4-20231113/esp-clang/lib
<dirbaio[m]>
that makes bindgen use esp's libclang
<dirbaio[m]>
which doesn't work for whatever reason
<dirbaio[m]>
and yep I installed the esp32 rust tooling last week
<sourcebox[m]>
I did not put this into .bashrc but have it in the export-esp.sh file.
<dirbaio[m]>
yea. it's annoying you have to source it every time you have to do esp32 stuff tho
<sourcebox[m]>
So it can be activated when using the ESP toolchain.
<dirbaio[m]>
especially if you want the envvars to get picked up by vscode/r-a
<dirbaio[m]>
so I just added them to bashrc
<dirbaio[m]>
which espup did mention as an option fwiw
<JamesMunns[m]>
SergioGasquez[m]: Maybe scroll up a bit, *doing* these steps caused an issue for dirbaio for building *other* projects with bindgen, due to the fact it brings in include files in the LIBCLANG_PATH :)
<JamesMunns[m]>
JamesMunns[m]: (so it grabbed the esp32 lib includes, even though he was doing a cortex-m build!)
<sourcebox[m]>
Sergio Gasquez: Maybe you could add a not to the docs about possible side effects.
<SergioGasquez[m]>
Oh! π’
<JamesMunns[m]>
tbh tho dirbaio, it sounds like the right process here is to specify `--no-include-path-detection` if that's not what you want.
<sourcebox[m]>
s/not/note/
<SergioGasquez[m]>
sourcebox[m]: Good idea
<dirbaio[m]>
JamesMunns[m]: hmm why? I do want it to include the "default" stdint.h
<dirbaio[m]>
there's nothing in the nordic headers that defines it
<JamesMunns[m]>
dirbaio[m]: in order to make it more deterministic? Not sure where we'd normally get it
<dirbaio[m]>
then you'd have to supply the path to stdint.h yourself
<JamesMunns[m]>
like, if you are on mac and pick up a weird stdint or something, I could see that be not good
<dirbaio[m]>
yeah :(
<JamesMunns[m]>
I have no idea how "portable" stdint is expected to be
<dirbaio[m]>
I guess it could grab some libc as a submodule and force use just that
<dirbaio[m]>
but nobody seems to do it and it works
<JamesMunns[m]>
dirbaio[m]: yeah, there's probably some deterministic system-gcc or system-clang path you can pull?
<dirbaio[m]>
also i'm surprised esp's stdint.h doesn't define uint32_t
<dirbaio[m]>
feels like something else is broken there
<dirbaio[m]>
but idk
<sourcebox[m]>
There are even more files to consider, e.g. size_t is defined in stddef.h.
<dirbaio[m]>
I hate C lol
<JamesMunns[m]>
dirbaio[m]: it might, but only be cfg gated for certain targets?
<dirbaio[m]>
Β―\_(γ)_/Β―
<dirbaio[m]>
not gonna debug it
<dirbaio[m]>
i've wasted enough time on this already
<JamesMunns[m]>
then if you have pragma once or ifndef you don't get the real one
subtlename has joined #rust-embedded
subtlename has quit [Changing host]
subtlename has joined #rust-embedded
subtlename has quit [Remote host closed the connection]
subtlename has joined #rust-embedded
subtlename has quit [Remote host closed the connection]
subtlename has joined #rust-embedded
subtlename has quit [Remote host closed the connection]
subtlename has joined #rust-embedded
subtlename has quit [Remote host closed the connection]
<JamesMunns[m]>
Poke the `cortex-m` team to see if it's reasonable to add a way to eagerly detect when we are missing a "real" linker script, e.g. force a linker error for a missing symbol defined in the c-m-rt link.x and referenced by the c-m-rt crate, so people don't end up with "no loadable section" errors from probe-rs.
<JamesMunns[m]>
I feel like I've seen people asking about that more recently, not sure if anything has changed, but it feels like something we can do something about, at least in the typical case.
<newam[m]>
I've got spotty internet, might not be here for the whole meeting.
therealprof[m] has joined #rust-embedded
<therealprof[m]>
I still find the GH "conversation" feature rather confusing.
<adamgreig[m]>
anything in particular?
<dirbaio[m]>
its a weird stackoverflow clone
<therealprof[m]>
Like: don't we record attendance anymore?
<therealprof[m]>
When do we add a new comment vs use a reply?
yruama_lairba[m] has joined #rust-embedded
<yruama_lairba[m]>
hi i'l searching help for avr target, i'd like to know how to get assembly, "cargo asm" or "cargo rustc -- --emit asm" doesn't work
<therealprof[m]>
What does the arrow up button do?
<adamgreig[m]>
yea, I guess attendance gets lost in the change, I'm not sure how useful it is but we could had people add a wave reaction or something for it?
<adamgreig[m]>
comments for each topic, reply when it's about that topic
<adamgreig[m]>
the up arrow I believe upvotes a comment/response, and the higher upvoted ones are sorted higher up, but I don't think it's relevant to our meetings at all
<therealprof[m]>
Also I find it weird that the previous meeting notes are mutable after the fact.
<adamgreig[m]>
I was going to say that's also the case on hackmd, but I suppose once I copy it into a new PR and thus into the repository they're not mutable
<adamgreig[m]>
though, locking doesn't stop members commenting or editing, so perhaps there's not much point there
<JamesMunns[m]>
for the record, I used discussions once because I didn't have access (or at least didn't have the link handy) to the hackmd we use, when I got asked to fill in last second a while back.
<JamesMunns[m]>
Some people liked it, todays the first time Adam's used it :p
<adamgreig[m]>
the hackmd is a new hackmd every time, you don't need a link or access, I just make a new one and paste in last week's :P
<vollbrecht[m]>
i think it can be usefull for a "premeeting" e.g collecting everything up to the meeting in an async style for the next week
<adamgreig[m]>
though for that to be useful we'll have to remember to make next week's each time
<adamgreig[m]>
the other thing I had considered (and did briefly with 747) is have one page and keep it open, but I fear it will get too noisy very quickly
<adamgreig[m]>
otoh this does also mean our entire discussions tab on that repo will just be meeting minutes. not sure if that's better or worse than the weekly PR before
<therealprof[m]>
Anyway, didn't want to derail the meeting. Whatever format is fine for me, just haven't gotten used to it. ;)
<yruama_lairba[m]>
lol, for "cargo rustc -- --emit asm" i loked in wrong place
<adamgreig[m]>
sure, it's useful to get feedback though, let's see how it goes for now?
<adamgreig[m]>
cool, so first up is James Munns's announcement/reminder that council meeting is this week so please let him know any items you have for that
<adamgreig[m]>
this is the updated version of what we discussed at RustNL, plus some tweaks after discussions from the previous version in https://github.com/rust-embedded/wg/pull/759
<therealprof[m]>
The new RFC sounds fine to me, I guess we just need to put it up for a vote?
<adamgreig[m]>
if anyone has specific points to discuss about the new PR now, go ahead, otherwise if resources team people could try and digest it and leave some comments so we can decide what to do with it soon
<adamgreig[m]>
I think sirhcel and eldruin had most of the feedback from the last version
bartmassey[m] has joined #rust-embedded
<bartmassey[m]>
Both @henk and I have made some progress on doing things here in anticipation. I would love to have any feedback before we go too far π
<adamgreig[m]>
for "issues and PRs for MB2 will continue to be posted on the legacy repo. This will necessitate redirecting people."
<adamgreig[m]>
we can mark the original repo "archived" and that prevents new issues and PRs
<adamgreig[m]>
the current status is basically "some people decided to write a translation and we agreed to link to it"
<adamgreig[m]>
the alternative there is we could host proper translation files in-repo and it'd be both easier for someone to do a new translation and easier to see where material has become out-of-date
<adamgreig[m]>
but as you'll see it's not merged
<bartmassey[m]>
Makes sense, but maybe a little worrisome without some kind of maintenance plan and checking.
<adamgreig[m]>
this isn't a blocker on the RFC at all, and we could just keep the same policy for now of "we'll link to translations if people make them"
<adamgreig[m]>
yea, certainly an advantage of just linking is that we're not endorsing the results to quite the same extent
<bartmassey[m]>
I'd be happy to add the translation support stuff to the new book, but I think someone else will have to step up and manage translations. I don't think we should blindly link them without some sort of process, probablyβ¦
<adamgreig[m]>
my thoughts previously were that the benefit of having links to translations outweighs the potential downside of some of them being somehow something we don't want to link to
eldruin[m] has joined #rust-embedded
<eldruin[m]>
ok I read through the rfc, thanks!
<adamgreig[m]>
but anyway, I don't mean to derail it, the RFC LGTM
<therealprof[m]>
Agreed. That was one of my main points previously.
<eldruin[m]>
under which url would the deprecated and the new books be published?
<bartmassey[m]>
Leave the deprecated book where it is.
<eldruin[m]>
bartmassey[m]: no broken links sound good
<bartmassey[m]>
New book probably at rust-embedded/discovery-mb2
<eldruin[m]>
hmm the landing page is still part of the legacy repo, though
<eldruin[m]>
changes have been rare, though.
<bartmassey[m]>
I think the landing page will point at the new repo first, which should be fine
<adamgreig[m]>
yea, /discovery can have a big "THIS BOOK IS DEPRECATED, KEPT FOR HISTORICAL REASONS, GO HERE FOR NEW BOOK"
<adamgreig[m]>
meanwhile we can update our other links, the bookshelf, the docs landing page, etc etc to just point directly to the new book
<therealprof[m]>
So, put it up for vote? π We haven't had an RFC for some time but I think that's how those should be dealt with.
<adamgreig[m]>
therealprof: it's just resources team, right? I@
<adamgreig[m]>
s/I@/we can just have the normal github review approval/
<adamgreig[m]>
adamgreig[m]: I see dirbaio has already commented, anything else to add there?
<dirbaio[m]>
lgtm modulo the build.rs nit, we can merge if no one else has concerns
<dirbaio[m]>
I don't know much about CAN :P
<dirbaio[m]>
but I guess the API is the same as the blocking one so it's OK π€·
<eldruin[m]>
yeah, seems fine to me
<adamgreig[m]>
how about the now-removed try_ methods?
<dirbaio[m]>
yeah try_* is not useful with async, it's been removed
<dirbaio[m]>
so it's ok?
<adamgreig[m]>
is there any point having some non-blocking methods for checking if it's possible to send/receive?
<eldruin[m]>
the same could be said about i2c or spi and there hals manage without them
<adamgreig[m]>
embedded-io has ReadReady/WriteReady
<adamgreig[m]>
i2c/spi aren't typically buffered, but uart and CAN are
<therealprof[m]>
SPI can be buffered.
<therealprof[m]>
I originally supported that even which caused some issues with people expecting it not to be. π
<adamgreig[m]>
perhaps I should say you don't asynchronously receive messages on SPI
<adamgreig[m]>
you receive when you ask, and not otherwise
<adamgreig[m]>
whereas UART and CAN you can receive at any time
<vollbrecht[m]>
typically =/= can be
<therealprof[m]>
Indeed, receiving on SPI cannot happen unsolicited.
<adamgreig[m]>
so in CAN I think it's more common to wonder "has a message arrived", and you might want to do that without blocking on waiting to read one
<adamgreig[m]>
but perhaps that shouldn't be try_receive, but more like ready()
<therealprof[m]>
Makes sense.
<dirbaio[m]>
with async you're most likely going to write the code with select/join
<dirbaio[m]>
or multiple tasks
<dirbaio[m]>
so you can "block" waiting for something while something else
<dirbaio[m]>
* something while also doing something else
<JamesMunns[m]>
Or now_or_never exists
<adamgreig[m]>
sure, but you still can't "check" if there's anything to receive with a combinator, right?
<therealprof[m]>
But try_receive() and ready() have a slightly different story.
<JamesMunns[m]>
(now or never is more like try_)
<dirbaio[m]>
adamgreig[m]: but you typically don't need it. you can just do `loop {let pkt = can.recv().await; process(pkt) }`
<therealprof[m]>
ready() means the peripheral is able to receive new data. try_receive() is a way to handle receives which might potentially fail.
<adamgreig[m]>
(I imagined ready more as "there's a new packet in the buffer which you could read now, so a call to read() won't block")
<adamgreig[m]>
the deleted try_receive() I think should stay gone, that was more like "try and read a message, but fail if there's none to read"
<therealprof[m]>
I guess in async land the future would go the way of the dodo if the peripheral fails?
<adamgreig[m]>
if you don't think there's a need for a read_ready() sort of method then I guess it's fine as-is
<adamgreig[m]>
therealprof: the existing proposed methods already return a Result
GrantM11235[m] has joined #rust-embedded
<GrantM11235[m]>
What if you don't want to wait between constructing the message and sending it? Like maybe the message is supposed to have an accurate timestamp
<therealprof[m]>
The example @dirbaio:matrix.org gave above, doesn't though.
<adamgreig[m]>
GrantM11235: in general for CAN any accurate timestamp should be added by the hardware at the moment of transmission but I take your point that in general one might want now-or-never transmission
<adamgreig[m]>
but I don't know if that's something we can really support. there's a race if you call write_ready() and get true and then write but something happened in the meantime to make it not able to transmit immediately
<adamgreig[m]>
in any event, in CAN your outgoing message is generally put in a mailbox and sent only when the bus becomes free, which you can't control because anyone else might start talking
<adamgreig[m]>
and that mailbox is usually configured as either FIFO or priority queue depending on the application...
<adamgreig[m]>
for the code I write I think I'd often find it useful to be able to check "is there space to enqueue a new outbound message" and "are there any unread inbound messages", but I'll accept that I could be writing the async code better and the former can be handled with a timeout and the latter with a select loop over everything else
<therealprof[m]>
Readiness is an intrinsic feature of futures, so I don't think we need something special here. If error handling is covered somehow, we don't need try_ methods.
<adamgreig[m]>
the readiness I'm talking about isn't inherent in the future though, it's to do with whether a call to read() is going to return immediately or have to wait potentially forever for something new to come in
<adamgreig[m]>
but yea, you could combine that with a timer future to get a timeout and go about your business
<GrantM11235[m]>
If you have to take a measurement before waiting for space in the buffer, the measurement will be out of date
<dirbaio[m]>
why are we discussing this again? didn't we already discuss this a while ago and decide to remove the try_* methods?
<therealprof[m]>
We're not discussing try_ methods.
<adamgreig[m]>
the try_ methods we removed were just a non-blocking read/write, but I'm more wondering about read_ready/write_ready like we have with embedded-io
<dirbaio[m]>
therealprof[m]: try_() and ready() are both ways of doing "nonblocking async io"
<dirbaio[m]>
the discussion is "do we want nonblocking async io"
<therealprof[m]>
Not quite.
<dirbaio[m]>
and imo the answer is "no"
<dirbaio[m]>
in embedded-io ReadReady/WriteReady were added to use with the blocking traits
<dirbaio[m]>
where you do need them
<dirbaio[m]>
to avoid blocking
<dirbaio[m]>
there's not much use for them if you use embedded-io-async, even if you could
<dirbaio[m]>
i've never used them π€·
<adamgreig[m]>
cool, fine with me then
<therealprof[m]>
Yes, but there are reasons why you might know to figure out whether a peripheral is ready to send or receive now, rather than queuing data or racing against a timer.
<adamgreig[m]>
try_write(), write(), and poll_ready_to_send() π±
lulf[m] has joined #rust-embedded
<lulf[m]>
The `try_write()` comment says 'Async write frame to TX buffer.' - probably why dirbaio let it go past review :D
<dirbaio[m]>
ah lol the buffered one does have it
<dirbaio[m]>
i'll eat my words then :D
<adamgreig[m]>
what's the difference with bufferedcan?
<therealprof[m]>
I guess the big question for me is how that actually works...
<adamgreig[m]>
I thought all the stm32 fdcan and bxcan had built-in mailbox storage, is it extra or does non-buffered bypass it or something?
<dirbaio[m]>
`Can` methods push/pop packets directly to the hardware
<dirbaio[m]>
`BufferedCan` methods push/pop packets to queues in RAM, and then the interrupt handler pushes/pops to the hardware
<dirbaio[m]>
I think
<dirbaio[m]>
the extra buffer makes it more tolerant to the cpu being busy with other stuff for longer I guess
<adamgreig[m]>
I guess, the hardware usually has like 10kB of buffer though...
<dirbaio[m]>
maybe non-fd has less buffer?
<therealprof[m]>
All of this sounds "best effort" to me, sometimes you want to have a bit more control over what gets sent out when and when the buffer/mailbox/queue or whatever is full you might want to take an alternative option rather than waiting for things to clear up.
<dirbaio[m]>
* maybe non-fd bxcan has less
<dirbaio[m]>
idk
<adamgreig[m]>
still it makes sense if the BufferedCan interface is secretly a channel into a ram buffer that you'd just expose the channel's normal send/try_send/poll methods?
<adamgreig[m]>
yea, it can do, and on a lot of stm32s I think the bxcan and usb sram is shared