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
Farooq has joined #rust-embedded
<Farooq> Do you know a roadmap to become a Rust kernel and firmware developer? I don't have any bare metal experience. But I have extensive experience developing normal programs. Plans I have in mind include porting Asterinas(the Rust kernel) to a simple RISC-V SBC as well as writing drivers for FreeBSD and/or Linux. What I have in mind is that I first get my hand dirty with std development on MCUs such as STM32, RPi Pico and ESP32. Then I go
<Farooq> no_std on these platforms. Then I think I will become ready to write drivers for Linux or FreeBSD. And finally I could think about porting a kernel like Asterinas to a new platform or SoC.
<Farooq> Tho I'm unsure about state of Rust in FreeBSD and Linux. Hopefully, they will support Rust well in 1-2 years when I want to get my hands dirty.
Farooq has quit [Changing host]
Farooq has joined #rust-embedded
pcs38 has joined #rust-embedded
Lumpio[m] has joined #rust-embedded
<Lumpio[m]> First step on any roadmap would be to get some board and blink an LED
<Lumpio[m]> What comes to the specifics you mentioned, I haven't heard of std support on STM32 or RP2040 so it's all no_std there. Linux allows Rust in modules only, and that is also no_std land.
M9names[m] has joined #rust-embedded
<M9names[m]> Farooq [Master Potato]: I don't think there's any "how to become a firmware person or a general purpose OS kernel person" roadmap, but I can tell you those are very different roles.... (full message at <https://catircservices.org/_irc/v1/media/download/AWZ3X4b4ai8_ZZA35pV_ugYF9eJIQc3OSsq9hs9DWGXe_Tl5XK8etLe1vDcboub4wZuDYjkgJ-6eWuFThvrAPqe_8AAAAAAAAGNhdGlyY3NlcnZpY2VzLm9yZy95a3RhUGJiT3lDSUJ0VE1hY2ZKYnFIV0s>)
<Farooq> I have to finish my current side project before I start a new one
<Farooq> but yeah I've bought a STM32, an RGB Matrix, and a joystick. I'll be creating a small toy for my little cousin
dngrs[m] has joined #rust-embedded
<dngrs[m]> forum.rust-embedded.org is defunct, right? (https://github.com/rust-embedded/wg/blob/master/CODE_OF_CONDUCT.md mentions it)
<dngrs[m]> * forum.rust-embedded.org is defunct, right? (https://github.com/rust-embedded/wg/blob/master/CODE_OF_CONDUCT.md links to it)
<JamesMunns[m]> I can't even remember it ever being a thing
stgl has joined #rust-embedded
<dngrs[m]> It's mentioned in a few historic places but maybe it was always wishful thinking? 😅
<dngrs[m]> I'll prepare a PR.
jotthyr[m] has quit [Quit: Idle timeout reached: 172800s]
mameluc[m] has joined #rust-embedded
<mameluc[m]> I am trying to use panic_reset but when I do I get stuck in the HardFault loop
<mameluc[m]> Frame 1: <unknown function @ 0x08000d20> @ 0x08000d20
<mameluc[m]> Error: CPU halted unexpectedly.
<mameluc[m]> Frame 0: "HardFault handler. Cause: Escalated UsageFault (Undefined instruction)." @ 0x08001682
<mameluc[m]> so I guess it fails at `8001682: strbr0, [r7, #-85]`?
<mameluc[m]> Anybody knows what I am doing wrong?
<mameluc[m]> This is on an M4 core using thumbv7em-none-eabi
jason-kairos[m] has joined #rust-embedded
<jason-kairos[m]> unrelated question: has anyone ever passed a pointer/reference to an asm block only to have the compiler optimize away the variable whose address you passed into the asm block?... (full message at <https://catircservices.org/_irc/v1/media/download/ASZR0zLr_D7iSQbtvLwcWZZbf3xm58ZtuBSeUVuAPPaXa7Ay4zDEc2CNcFlmPgrJ20UUsLgT3k2HrhtO34QFUui_8AAAAAAAAGNhdGlyY3NlcnZpY2VzLm9yZy9zaFJ0d05abmp2UGhYVWR1T0dDRXZ0aWM>)
<jason-kairos[m]> * unrelated question: has anyone ever passed a pointer/reference to a variable to an asm block only to have the compiler optimize away that same variable?... (full message at <https://catircservices.org/_irc/v1/media/download/AU_l6Kw2MY7B-M07Dp6X47tb0Db41KTxsY0m8C7SAU21i33UNh4QQghEnWXedOIZguQ4lu-gdhafMYDgVXrRX3e_8AAAAAAAAGNhdGlyY3NlcnZpY2VzLm9yZy9Ya1ppdUtzUHVoQ2dtcnJka25zSU14YmE>)
<jason-kairos[m]> * unrelated question: has anyone ever passed a pointer/reference to a variable to an asm block only to have the compiler optimize away that same variable?... (full message at <https://catircservices.org/_irc/v1/media/download/AVaWamWOZwBbTSbOjCkNrTK521QLMu6ks2mhnhBEl_E5aH6s1Dldi4tLGsyKdg5bJPeISFgzZiEVhYcDgcj_PX6_8AAAAAAAAGNhdGlyY3NlcnZpY2VzLm9yZy9zdVRqekNqeHZtY2Z0SWlOV3NIaU5TUmk>)
pcs38 has quit [Quit: leaving]
<jason-kairos[m]> the address of my_option is 0x22bb8
<jason-kairos[m]> the address of write ends up being 0x22b18
<jason-kairos[m]> the size of the structure of 0x38 - so something is totally invalid
dne has quit [Remote host closed the connection]
dne has joined #rust-embedded
adamgreig[m] has quit [Quit: Idle timeout reached: 172800s]
<jason-kairos[m]> Found my answer, it's very easy to generate a move and invalidate the original option.
Hallo124 has quit [Remote host closed the connection]
Hallo124 has joined #rust-embedded
Ralph[m] has quit [Quit: Idle timeout reached: 172800s]
vollbrecht[m] has quit [Quit: Idle timeout reached: 172800s]
Hallo124 has quit [Remote host closed the connection]
Hallo124 has joined #rust-embedded
<thejpster[m]> I'm trying to program the clock tree on an STM32F3 without using a HAL, and probe-rs is disconnecting if I try and run at 72 MHz. Dividing HSE by 2 makes it work (so, it should be 36 MHz).
<thejpster[m]> I feel like I'm forgetting something...
<thejpster[m]> I have remembered to halve PCLK1 and set the flash latency
<jason-kairos[m]> the configurator tool is good for that
<jason-kairos[m]> studying the clock tree in the ref manual is also pretty much required
GuineaWheek[m] has joined #rust-embedded
<GuineaWheek[m]> wait is there seriously not a good way to await on multiple timer channels with inputcapture at a time in embassy
<jason-kairos[m]> (I avoid async to avoid learning how to do poll shenanigans properly)
<jason-kairos[m]> * (I avoid async to avoid learning how to do the required shenanigans properly)
<thejpster[m]> aaaaaa. I type the Flash peripheral base address wrong.
Hallo124 has quit [Remote host closed the connection]
Hallo124 has joined #rust-embedded
jfsimon has quit [Remote host closed the connection]
jfsimon has joined #rust-embedded
<GuineaWheek[m]> also i can’t figure out how to join the embassy matrix room
<GuineaWheek[m]> like i can’t find a link anywhere
<JamesMunns[m]> https://matrix.to/#/#embassy-rs:matrix.org
therealprof[m] has joined #rust-embedded
<therealprof[m]> <thejpster[m]> "I'm trying to program the..." <- I'd check with STM32Cube for your particular chip... Some models have some annoying specialities.
<GuineaWheek[m]> in general the discoverability of matrix rooms seems really really bad
<JamesMunns[m]> surprised embassy isn't on that list already tho
xnor has quit [Quit: WeeChat 3.4]
<jason-kairos[m]> is async stuff valuable on embedded if you are already using an RTOS with threads?
<jason-kairos[m]> I suppose automatically gives you something like an IPC interface - which maybe might be nicer than what an RTOS provides
<jason-kairos[m]> for some reason, I've had a hard time selling myself on the idea. (Async is great for dealing with Amazon's web APIs, but embedded, I don't know)
reto[m] has joined #rust-embedded
<reto[m]> @[Guinea Wheek] heres also the rust embedded space on matrix that is very helpful: https://matrix.to/#/#rust-embedded-space:matrix.org
<GuineaWheek[m]> i joined the space but i can’t see a list of rooms
<GuineaWheek[m]> on element
ivmarkov[m] has joined #rust-embedded
<ivmarkov[m]> jason-kairos[m]: - Async helps reduce the number of threads you might be having otherwise. And thus the need to carefully size the stack of each of these
<ivmarkov[m]> - Purely from programming POV, async is structly superior to blocking, as it has something Boats call "intra-task concurrency" which I've found incredibly useful
<ivmarkov[m]> - Finally, async these days might be a necessity, as a lot of crates are async-only, as as a minimum, you should prepare yourself for a lot of `block_on!`s, if you want to stay in the blocking world
<ivmarkov[m]> s/call/calls/
<JamesMunns[m]> oh hey I'm writing slides for this right now :D
<JamesMunns[m]> I dunno about "strictly superior", but it's a neat tool, and a different way of solving problems. It's very well matched to a lot of embedded problems. Strictly ignoring it would be a shame, because there's a lot of problems you can solve very directly using async.
<JamesMunns[m]> but it's like any other tool: nothing is *compelling* you to use it, and you don't *have* to.
<ivmarkov[m]> Can't imagine not having select these days. I mean, the "good" select, not - like - select!.
<JamesMunns[m]> yep, it has become very core to how I solve problems, personally!
<ivmarkov[m]> Maybe share your sildes, for us, mortals to see and learn :P
<jason-kairos[m]> Can you give a concrete example, maybe a link to a simple project that uses async in a canonical way?
<ivmarkov[m]> Otherwise, of course - https://without.boats/blog/let-futures-be-futures/
<JamesMunns[m]> ivmarkov[m]: wednesday :p
<ivmarkov[m]> Ah, also cancellation. I mean, for me - drop = cancel is a godsend. Even with all the "cancel safe" caveats.
<GuineaWheek[m]> is it possible to access the raw PAC via embassy_stm32
<ivmarkov[m]> jason-kairos[m]: Difficult.... there was a youtube video popular around here which goes from "manual polling" to "async"... but it is more of a "you don't need a task scheduler" type of a thing IMO rather than "you still would benefit from it even on top of a task scheduler" thing...
<ivmarkov[m]> * need a (traditional) task scheduler", * of a (traditional) task scheduler"
<JamesMunns[m]> jason-kairos[m]: the short answer is that lots of embedded problems are *waiting* on things: waiting on a packet, waiting on a dma transfer, waiting on a button.
<JamesMunns[m]> async is a set of tools of writing state machines *over time*.
<jason-kairos[m]> side remark: I've seen C libraries that would benefit from a (more ergonomic) task scheduler, or threads, or whatever
<ivmarkov[m]> In all fairness, you could still wait in a blocking way on those things. That's the definition of an RTOS by the way. It is just that, when you need to wait on multiple things, in my opinion, in blocking it becomes a bit hairy
<jason-kairos[m]> * I've seen embedded C libraries
<ivmarkov[m]> ... or when you need to "cancel" stuff. How do you "cancel" a thread?
xnor has joined #rust-embedded
<jason-kairos[m]> from what I've seen embedded threaded 'things often end up with some version of IPC clients/servers/notifications/requests/responses/etc
<jason-kairos[m]> * threaded 'things' often
<jason-kairos[m]> I agree, canceling is a foreign concept to me
<jason-kairos[m]> I imagine that threads with IPC stuff on top is something akin to "poor man's async"
<JamesMunns[m]> I don't think you have to orient it one over the other, just different tools for different cases
<JamesMunns[m]> for example: hubris allows for totally killing a task, or handling a panic
<JamesMunns[m]> which is not generally possible in async/await alone
<jason-kairos[m]> (I'm still trying wrap my head around the questions of what makes a state machine async shaped?)
<jason-kairos[m]> s/questions/question/
<JamesMunns[m]> generally, if you have state machines that are waiting for events, they are a good candidate for async
<JamesMunns[m]> basically, futures are "entities that will resolve into an event, at some point in the future"
<JamesMunns[m]> that could be receiving a message, getting a notification, a button press, etc.
<JamesMunns[m]> I started writing this, but it wasn't succinct enough, maybe if it's useful I'll come back and draw the rest of the owl :D
<JamesMunns[m]> but it does cover futures a bit
<JamesMunns[m]> (I immediately got deeper into the impl than I wanted to, :/)
<ivmarkov[m]> jason-kairos[m]: Note that a `Future` per se is not an escape hatch from state machines hell. It is the async syntax specifically.
<jason-kairos[m]> So I've very familar with enum based state machines, timers and "analog" comparators and such in rust
<jason-kairos[m]> I get the rough impression from the draft document James linked to that some enum variants might be replaced with lines of code with async?
<jason-kairos[m]> s/ve/m/
<ivmarkov[m]> What I'm saying is, writing a future by yand means a terrible, error prone, explicit state machine, just like in older c/c++. It is much better to let the compiler generate the future impl for you by you using the async syntax, with the usual if s while s and so on.
<ivmarkov[m]> s/yand/hand/
<jason-kairos[m]> (ie. position in a function becomes the enum variant / state of the state machine)
<ivmarkov[m]> jason-kairos[m]: > <@jason-kairos:matrix.org> So I'm very familar with enum based state machines, timers and "analog" comparators and such in rust
<ivmarkov[m]> > I get the rough impression from the draft document James linked to that some enum variants might be replaced with lines of code with async?
<ivmarkov[m]> Yes. async gives you linear flow that is easier to grok by humans, but the compiler converts to an enum state machine.
<jason-kairos[m]> * state machine ?)
<ivmarkov[m]> jason-kairos[m]: Yes, roughly.
<jason-kairos[m]> Okay, I can sort of buy the idea that aync used in that fasion might make a 5 state timer "thingy" with multiple state transitions easier to follow
<jason-kairos[m]> s/aync/async/
<jason-kairos[m]> s/aync/async/, s/fasion/fashion/
<ivmarkov[m]> Once you go beyond a timer, explicit state machines become intractable imo. But this topic is tange tial to your original question of why writing implicit state machines with async versus just using threads, which are just as implicit but more heavyweight hard cancellation, and wait-for-multiple-ovjects in win32 so to say is a terrible api and that's what you have with threads only.
<ivmarkov[m]> * in win32 is so to
<ivmarkov[m]> * Once you go beyond a timer, explicit state machines become intractable imo. But this topic is tangential to your original question of why writing implicit state machines with async versus just using threads, which are just as implicit but more heavyweight hard cancellation, and wait-for-multiple-ovjects in win32 is so to say is a terrible api and that's what you have with threads only.
<ivmarkov[m]> * Once you go beyond a timer, explicit state machines become intractable imo. But this topic is tangential to your original question of why writing implicit state machines with async versus just using threads, which are just as implicit but more heavyweight; and have hard cancellation, and wait-for-multiple-ovjects in win32 is so to say is a terrible api and that's what you have with threads only.
<ivmarkov[m]> * Once you go beyond a timer, explicit state machines become intractable imo. But this topic is tangential to your original question of why writing implicit state machines with async versus just using threads, which are just as implicit but more heavyweight; and have hard cancellation, and wait-for-multiple-ovjects in win32 so to say is a terrible api and that's what you have with threads only.
<ivmarkov[m]> * Once you go beyond a timer, explicit state machines become intractable imo. But this topic is tangential to your original question of why writing implicit state machines with async versus just using threads, which are just as implicit but more heavyweight; and have hard cancellation, and wait-for-multiple-objects in win32 so to say is a terrible api and that's what you have with threads only.
<ivmarkov[m]> * Once you go beyond a timer, explicit state machines become intractable imo. But this topic is tangential to your original question of why writing implicit state machines with async versus just using threads, which are just as implicit but more heavyweight; but have hard cancellation, and wait-for-multiple-objects in win32 so to say is a terrible api and that's what you have with threads only.
<ivmarkov[m]> * Once you go beyond a timer, explicit state machines become intractable imo. But this topic is tangential to your original question of why writing implicit state machines with async versus just using threads, which are just as implicit but more heavyweight; but have hard cancellation, and wait-for-multiple-objects in win32 so to say is a terrible api but that's what you have with threads only.
<KevinPFleming[m]> <GuineaWheek[m]> "is it possible to access the raw..." <- yes add the unstable-pac feature to the dependency in cargo.toml
<jason-kairos[m]> are there any good examples of async used to simplify a modestly complex enum based state machine? (I know, it really just depends on the application)
Dlaw[m] has joined #rust-embedded
<Dlaw[m]> jason-kairos[m]: Well, they're more than "modestly" complex, but the I think the embassy-net and embassy-usb drivers owe much of their success and succinctness to being written as async drivers
<i509vcb[m]> ivmarkov[m]: Not embedded, but I have a wayland compositor implementation where the window management is async and it takes the incredibly complicated state machines you need to maintain (especially for transactional layout updates) and makes it very simple.
<i509vcb[m]> i509vcb[m]: Code is a bit too much of a mess for public though
<jason-kairos[m]> i509vcb[m]: I have a feeling it's going to take me a few years to learn to think async by default
<i509vcb[m]> jason-kairos[m]: although async as default isn't always the best option
<jason-kairos[m]> i509vcb[m]: a lot of potential for hidden complexity
<i509vcb[m]> jason-kairos[m]: I've tried using async for "static dynamic dispatch" in a PC emulator and I had to write some incredibly complicated single slot "bus" channel to make it perform okay enough
<ivmarkov[m]> i509vcb[m]: Speaking of `embassy-net`... `rs-matter` is async too. (and no_std and no-alloc). It is a giant state machine too, in many ways (or a bunch of giant state machines), but can't imagine writing it as such explicitly. As the Matter C++ SDK did. The alternative would've been threads, but even Matter C++{ does not use those.
<ivmarkov[m]> * Speaking of embassy-net... rs-matter is async too. (and no_std and no-alloc). It is a giant state machine too, in many ways (or a bunch of giant state machines), but can't imagine writing it as such explicitly. As the Matter C++ SDK did. The alternative would've been threads, but even Matter C++ does not use those due to reasons (embedded, low footprint etc. etc.).
<jason-kairos[m]> ivmarkov[m]: It often seems to me that where async really shines is in request/reply type packet communications
<jason-kairos[m]> everywhere else, even timers and state machines, is kind of meh...
<jason-kairos[m]> * It often seems to me that where async really shines is in request/reply type packet communications (eg. multiple concurrent connection type things)'
<jason-kairos[m]> everywhere else, even timers and state machines, is kind of meh...
<JamesMunns[m]> jason-kairos[m]: I'd say give it a try before you pass judgement. It's worth learning, even if just to have a better understanding of what you're avoiding.
<ivmarkov[m]> jason-kairos[m]: I disagree, but in the end, nothing is black or white. I guess you have to get your feet wet with async Rust in embedded, and then judge for yourself. It is difficult to assess it by just looking at it "from the outside". I was having similar questions a few years ago, as in, the extra cognitive burden of async might not be worth it, but once you "get it" at least for me - it is a productivity gain. Even on top of
<ivmarkov[m]> an rtos.
kl1n3 has joined #rust-embedded
kline has quit [Ping timeout: 608 seconds]
<ivmarkov[m]> ivmarkov[m]: By the way, timers are actually a great simple example where async really shines. How would you do timers on top of an embedded rtos if you only have blocking stuff? Callbacks. Quite inconvenient.
<jason-kairos[m]> ivmarkov[m]: Callbacks? nah... in a threaded system one would yield execution until some condition was true.
<jason-kairos[m]> jason-kairos[m]: suppose I have a system that collects events and sends data onto a bus/network every 20 minutes
<jason-kairos[m]> some events get queued up for the 20 minute interval, others might trigger an immediate transmission
<jason-kairos[m]> jason-kairos[m]: with async, how would that translate?
Noah[m] has joined #rust-embedded
<Noah[m]> is there an easy way to get a debugger on a teensy?
<JamesMunns[m]> Noah[m]: no, none of the pins are broken out
<i509vcb[m]> iirc the teensy doesn't expose jtag/swd pins at all?
<ivmarkov[m]> jason-kairos[m]: yes. but if you happen to run on top of a freertos, its systick is 10ms, so if you want higher res, you need a timer with a callback. Sure, the timer then can wake a condvar from its callback on which a thread is waiting but... more code than with async. And arranging threads and... If you really want to stay theoretical and assess it on that level, the article of Boats - in its intra-task concurrency section - is
<ivmarkov[m]> exactly about that topic. But yeah, theoretical. Get your feet wet. :) I stop now.
<dngrs[m]> huh. that's weird.
<jason-kairos[m]> Do any async system have the concept of time? ie. like run this task in 10 minutes, or "oh wait I changed my mind, run that task immediately"
<jason-kairos[m]> I'm trying to imagine how one would shoehorn an async runtime into a thread based system
<dngrs[m]> jason-kairos[m]: not as a primitive, but you can layer something like that on top. You can sleep, like in threads
<dngrs[m]> and for changing your mind, you'd select on a sleep task and an abort-sleep-task
<jason-kairos[m]> s/system/systems/
<i509vcb[m]> You pretty much say, run both tasks pick the first to finish
<i509vcb[m]> s/run/poll/, s/tasks/futures/
<i509vcb[m]> or may be preferable depending whether you want a timeout to take priority or the semaphore to take priority
<ivmarkov[m]> Since the actual task is nowhere to see, a variation of the above would be:
<ivmarkov[m]> select and race are - putting the details about fairness execution aside - the same thing
<jason-kairos[m]> Do the async runtimes have any concept of time, or are the just spin polling internally?
<jason-kairos[m]> I imagine it just depends
<dngrs[m]> jason-kairos[m]: neither
<dngrs[m]> it's not a problem solved by this layer
<thejpster[m]> <i509vcb[m]> "iirc the teensy doesn't expose..." <- Pretty sure Teensy is the platform with the proprietary boot stuff, to prevent people cloning the hardware.
<thejpster[m]> That mount be why debugging is disabled
<thejpster[m]> s/mount/might/
<dngrs[m]> jason-kairos but to answer what I think you actually want to know: it's not gonna be busy waiting
<jason-kairos[m]> I suppose it must be event based then, and yielding/running to completion are events
<dngrs[m]> that's what I'm trying to tell you: how it is implemented is not the concern of the async runtime
<i509vcb[m]> If you read about how async runtimes are implemented on platforms with std you hear the idea of a "reactor" (the thing that wakes up a task due to some external thing, like a timer), well in embedded the "reactor" is your hardware
<dngrs[m]> it could be implemented in various ways. Interrupts, timers, etc. Even busy waiting. But that's all a question of the timer guts, not the async guts
<dngrs[m]> case in point, some "async" stuff (on std) is actually blocking under the hood, e.g. tokio file io
andwass[m] has joined #rust-embedded
<andwass[m]> This talk gives some info how it works under the hood for embassy
<dngrs[m]> you might also find this article insightful, it specifically mentions sleeps/timer things: https://fasterthanli.me/articles/pin-and-suffering
<dngrs[m]> it's pretty heavy though, goes into a lot of details you won't typically need.
<jason-kairos[m]> so in embassy and other systems, do the derive/proc macros manually add state machine structs to some global variable / task list for the executor to look at?
<dngrs[m]> the async state machine is generated by the rust compiler
<i509vcb[m]> jason-kairos[m]: iirc intrusive linked lists are how the task registration works, but the compiler does the async state machines
jfsimon has quit [Remote host closed the connection]
jfsimon has joined #rust-embedded
<KevinPFleming[m]> The 'let-futures-be-futures' blog post linked earlier today is really useful for understanding these things; I read it today while sitting in a medical office waiting room and I learned things :-)
Hallo124 has quit [Remote host closed the connection]
Hallo124 has joined #rust-embedded
dirbaio[m] has quit [Quit: Idle timeout reached: 172800s]
rafael[m] has quit [Quit: Idle timeout reached: 172800s]
jfsimon has quit [Remote host closed the connection]
jfsimon has joined #rust-embedded
jfsimon has quit [Remote host closed the connection]
jfsimon has joined #rust-embedded
Foxyloxy has quit [Read error: Connection reset by peer]
Foxyloxy has joined #rust-embedded