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
starblue has quit [Ping timeout: 276 seconds]
starblue has joined #rust-embedded
sroemer has joined #rust-embedded
Darius has quit [Ping timeout: 260 seconds]
anton_star has joined #rust-embedded
Darius has joined #rust-embedded
ello has quit [Quit: ZNC 1.9.1 - https://znc.in]
ello has joined #rust-embedded
sroemer has quit [Ping timeout: 252 seconds]
sroemer has joined #rust-embedded
emerent has quit [Ping timeout: 260 seconds]
emerent has joined #rust-embedded
<thejpster[m]> https://github.com/rust-lang/compiler-team/issues/800 - MCP to delete the existing AVR target and add avr-unknown-unknown
<thejpster[m]> (Which I think should be avr-unknown-none )
<M9names[m]> <thejpster[m]> "(Which I think should be avr-..." <- i'm curious why you think the vendor field should be "unknown". we know exactly which vendor produces avr chips, either the field should contain that or IMO it should be dropped.
sroemer has quit [Ping timeout: 252 seconds]
<M9names[m]> if we assume that we only specify a vendor when it matters (because there are arch variants from different vendors), then it should just be avr-none.
<M9names[m]> ah, they do give the rationale about the specific triple they chose:
<M9names[m]> > (avr-unknown-unknown instead of avr-unknown-gnu), because that's the name LLVM already uses.
<M9names[m]> unfortunate
sroemer has joined #rust-embedded
sroemer has quit [Changing host]
sroemer has joined #rust-embedded
<thejpster[m]> Because it’s the machine vendor not the CPU vendor and you don’t know who made the machine the chip is in
<thejpster[m]> Traditionally the field would be pc (for PC compatible), apple, sun, or ibm.
sroemer has quit [Ping timeout: 252 seconds]
<thejpster[m]> See also aarch64-apple-darwin vs aarch64-unknown-linux-gnu
<thejpster[m]> And I agree typically you would leave out the unknown field.
sroemer has joined #rust-embedded
snorkman[m] has joined #rust-embedded
<snorkman[m]> snorkman[m]: I have also tried running [another USB example](https://github.com/stm32-rs/stm32f4xx-hal/blob/master/examples/usb-serial-poll.rs) from the repo and can confirm it worked on the uC.
<snorkman[m]> <snorkman[m]> "I have also tried running [..." <- Solved it, it was sth quite simple. I forgot to enable the PLL.
diondokter[m] has joined #rust-embedded
<diondokter[m]> Hey all, I don't there is, but is there a way to do a call to defmt where it doesn't print the second line with location of the print?
<diondokter[m]> I'm printing out all registers of a device and it's really noisy
<Lumpio[m]> <thejpster[m]> "You mean like ITM?" <- Needs an extra pin which is unavailable surprisingly often and only goes in one direction
<dirbaio[m]> diondokter[m]: > <@diondokter:matrix.org> Hey all, I don't there is, but is there a way to do a call to defmt where it doesn't print the second line with location of the print?
<dirbaio[m]> > I'm printing out all registers of a device and it's really noisy
<dirbaio[m]> Maybe you can do a single big print with \n's in it
<diondokter[m]> Yeah well... But then I'd have to read all registers ahead of time and store them somewhere
<dirbaio[m]> True... Otherwise you can change the log format in the host side to remove the 2nd line thing. I don't think it's possible to disable it per line
<diondokter[m]> Right now I do it with a callback per register read
<diondokter[m]> dirbaio[m]: Hmmm yeah probably easiest
<diondokter[m]> Could be cool if we could get access to the formatter like in the Format function
<diondokter[m]> And then write! away
n_vl[m] has joined #rust-embedded
<thejpster[m]> <dirbaio[m]> "True... Otherwise you can change..." <- Yeah it’s a host side option. The new decoder offers an alternate format that puts it all on one line instead. If you want to piecemeal `print!` multiple parts then … that’s not supported by defmt and not what is was designed to do. Local buffering might be the best solution.
<JamesMunns[m]> I tend to use embassy-time for ~everything, and I think it's the best embedded impl if you want a global, shared, monotonic timer.
<JamesMunns[m]> "time" is really 3-6 problems that look the same from the outside, but depending on things that are important to different people, it ends up very hard to find a "one size fits all" solution!
<n_vl[m]> JamesMunns[m]: I guessed as much.
<n_vl[m]> I was / am looking for something equivalent to vTaskDelay with xTickTypeMs from the FreeRTOS world.
<n_vl[m]> Something which says I don't have anything to do for the next while. Remind me when it's my turn. Ideally right after x time has passed.
<JamesMunns[m]> If you're using async and embassy time, you get a very convenient Timer::after(Duration::from_millis(...)).await
<JamesMunns[m]> which also lets you do things like timeouts on receiving or sending data, or any other future
<n_vl[m]> JamesMunns[m]: I was hoping to do a non embassy implementation as well.
<n_vl[m]> Something I could integrate into existing RTOS code bases
<n_vl[m]> btw. I loved the talk about postcard-rpc
<vollbrecht[m]> n_vl[m]: > <@n_vl:matrix.org> I was hoping to do a non embassy implementation as well.
<vollbrecht[m]> > Something I could integrate into existing RTOS code bases
<vollbrecht[m]> embassy-time is pretty much standalone, so while its for sure a dependency its not much of a "lock in"
<JamesMunns[m]> The big thing is that it requires an interrupt, to keep the timer rolling and accurate
<JamesMunns[m]> if that's not a blocker, you should be able to use it wherever.
<n_vl[m]> cool, thanks to the two of you
<JamesMunns[m]> If you really want to lean on your RTOS, then it might be better to make a library that works for you, and integrates well in the RTOS!
<diondokter[m]> Hmmm this is kinda tricky. If you have a device driver and it has a debug function `print_all_registers`, how would you want it to work?... (full message at <https://catircservices.org/_irc/v1/media/download/Ab3wrOJrpYGYqaFFSzOY4ypVsqGpn9CelPV8ZoszhIq1KzGMsXKvD396onwIZroD9bH6Qa97U-NY-rwYzKjc7zBCeS7RnoIwAGNhdGlyY3NlcnZpY2VzLm9yZy9Ba2ZMY1N2UmZneUtQSmZSQ0xWQWNQSFI>)
<JamesMunns[m]> diondokter[m]: > <@diondokter:matrix.org> Hmmm this is kinda tricky. If you have a device driver and it has a debug function `print_all_registers`, how would you want it to work?... (full message at <https://catircservices.org/_irc/v1/media/download/AVsuRG4eR_y0S-eSvolQ7E764AfPMAsmh6J3c8-t39BnecPahrQocMf8SIiivMBWFCFFfoImiTMa1HCV1a5bjilCeS7RpXHAAGNhdGlyY3NlcnZpY2VzLm9yZy9Md1lHVWdnV05vblJmeFdyT1pCWnVacEg>)
<JamesMunns[m]> JamesMunns[m]: yeah, the callback is sort of like that, I do think that'd be the most flexible
<JamesMunns[m]> but by making it an iterator it's easier to handle async or not async
<diondokter[m]> An iterator probably has the same issue with the register types. Like what'd be the type of the Item?
<n_vl[m]> It's less about wanting to and more about wanting to demonstrate having a plug and play solution in an existing C code base.
<n_vl[m]> In this case I have code that will do common logic both on an esp32 and an stm32.
<n_vl[m]> Being able to have portable code for both platforms that just works is a big +
<JamesMunns[m]> You can definitely make your own time traits as well, they don't have to ONLY come from embedded-hal!
<JamesMunns[m]> For example, you could write whatever timer trait you need, and have an impl for each hardware, or even one that is specific to "any FreeRTOS environment"
<JamesMunns[m]> Having the RTOS also makes it different, but maybe a little easier, because the RTOS probably already handles time at some level for you
<JamesMunns[m]> so I'd guess there's some "sleep" primitive available, like you mentioned.
<JamesMunns[m]> diondokter[m]: How many different "types" do you support?
<diondokter[m]> JamesMunns[m]: Every register is its own type. For this driver, over a hundred (though I hope to generalize it for the device-driver crate)
<vollbrecht[m]> n_vl[m]: > <@n_vl:matrix.org> It's less about wanting to and more about wanting to demonstrate having a plug and play solution in an existing C code base.... (full message at <https://catircservices.org/_irc/v1/media/download/AaHZ9xosbWFnl9XhNIfBGI6Srrifq-Z_91VUGBdQ212j8GkYwrkW6NIG0LpYlSTmo3zvbxzC0qh_cb3_CsvF9_tCeS7R9EKQAGNhdGlyY3NlcnZpY2VzLm9yZy9UenlNWlVCcmtkS0V4SklkWFdQZnhGeGs>)
<diondokter[m]> Maybe generate an enum?
<vollbrecht[m]> but the interface via traits is still usefull overall
<JamesMunns[m]> diondokter[m]: I think even with defmt, 100 fmt impls is going to be potentially Not Great
<diondokter[m]> Ha true. Using Debug it was taking 20kb
<diondokter[m]> * was taking >20kb
<diondokter[m]> But it's really only meant for debugging
<JamesMunns[m]> one option (maybe?) is to have a few primitive types, 8/16/24/32 bit unsigned values, then an array of names and bit ranges, and maybe metadata for each of those like variant meanings and/or endianness or r/w?
<JamesMunns[m]> postcard-schema uses a proc macro for this, but I end up making a lot of types that are `&'static` or `&'static [...]` that I make as consts
<JamesMunns[m]> that way if you never use them, they get removed, but you can get variably sized and variably nested items
<JamesMunns[m]> then you could have an iterator that was a visitor where the item is `(ItemEnum, &'static FieldMetadata)` or something
<diondokter[m]> Yeah that's interesting, but also a much bigger system than I want to implement for this...
<JamesMunns[m]> diondokter[m]: Fair, I've just spent the last 2 weeks improving this, and adding some pretty powerful const stuff (like a const fn that gives you all the unique types used by many schemas, for example)
<JamesMunns[m]> you can do some pretty powerful things with consts, const fns, and a little bit of proc macro/decl macro/codegen glue :D
<diondokter[m]> Yeah, been looking from the sidelines on what you post on bluesky and it seem pretty neat!
<JamesMunns[m]> your "read all registers" is a lot like my "retrieve all schemas" endpoint in postcard-rpc, though you do an additional external load for each value
<JamesMunns[m]> do you plan to end up having both an async and a non-async "read all registers"?
<diondokter[m]> Yep
<JamesMunns[m]> gotcha
<diondokter[m]> But that's easily duplicated
<JamesMunns[m]> (gotta run, happy to chat if you want impl ideas, otherwise I'm interested in what you come up with :) )
<diondokter[m]> Ideally we'd have higher ranked closures (there's probably a better name) where you can call a closure with a generic param
<diondokter[m]> Thanks!
chrysn[m] has quit [Quit: Idle timeout reached: 172800s]
<JamesMunns[m]> yeah, the visitor pattern, like serde, is one way to sort of emulate that
<JamesMunns[m]> e.g. a single trait with "do the thing with type/kind X"
<JamesMunns[m]> then the "driver" of the visitor picks which one to call
<JamesMunns[m]> then for different fields you'd have something like a "bitfield32" variant that has the `u32` and an array of fields, sort of like how different structs are serialized in rust
starblue[m] has quit [Quit: Idle timeout reached: 172800s]
<JamesMunns[m]> like a struct is a "kind", and it has an array of "fields"
<diondokter[m]> Yeah but I think that's too much...
<diondokter[m]> The point is not efficiency, but easy debugging. If you have to write a visitor implementation it might be efficient, but not easy
<diondokter[m]> I think I will just make a big enum with all the different registers and so the user can just print that.
<JamesMunns[m]> the trick, like serde, is to pick the minimal number of "unique kind"s, then express all the unique items as one of those kinds
<JamesMunns[m]> for example, like how `Vec<T>` and `[T]` and `HashSet<T>` all just end up being `Sequence(T)`
<JamesMunns[m]> anyway, you know your problem better than I do, like I said my head is just extremely in how postcard/serde work right now :D
<diondokter[m]> Ha yeah, it's a good idea and would work! It's just not the right tradeoffs for what I'm thinking :)
joelsa[m] has joined #rust-embedded
<joelsa[m]> <JamesMunns[m]> "anyway, you know your problem..." <- Maybe you’re the perfect person to give a hint about solving this problem then:... (full message at <https://catircservices.org/_irc/v1/media/download/AVYNvSH9WuxVXxAxf3APwPv7CKTzKCpVKtrfGOKnVCuI7m22ZQo8HN0EC_-HpKWOJhxt3L4E2LONfAsqxnhxa9pCeS7Y9NfgAGNhdGlyY3NlcnZpY2VzLm9yZy9NV3pCRVlub21pa3BlYXhYT3FEcVpCdks>)
<JamesMunns[m]> You could do it with serde, but honestly id probably use something like nom instead on a specific type for this
<JamesMunns[m]> IMO serde works best when the format is "general data store", and not "specific wire format"
<JamesMunns[m]> If it's always space separated, I might not even use nom, and just use "split whitespace"
<JamesMunns[m]> This is a repl for the command line, but honestly you could use the same pattern for parsing over the wire: https://github.com/jamesmunns/postcard-rpc/blob/066db484932698f653ba015add323f9700b14cad/example/workbook-host/src/bin/comms-02.rs#L8-L140
<JamesMunns[m]> joelsa ^
<JamesMunns[m]> You could have a bunch of types that impl some trait/method like "fn from_parts(&[&str]) -> Option<Self>`
<JamesMunns[m]> s/"/`/
<JamesMunns[m]> so you can have one top level match on the "command" word, or you can use slice patterns like I do in the repl
<JamesMunns[m]> but yeah, it depends on what you want to do. If you want a single enum for in/out, you could have basically that repl match inside of the `from_line() -> Option<Self>` method. If you just need to do the stuff, you could have what you need to do in each arm, like the repl does
<JamesMunns[m]> sorta depends on how you want/need to structure your program. Sometimes there's no need to match twice, once to make the enum then a second time on the enum to do something. But if you want to store a queue of messages in/out, then maybe having the enum is worth it.
<joelsa[m]> Thanks for the answer! :)
<joelsa[m]> <JamesMunns[m]> "This is a repl for the command..." <- Thats a great link and that looks like a sane and simple implementation.
<JamesMunns[m]> it's one of my favorite patterns! It's simple enough to not be a library, and makes for very quick CLI tools as well :D
<joelsa[m]> My reasoning for the structs is that I can just put a serde derive over it and store the existing configs into toml and slowly migrate the whole project
<JamesMunns[m]> yeah, that's fair, I would just have the "from wire/to wire" part not be serde
<JamesMunns[m]> you could have the configs still be serde for non-legacy usage, for sure
<joelsa[m]> <JamesMunns[m]> "You could have a bunch of..." <- Yep that plus building these impls with a proc_macro sounds like a sane way probably
hampycalc[m] has quit [Quit: Idle timeout reached: 172800s]
<RockBoynton[m]> James Munns: For postcard-rpc, it seems like the design is focused on PC <-> MCU comms, but is there anything necessarily precluding MCU (requester) <-> MCU comms (responder) config?
<JamesMunns[m]> Not precluded, just haven't needed it personally so I haven't written it.
scorpion2185[m] has quit [Quit: Idle timeout reached: 172800s]
<RockBoynton[m]> got it, I should have dug into the issue tracker first haha
<JamesMunns[m]> So now we have code for 3/4 configurations: MCU server, PC client, PC server. I intend to some day have an MCU client, and depending on how complete you want/need it to be, you could implement basic request/response, one-in-flight-at-a-time pretty easy
<JamesMunns[m]> Handling topic subscription with alloc is harder, or at least I don't have a handle of how I would do it yet without a lot of fiddly setup
<JamesMunns[m]> Handling topic subscription without alloc is harder, or at least I don't have a handle of how I would do it yet without a lot of fiddly setup
<JamesMunns[m]> Edit: without, not with
<RockBoynton[m]> On a more general note, I currently have a heterogenous repo that is organized as one cargo workspace that contains no_std libraries (with std and no_std features and examples), no_std binaries, and std binaries. Getting them all to work well with Rust-Analyzer is proving very difficult and I've just been manually changing the RA config target depending on what I'm working on and commenting out my std binaries in the workspace
<RockBoynton[m]> members (cause otherwise it fails to work on a thumb target and stops RA completely)
<RockBoynton[m]> Does anyone have suggestions for how to better organize my crates so I can have a seamless dev experience with RA?
<RockBoynton[m]> I was thinking of having all my libraries in one workspace and each binary in it's own crate instead, but I'm not sure if that will help
<Socke> on the esp32 with esp-idf-sys, how would I achieve that the system reboots once the main function returns?
<Socke> (other than just wrapping it into another function)
sroemer has quit [Ping timeout: 272 seconds]
gauteh[m] has quit [Quit: Idle timeout reached: 172800s]
cbjamo[m] has quit [Quit: Idle timeout reached: 172800s]
PhilMarkgraf[m] has quit [Quit: Idle timeout reached: 172800s]
notafbihoneypot[ has quit [Quit: Idle timeout reached: 172800s]
Icy-Thought[m] has quit [Quit: Idle timeout reached: 172800s]
M8alpreet[m] has quit [Quit: Idle timeout reached: 172800s]
danielb[m] has quit [Quit: Idle timeout reached: 172800s]
<vollbrecht[m]> <Socke> "on the esp32 with esp-idf-sys..." <- you don't need to overcomplicate here. You can make the last statement just a call to esp_restart() that would handle it.
<vollbrecht[m]> For an unhandeld error you always would panic and thous by default restart if you didn't change that default behaviour.