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
vollbrecht[m] has quit [Quit: Idle timeout reached: 172800s]
stgl has quit [Quit: ZNC 1.8.2 - https://znc.in]
stgl has joined #rust-embedded
khionu[m] has quit [Quit: Idle timeout reached: 172800s]
IlPalazzo-ojiisa has quit [Quit: Leaving.]
Guest7282 has left #rust-embedded [Error from remote client]
Guest7282 has joined #rust-embedded
Guest7282 has left #rust-embedded [Error from remote client]
Congyu[m] has quit [Quit: Idle timeout reached: 172800s]
<thejpster[m]> has anyone used nrfutil?
<thejpster[m]> did anyone realise it was written in Rust? TIL.
<michaeldesilva[m> Hi all, would anyone know why my chip is crashing at this point git remote add origin git@github.com:bsodmike/h7.git. Earlier today I was able to get it to run via the debugger (jlink with SWD) to the point where it flashed and LED in the main run loop https://github.com/bsodmike/h7/blob/master/h7-cm7/src/main.rs#L512-L515
<michaeldesilva[m> michaeldesilva[m: cc James Munns wondering if you'd have any suggestions :)
Guest7282 has joined #rust-embedded
<michaeldesilva[m> Unfortunately I cannot measure VCAP as this is a ball-grid array chip, and I don't see any obvious breakout points on the Arduino GIGA R1 WiFI board.
<michaeldesilva[m> * Hi all, would anyone know why my chip is crashing at this point git remote add origin git@github.com:bsodmike/h7.git. Earlier today I was able to get it to run via the debugger (jlink with SWD) to the point where it flashed and LED in the main run loop https://github.com/bsodmike/h7/blob/master/h7-cm7/src/main.rs#L512-L515.
<JamesMunns[m]> <michaeldesilva[m> "cc James Munns wondering if you..." <- Please don't tag specific people for general help requests.
ryan-summers[m] has joined #rust-embedded
<ryan-summers[m]> Not sure what you mean by "my chip is crashing". More descriptive info would be helpful. Do you get a hard fault? Does the debugger disconnect? Crashing can be a lot of things
<michaeldesilva[m> <JamesMunns[m]> "Please don't tag specific people..." <- Sorry, got it
<michaeldesilva[m> <ryan-summers[m]> "Not sure what you mean by "my..." <- It does this in a loop and does not stop... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/IBrDlpgwFMqdZBlwQRVBaqBa>)
<michaeldesilva[m> > <@ryan-summers:matrix.org> Not sure what you mean by "my chip is crashing". More descriptive info would be helpful. Do you get a hard fault? Does the debugger disconnect? Crashing can be a lot of things... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/EuvIhdbLYpkkuvYPJXKbBtSM>)
<ryan-summers[m]> My best guess is that the chip is working fine and your delay is never completing
<ryan-summers[m]> Can you confirm your delay implementation actually works and returns?
<michaeldesilva[m> yes it worked before (no change to the code)
<michaeldesilva[m> right now it doesn't get past the vco0 line, if I set a breakpoint after it, never gets there
<michaeldesilva[m> I can step through and set breakpoints on code before `let mut pwrcfg = pwr.vos0(&dp.SYSCFG).freeze();` it does not step through or stop on any BPs after that
<michaeldesilva[m> * set breakpoints (BPs) on code
<JamesMunns[m]> If you're changing power or frequency settings its possible the chip becomes unstable and the debugger loses control
<JamesMunns[m]> does step into si work instead of s for step/step over?
<michaeldesilva[m> si takes me as far as https://github.com/stm32-rs/stm32h7xx-hal/blob/master/src/pwr.rs#L487-L492 doesn't go beyond that ( and doesn't continue in main).
<JamesMunns[m]> oh lol
<michaeldesilva[m> and the VCAP pin is under a BGA "ball" lol
<JamesMunns[m]> Yeah, this means: "go read the reference manual and schematic"
<JamesMunns[m]> like, it means you are likely configuring the software in a way that does not match the hardware
<michaeldesilva[m> the Portenta H7 uses the same chip as the GIGA R1 WiFI - but I wonder if vos1 is too high a voltage given... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/aQfCcsHCniCorabQDBizyTTL>)
<JamesMunns[m]> I'm not familiar with that stm32 board, but there are certain dcdc and ldo and other power settings that might not be applicable depending on how the board is wired up
<michaeldesilva[m> 🤷‍♂️ the original author used the same setting for the Portenta though...
<michaeldesilva[m> JamesMunns[m]: True
<JamesMunns[m]> like, it's not necessarily the chip, which is general purpose, but specifically how the power supply circuit was wired up on that board.
<michaeldesilva[m> but what's concerning is that it worked for a few hours
<JamesMunns[m]> even though they use the same chip they might use different board wiring
<michaeldesilva[m> * but what's concerning is that it worked for a few hours - with the debugger and I could step into the loop().
<michaeldesilva[m> I then disconnected while having breakfast
<michaeldesilva[m> and then... it stopped progressing
<michaeldesilva[m> * stopped progressing. FYI I connected/disconnected several times when it worked too
<michaeldesilva[m> michaeldesilva[m: I had no trouble watching the LED colour progress through https://github.com/bsodmike/h7/blob/master/h7-cm7/src/main.rs#L154-L156
<michaeldesilva[m> * through https://github.com/bsodmike/h7/blob/master/h7-cm7/src/main.rs#L154-L156, since it's a RGB LED
<michaeldesilva[m> * through https://github.com/bsodmike/h7/blob/master/h7-cm7/src/main.rs#L154-L156, since it's a RGB LED - and then it kept on blinking the blue LED
<JamesMunns[m]> Not sure! It might be good to read the reference manual for that part of RCC, and figure out what the values are supposed to be. I'll let someone else with more experience with the stm32 h7 power circuitry chime in.
<ryan-summers[m]> If your voltage is unstable or something, it very well could work intermittently. You're outside of specified behavior at that point
<JamesMunns[m]> (I only know that it has a ton of options, and it might be getting upset if you are asking it to do something unreasonable)
<ryan-summers[m]> And/or not within spec
pflanze_ has joined #rust-embedded
stephe_ has joined #rust-embedded
cyrozap_ has joined #rust-embedded
Guest7282 has left #rust-embedded [Error from remote client]
<JamesMunns[m]> Misc note, I'm gunna ping about it in the meeting tomorrow, but if anyone has written a blog post they want to plug for https://github.com/rust-embedded/wg/issues/720, or still want to respond to the prompt, I'm going to be writing this this week. Please comment on the issue, including "hey I need a day but I plan to submit".
cyrozap has quit [*.net *.split]
pflanze has quit [*.net *.split]
stephe has quit [*.net *.split]
stephe_ is now known as stephe
<M9names[m]> <michaeldesilva[m> "and the VCAP pin is under a BGA..." <- the VCAP pins might be under the chip, but the parts they are connected to are not.
<M9names[m]> the schematic for the board will tell you what to look for, and the datasheet for the board has a nice high resolution image of component placement for you to find those parts
<M9names[m]> <michaeldesilva[m> "🤷‍♂️ the original author used..." <- when things go wrong, probably best to assume that you and others before you got it wrong.
<M9names[m]> maybe it worked just fine for them for a while, too? or they don't have that board and assumed like you that it would be the same.
<michaeldesilva[m> <M9names[m]> "the VCAP pins might be under the..." <- > <@9names:matrix.org> the VCAP pins might be under the chip, but the parts they are connected to are not.
<michaeldesilva[m> Oh doh! good point!!
<michaeldesilva[m> > the schematic for the board will tell you what to look for, and the datasheet for the board has a nice high resolution image of component placement for you to find those parts
<michaeldesilva[m> <M9names[m]> "when things go wrong, probably..." <- > <@9names:matrix.org> when things go wrong, probably best to assume that you and others before you got it wrong.
<michaeldesilva[m> > maybe it worked just fine for them for a while, too? or they don't have that board and assumed like you that it would be the same.
<michaeldesilva[m> Got it, thanks
<michaeldesilva[m> * Got it, thanks; it's also an old codebase
notgull has joined #rust-embedded
notgull has quit [Ping timeout: 252 seconds]
<michaeldesilva[m> C32, 33, 34 are connected to VCAP and gnd (bypass caps?)
<M9names[m]> makes sense. probably following design guidance from the chip reference manual.
<M9names[m]> PS: i'm not an EE, don't follow my electronics advice
<michaeldesilva[m> M9names[m]: I wasn't doing anything fancy apart from simple blinkys but I started off with C++/Arduino IDE. I managed to kill my other board, well so I assume as it no longer enters DFU mode. I basically cannot flash it (over USB).
<michaeldesilva[m> My remaining board is fine in terms of replacing the bootloader if I want to
<JamesMunns[m]> > I managed to kill my other board,
<JamesMunns[m]> Just in case, there's usually a way to force the board to reset power supply settings, there's an STM32 blog post on it somewhere, I think holding one of the pins low on startup? It may have been you wrote some incorrect power supply value and now it won't load.
<JamesMunns[m]> That being said, chips like this with their own integrated power circuitry do make it a bit more possible to actually fry them, than boards that just use a fixed external LDO or something
<JamesMunns[m]> https://community.st.com/t5/stm32-mcus/how-to-unbrick-an-stm32h7-after-setting-the-wrong-power-mode/ta-p/49691 is the post I've seen, not sure if it's possible on the arduino board with the pins available.
<michaeldesilva[m> <JamesMunns[m]> "https://community.st.com/t5/stm3..."; <- that guide refers to "user Flash" - they just mean the entire FLASH area right? https://github.com/bsodmike/cortex-m-quickstart-arduino-giga-r1-wifi/blob/master/memory.x#L8
<JamesMunns[m]> michaeldesilva[m: yes, afaik
<michaeldesilva[m> Thanks all for the help, taking a break for the day. Will be back :)
Guest7282 has joined #rust-embedded
<M9names[m]> One other bit of advice: Rust isn't the only game in town, others have managed to successfully use these boards.... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/XftjgVvPAdenImBUPpZMlHzX>)
IlPalazzo-ojiisa has joined #rust-embedded
exark has quit [Quit: quit]
exark has joined #rust-embedded
<JamesMunns[m]> btw have we discussed that the static mut transform in the cortex-m-rt::interrupt macro is only sound on single core devices?
<thejpster[m]> oh snap, I don't think we have
<JamesMunns[m]> https://github.com/rust-embedded/cortex-m/issues/411 sort of, but it's also #[interrupt] and not just #[entry]
<thejpster[m]> single image multi core systems, specifically. I think a multi core system running a unique image on each core would be OK.
<JamesMunns[m]> yeah, mentioned it in the comment
<JamesMunns[m]> only if they share the same vector table/isrs
<thejpster[m]> if anyone has any ideas on how to write https://github.com/rp-rs/rp-hal/blob/1481429255f518f4a481395bd4a157c9d482fec1/rp2040-hal/examples/gpio_irq_example.rs#L154 so it's both sound and non-ugly, that would be great
<JamesMunns[m]> I mean technically as written it is sound, but ONLY because you never start the second core.
<thejpster[m]> in general I reach for the static mut when the ISR has some state it needs to retain between executions.
<thejpster[m]> Thinking about the RP2040, you could make things better perhaps by having the HAL code that takes Core 1 out of reset also set Core 1's VTOR so it can't run any of Core 0's interrupts, with some #[interrupt(core1)] macro perhaps that puts it in the correct vector table.
<JamesMunns[m]> I can't remember how embassy sets up interrupts between the two cores, but conceptually it seems hard to handle "this is only safe if you don't use the static mut transform OR it only runs on one core"
<JamesMunns[m]> or "static mut transform XOR runs on both cores", esp since cmrt doesn't actually handle enabling interrupts for you
<JamesMunns[m]> imho: I think the right answer is "the static mut transform should go", it's confusing AND now sometimes unsound
<JamesMunns[m]> (I think a better fix is just good/better static data structures)
dirbaio[m] has joined #rust-embedded
<dirbaio[m]> embassy is designed so it doesn't care which irq the core runs on so it's not directly affected (it's still affected if the user writes an interrupt handler using static mut transform, but that's more like cortex-m-rt's fault)
<dirbaio[m]> I think the static mut transform should be moved from cortex-m-rt to a separate crate
<dirbaio[m]> so it's something the user specifically opts into using
<dirbaio[m]> with all the caveats
<dirbaio[m]> such as multicore-unsoundness
<JamesMunns[m]> I wonder if I need to revisit `cmim`, or my "fake mutex that just checks VECTACTIVE" trick: https://docs.rs/cmim/latest/cmim/
<JamesMunns[m]> e.g., when you "lock" the mutex, if you aren't in the specific configured ISR, it panics/fails
<dirbaio[m]> it's also multicore-unsafe isn't it?
<JamesMunns[m]> yeah, for it to be multicore sound you'd have to specify the core AND the interrupt
<JamesMunns[m]> could maybe default to core0? but idk if "check which core you're on" is actually portable
<JamesMunns[m]> probably not?
<dirbaio[m]> it's not :D
<dirbaio[m]> imo it's fine for crates from the ecosystem to be multicore-unsafe (as long as they document it ofc)
<dirbaio[m]> but we shouldn't have multicore-unsafe stuff in cortex-m crates such as cortex-m-rt
<JamesMunns[m]> yeah, so i'd need a feature like `single-core` that provides a default "get core" fn, or you'd have to bring your own
<dirbaio[m]> especially after putting the effort of fixing cortex_m::interrupt::free()
<dirbaio[m]> it's pointless if we leave multicore-unsafe stuff in cortex-m-rt :D
<JamesMunns[m]> sounds like it's time for a meeting nomination :D
<JamesMunns[m]> "audit c-m-rt for multicore unsound features" :p
<dirbaio[m]> I think it's only the static mut transfor
<dirbaio[m]> s/transfor/transform/
<JamesMunns[m]> I can change the title of this issue to a more general "`static mut` transform is unsound on multi-core systems"
<JamesMunns[m]> update: no I can't, not on the c-m team :D
<thejpster[m]> done
<thejpster[m]> i continue to believe that making the right thing the easy thing is the best approach
<thejpster[m]> and critical_section::Mutex<core::cell::RefCell<Option<bsp::Led>>> is not the easy thing
<thejpster[m]> * and `critical_section::Mutex<core::cell::RefCell<Option<bsp::Led>>>` is not the easy thing
<dirbaio[m]> agreed
<dirbaio[m]> the static mut transform doesn't help with that though, you still need the global `Mutex<RefCell<Option<T>>>` to temporarily move the thing into the static mut.
<dirbaio[m]> and it uses 2x the RAM
<JamesMunns[m]> imo people do want a "send to interrupt" data structure
<dirbaio[m]> RTIC 🙃
<JamesMunns[m]> (and ideally one that doesn't disable all other interrupts while you hold a `&mut` ref to it inside that interrupt)
<thejpster[m]> maybe the answer is to give them one, and leave it as a global static, and they have to pay the price of locking the item on interrupt entry. If they don't want to pay that price, they can use something like RTIC which solves the problem for them
<thejpster[m]> I have enough trouble teaching embedded rust without putting RTIC on day one (it's on day 3).
<dirbaio[m]> fwiw RTIC doesn't support multicore either
<thejpster[m]> there has to be a simple set of milestones between "hello, world" and "I push a button, an interrupt fires, and the LED goes blink", and then on to async/await or rtic or whatever you might build a production system out of
<thejpster[m]> simple, and ideally, sound
<dirbaio[m]> maybe teach raw interrupts last?
<thejpster[m]> they're embedded programmers learning rust
<thejpster[m]> they love interrupts
<thejpster[m]> they know interrupts
<dirbaio[m]> lol!
<dirbaio[m]> fair
<dirbaio[m]> so the issue is more "Rust makes using interrupts too hard", not "interrupts are advanced black magic"
<dirbaio[m]> 🤔
<JamesMunns[m]> "you've been lied to your whole career about how simple X thing is"
<JamesMunns[m]> is an evergreen "learning rust" take
<thejpster[m]> yeah, because an interrupt moves you into the land of "shared mutable state" because there's no way to move ownership into a freestanding function
<thejpster[m]> RTIC fixes this by making interrupt handlers methods, not freestanding functions (effectively). It hands the function its own state back every time.
<JamesMunns[m]> thejpster[m]: fwiw forever ago oli-obk had a crate that basically had a closure/spawn-like syntax for interrupt handlers
<thejpster[m]> I want like, 50% of that, but in plain and simple rust, not magical macro trickery.
<JamesMunns[m]> it never took off because it required heap alloc to move the context/closure environment
<dirbaio[m]> cmim looks quite close to what you're looking for
<JamesMunns[m]> He used that when teaching his embedded university course
<JamesMunns[m]> yeah, very seriously, if there is interest, I can update cmim to current crates and make it multicore sound.
<dirbaio[m]> JamesMunns[m]: TAIT? 🤔
<JamesMunns[m]> it lowers the cost to a core + vectactive check in the interrupt, and acts like a fancy version of StaticCell more or less
<JamesMunns[m]> dirbaio[m]: yeah, I was wondering that too
<JamesMunns[m]> can you statically name a closure type like that?
<dirbaio[m]> with TAIT, yes
<JamesMunns[m]> neat, I knew you could for async fns, wasn't sure if you could with a closure too
<dirbaio[m]> async fns and closures are the same kind of "cursed unnameable types" yeah
<JamesMunns[m]> yeah, I have no idea how you can define a static that references the type of the closure inside of the main fn, but maybe you can also define the static in the same scope?
<JamesMunns[m]> idk what tait syntax actually looks like lol
jannic[m] has quit [Quit: Idle timeout reached: 172800s]
<JamesMunns[m]> Neat!
<JamesMunns[m]> todo: make a cool interrupt handler crate when tait lands
<dirbaio[m]> it'd be the cleanest syntax by far 🚀
<JamesMunns[m]> Jonas also made a "scoped interrupts" crate: https://docs.rs/irq/latest/irq/
<dirbaio[m]> just move things into the irq handler closure
<JamesMunns[m]> dirbaio[m]: yeah, and get back an "irq handle" that can be used to disable the irq and get back the state bits
<JamesMunns[m]> dirbaio[m]: how far out is TAIT these days? :p
<dirbaio[m]> very :(
<dirbaio[m]> but ATPIT is nearer and it might be enough for this use case too
FreeKill[m] has quit [Quit: Idle timeout reached: 172800s]
<JamesMunns[m]> dirbaio[m]: lmao I love cursed feature initials, ATPIT is a new one to me
<dirbaio[m]> associated type position impl Trait :D
<JamesMunns[m]> "associated type position impl trait"
<dirbaio[m]> TAIT in associated types
<dirbaio[m]> actually I think it's not enough for this use case
<dirbaio[m]> because you need the closure to capture stuff from the parent function
<dirbaio[m]> you can't move it to a dummy trait method
<dirbaio[m]> gah
<JamesMunns[m]> can you use an owning capture rather than a borrowed capture?
<JamesMunns[m]> ah
<JamesMunns[m]> dirbaio[m]: guess not
<dirbaio[m]> it's not enough for static_cell::make_static!() either which is a giant shame
<dirbaio[m]> it'll be enough for embass-executor tho
<dirbaio[m]> ¯\_(ツ)_/¯
<JamesMunns[m]> dirbaio[m]: yay for yeeting the pool allocator
<dirbaio[m]> a sorely needed yeeting indeed
notgull has joined #rust-embedded
notgull has quit [Ping timeout: 264 seconds]
Guest7282 has left #rust-embedded [Error from remote client]
Guest7282 has joined #rust-embedded
kenny has quit [Quit: WeeChat 4.2.1]
kenny has joined #rust-embedded
Guest7282 has left #rust-embedded [Error from remote client]
Guest7282 has joined #rust-embedded
a2800276 has joined #rust-embedded
TomB[m] has joined #rust-embedded
<TomB[m]> <dirbaio[m]> "fwiw RTIC doesn't support..." <- Multicore adds many many annoyances
<TomB[m]> * many annoyances, I've learned a lot working on related things in Zephyr... some asymmetric/symmetric, doesn't matter... many annoyances
<TomB[m]> * many annoyances, I've learned a lot working on related things in Zephyr... asymmetric/symmetric, doesn't matter... many annoyances
<TomB[m]> In the end everything ends up needing a mailbox between cores anyways, almost better off starting off with message passing and avoiding the disaster that is shared memory until you actually (maybe never) need it
<TomB[m]> suddenly cache effects, atomics, and such become performance critical things that if not handled with care thrash the instruction pipes and icache/dcache's
<thejpster[m]> which reminds me of the hubris OS where every task is its own application
<TomB[m]> * effects, atomics, placement in memory, and such
<TomB[m]> thejpster[m]: I'm working on something similar for Zephyr, with linux kernel like loadable elfs and such, where you could load an elf and run it in a user mode (mpu/mmu controlled memory access) thread, seems to be a very desired feature lately
<thejpster[m]> you might quickly run into issues with debug symbols in rwpi code.
<thejpster[m]> i think hubris cheats by working out the memory map in advance and linking each binary statically. I think.
<thejpster[m]> but last i checked lld bails if you try and link an rwpi Cortex-M binary with any debug symbols in it.
<TomB[m]> yeah debugging and dictionary logging suddenly become a lot more "interesting"
<thejpster[m]> TockOS is similar ... I can't remember if they are stuck with applications written in C or if they have some other solution
<TomB[m]> I didn't bother with rwpi or pic, for arm I implemented it by having the loader do the final linking
<thejpster[m]> I solve the problem on my OS by being like MS-DOS and only letting you load one program at a time
<TomB[m]> so its a static elf that's partially linked (missing symbols linked at load time, and regions need relocation ops done)
<thejpster[m]> how do you make a not-finally-linked ELF and that loader can fixup?
<thejpster[m]> I mean, ld can do it on linux, but how do you teach a bare-metal linker to do that?
<TomB[m]> to do the linking? write a linker basically
<thejpster[m]> oof
<TomB[m]> it reads the elfs, and applies the relocations
<thejpster[m]> yaks not gunna shave itself
<TomB[m]> surprisingly much simpler than you might expect with a few simple rules...
<TomB[m]> for arm I had to implement all of 2 relocations to make it work so far
<thejpster[m]> what does the toolchain look like to make the sort-of-static ELF in the first place?
<TomB[m]> the key is to force the compiler to not generate pc relative bl[x] instructions and that solves like 95% of the issue
<TomB[m]> so -mlong-calls
<TomB[m]> gcc flag
<thejpster[m]> what's wrong with PIC for the program code?
<dirbaio[m]> the hubris "each task is a separate application with memory isolation and IPC" is "microservices for microcontrollers"
<dirbaio[m]> you separate SPI into an "SPI task", now every SPI transfer is an IPC call with a context switch
<dirbaio[m]> and unsurprisingly it's slow as hell https://artemis.sh/2022/03/28/oxide-hubris-on-pinetime.html
<TomB[m]> dirbaio[m]: > <@dirbaio:matrix.org> the hubris "each task is a separate application with memory isolation and IPC" is "microservices for microcontrollers"... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/xJQdUyKYdYtRVjWJfxBnoffi>)
<dirbaio[m]> the advertised advantage of it is "if a task crashes it can restart without bringing down the rest of the system"
<TomB[m]> it doesn't exactly look like microservices, but it kind of becomes it
<JamesMunns[m]> I haven't made it as far as I want to with mnemos, but I wonder if having the io_uring style syscall interface would buy a good chunk of that back
<dirbaio[m]> but it's only true if you spend 3x the effort on error handling
<dirbaio[m]> like, if you have a "filesystem task" and another task is using it to read/write a file
<TomB[m]> James Munns: yeah I started implementing that for zephyr too!
<dirbaio[m]> and the filesystem crashes
<dirbaio[m]> * the filesystem task crashes
<TomB[m]> because of that exactly thing, and I think the answer in my mind at least is Yes
<dirbaio[m]> the user task suddenly finds its file handles are POOF gone
<JamesMunns[m]> but it's still a thing I don't think makes sense at like "small mcu" scale - mnemos is more aimed at like cortex-A/rv64, and it HAPPENS to work okay on big MCUs
<dirbaio[m]> in what other OS can your file handles magically disappear like that?
<dirbaio[m]> in none
<dirbaio[m]> nobody writes code with that in mind
<dirbaio[m]> so in the end the only option you're left with is if the FS task crashes, restart everything that depends on it too
<dirbaio[m]> at which point you're restarting everything anyway
<TomB[m]> James Munns: actually... I think it does, I feel like about 80% of the mcu does is setup I/O tasks (embassy embodies this really right...)
<TomB[m]> io_uring is a queue of I/O tasks mostly
<dirbaio[m]> so you might've as well written a plain old monolithic firmware and let it all restart on crash
<JamesMunns[m]> Honestly, IMO embassy is a much better choice for MCUs, for all the reasons dirbaio is mentioning :D
<JamesMunns[m]> like, if you statically KNOW what the firmware is supposed to do: save yourself a lot of heartache and make a good firmware instead
<dirbaio[m]> and spend like 10% of the engineering effort you spent into creating microservices for microcontrollers into trying to make your firmware not crash in the first place :D
<JamesMunns[m]> OSs get more compelling when you have "programs over time", if that makes sense
<JamesMunns[m]> like, if the user installs stuff, and you really are building a general purpose PC? yeah! have an OS! Building a specific device? No! Make one application/firmware!
<JamesMunns[m]> I have seen some "run third party code on your MCU" interest, idk if I've ever seen it done well
<thejpster[m]> tradeoffs though
<TomB[m]> So one of the users of Zephyr is SOF, and SOF lets you run on these xtensa hifi dsps for audio pipes
<thejpster[m]> if one task is talking to the radio and one task is talking to the engine CAN bus, I want more than "engineers tried hard" to prevent a bad DAB graphic from taking out my brakes
<TomB[m]> those audio pipes, like gstreamer for example, might change what they do over time
<TomB[m]> * audio pipes, kind of like gstreamer, * like gstreamer/pipewire/etc for
<TomB[m]> so its a lot less known whats going to be done when you go to build the firmware
<TomB[m]> a lot of stuff might be there built in doing nothing
<TomB[m]> * doing nothing, some parts of the pipeline might be developed and built by different people, etc
<JamesMunns[m]> idk, I think embedded is wide enough that we could all "well what about" each other till the cows come home
<thejpster[m]> how dare you propose a solution for your problem that doesn't also fix my problem
<thejpster[m]> it's an outrage
<JamesMunns[m]> i'm gunna state: I think monolithic firmwares, probably without even an RTOS, are a better choice for 90% of firmware projects
<TomB[m]> haha, no doubt
<TomB[m]> some of the easiest and least bug ridden firmwares I've created myself were... simple super loops in C
<thejpster[m]> this is the internet, and I'll not countenance nuance and tolerance here
<JamesMunns[m]> I think there are some very interesting applications of:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/IjnPvLsPYtVffMQrBTAJZxnV>)
<thejpster[m]> the lowest power firmware I ever wrote was also a super loop. true fact.
<thejpster[m]> lasted 10 year on a single lithium cell. Apparently - it hasn't been running that long yet.
<JamesMunns[m]> (I've talked >1 customer off the ledge of "what we need is docker for MCUs" when what they need is basically like two rust crates and a monolithic firmware)
<dirbaio[m]> overengineering baby
<dirbaio[m]> * overengineering, baby!
<TomB[m]> JamesMunns[m]: did they also say they wanted kubernetes?
<thejpster[m]> won't someone thing of the consultants
<TomB[m]> I've directly heard this nonsense myself
<thejpster[m]> s/thing/think/
<dirbaio[m]> I bet they were looking at using WASM for their docker for MCUs
<JamesMunns[m]> anyway, enjoy the memeing. I do want to play with thejpster's work on a minimal runtime linker, and the preprocessing approach is very similar to what Tom B said
<TomB[m]> * nonsense myself (not in my current employment)
<JamesMunns[m]> dirbaio[m]: yes, I saw one doing that, tho those weren't my customers
<dirbaio[m]> 🫠
<TomB[m]> JamesMunns[m]: yeah its... really surprisingly not as terrible as I imagined
<JamesMunns[m]> (imo, "wasm on mcus" is silly because a prerequisite is "have good portable hardware abstractions for the wasm interface", and we've spent 6 years on so far and its still hard and no one else is doing it well)
<TomB[m]> I had envisioned this arduous endless task... and then I had stuff working in a week or two
<JamesMunns[m]> like, I think scripting on MCUs is sometimes very neat and fun and useful. I've done it with forth, I know others have with Lua, I know some have with wasm too. but that's not the hard part, and everyone who says it is The Future is trying to sell you something (or is smoking VC funding)
<thejpster[m]> man I could do some seriously crazy shit if I had VC funding
<TomB[m]> thejpster: maybe helpful, the compiler flags I used to make my life easy for this... -mlong-calls -mthumb -c- o output.elf something.c
<JamesMunns[m]> At least, that's my opinion today, and if someone out there proves me wrong I'd be very open and excited about it :)
lulf[m] has joined #rust-embedded
<lulf[m]> The downsides of monolithic firmware appears less of a problem when using a language like Rust too, but I can more understand the paranoia in a C world. I reminds me a bit of monolithic vs microkernels. Microsoft had an approach to OS design named 'Singularity' that iirc went down the 'language safety' rather than microkernel approach.
<JamesMunns[m]> thejpster[m]: it's like the aladdin scene: "Phenomenal Cosmic Power! itty bitty living space"
<JamesMunns[m]> lulf[m]: yeah, I feel like "true isolation" (e.g. trustless 3rd party code) and "maximum efficiency" are opposite options.
<thejpster[m]> IIRC the macOS kernel (XNU) is a microkernel (Mach) that has a bunch of drivers loaded into the same address space for performance
<JamesMunns[m]> so like, you can use Rust with a monolithic app and be pretty sure the safe code works the way you expect, OR you can have a trust boundary, and pay different flavors of cost in temporal and spacial partitioning
<thejpster[m]> someone said that on a post the other day, and it hit me like a bell
<thejpster[m]> resiliance and efficiency are in tension
<thejpster[m]> explains a lot about politics actually
<JamesMunns[m]> thejpster[m]: yeah, I'd agree with this. I don't either is particularly right, and there are a million different lines you can draw in efficiency that matter more or less for your use cases
DrJoniPelham[m] has joined #rust-embedded
<DrJoniPelham[m]> thejpster[m]: Yes this is particularly well illustrated with how logistics chains get effected by shipping issues. Manufacturing got so used to minimising warehousing to be more efficient (JIT, Kanban, etc) that when there is a delay even small it can result in assembly lines having to shutdown for awhile until they have what is needed.
<thejpster[m]> apparently we use to have a UK Government minister responsible for both: https://www.gov.uk/government/ministers/minister-for-government-resilience-and-efficiency
<thejpster[m]> which I think says a lot
<DrJoniPelham[m]> Yeah saving money without sacrificing resilience. Difficult brief... 😅
<JamesMunns[m]> thejpster[m]: > turning a big dial taht says "resilience/efficiency" on it and constantly looking back at the audience for approval like a contestant on the price is right
<thejpster[m]> higher, higher, lower lower!
<JamesMunns[m]> btw any folks still/recently in the safety critical world out there? Does anyone know if "Must" is the recommended replacement term for "Shall" for requirement docs these days?
<JamesMunns[m]> It was "Shall" back in my day, but I think it shifted away from that towards Must (from looking at rfc2119 terms)
MatthieuDartiail has joined #rust-embedded
<JamesMunns[m]> This is the right forum!
<JamesMunns[m]> The answer is probably: there isn't something out of the box for doing what you ask today
<JamesMunns[m]> There are some people I am aware of who have done some level of code generation for gateware, either generating an SVD and feeding it to svd2rust or a similar tool, or generating Rust directly
<JamesMunns[m]> Also, I don't think svd2rust supports Cortex-A targets? But that might matter less for you in a hosted environment like Linux where you mostly just want accessor functions for hardware peripherals with some level of type/ownership safety.
<JamesMunns[m]> there's also `chiptool`, which might be more accessible to general register codegen, I think someone was recently using it to generate code for external I2C/SPI hardware that has "registers" for configuration and stuff, not sure
<JamesMunns[m]> (https://github.com/embassy-rs/chiptool is sort of a cousin to svd2rust, with different capabilities)
<thejpster[m]> I don't have a preference, but there was an RFC to clarify that you MUST write them in uppercase.
<MatthieuDartiail> I discussed with the FPGA people but apparently there is no obvious way for them to generate SVD. So I was considering mostly writing Rust directly. Thanks for the link to chiptool I will have a look.
<JamesMunns[m]> Yeah! If you can get the fields, including addresses and value meanings, in SOME kind of machine readable format (JSON, CSV, whatever), you can probably write something that translates that into the yaml or xml or whatever that the other tools need
<JamesMunns[m]> stuff like bitfield sizes, enumerated meanings for subfields, addresses, names, etc.
<MatthieuDartiail> Another thing that is not clear to me is how those crates work in the presence of an OS. Since I need to mmap things rather than access them directly.
<JamesMunns[m]> it's not uncommon to "invent" an XML, even doing stuff like scraping PDF tables into raw data, cleaning it up, and making an XML for that
<JamesMunns[m]> MatthieuDartiail: yeah, all those tools (AFAIK) assume a fixed memory address
<JamesMunns[m]> so like, you'd need to use the address you mmap to
<JamesMunns[m]> (MAP_FIXED, I think?)
<MatthieuDartiail> Ok I will to play around then. Currently the C code doing those things use MAP_SHARED but I will have to see if it really needed.
<MatthieuDartiail> * Ok I will have to play around then. Currently the C code doing those things use MAP_SHARED but I will have to see if it really needed.
<JamesMunns[m]> (i'm not so familiar with mmap, so I mostly just mean that stuff will always be at the specific addr, not some variable base + offset)
<JamesMunns[m]> so like the UART will ALWAYS be at 0x4000_0000, or something :D
<MatthieuDartiail> Yes there is a bunch of fixed addresses that are mapped.
boondocker[m] has joined #rust-embedded
<boondocker[m]> Assuming you're writing in linux userspace and mmap from /dev/mem to map some physical base address into the virtual address space of a process? You could write a register access struct that then works at offsets from the mapped region
<MatthieuDartiail> Yes that is what I have in mind, I am mostly trying to figure out what is the best way to write those register access. As I sais my impression from the book was that it was better to avoid doing it manually due to the amount of boiler plate. But it will be a good exercise for sure.
<MatthieuDartiail> s/sais/said/
<boondocker[m]> maybe look at how svd2rust generates register access code, or the svd2rust docs to get a sense of how it generates accessors
vollbrecht[m] has joined #rust-embedded
<vollbrecht[m]> a interface adapter with some macro's to generate registers, bitfields etc is something like tock-registers. I used that on an armv7 running linux to some mmap peripheral where i otherewise could not get access. Though this is just for the interface, if you dont want to use the macro's and defining all register manually you could write some software that implements the
inara has quit [Quit: Leaving]
inara has joined #rust-embedded
adamgreig[m] has quit [Quit: Idle timeout reached: 172800s]
<vollbrecht[m]> adamgreig: for the meeting tomorrow i would like to add a topic if it would fit into it. Is there already a place where it could be added.
<vollbrecht[m]>
<vollbrecht[m]> We in (esp-hal / esp-idf-hal) want to touch on a topic around "embedded-svc". We would appreciate some feedback especially from other projects that also provide networking / storage in some form. ( rp2040 / embassy etc). In short its about the future of the crate itself. Here is the current relevant [issue](https://github.com/esp-rs/embedded-svc/issues/72)
<vollbrecht[m]> s/./?/, s///
Ralph[m] has joined #rust-embedded
<Ralph[m]> <vollbrecht[m]> "adamgreig: for the meeting..." <- > <@vollbrecht:matrix.org> adamgreig: for the meeting tomorrow i would like to add a topic if it would fit into it. Is there already a place where it could be added?... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/NiFUxItJdhxdXiCfJKIaprZC>)
<JamesMunns[m]> Ralph[m]: fwiw, I'm probably going to do a breaking postcard release to avoid this happening again, it's not just heapless
<JamesMunns[m]> JamesMunns[m]: I should have been better about "deps in public API" hygiene, but what can you do.
<dirbaio[m]> I don't think heapless is ready for 1.0, there's a bunch of stuff in the pipeline that massively changes the api
<JamesMunns[m]> dirbaio[m]: Oh?
<dirbaio[m]> like alignment for the buffer (PR'd) or ability to use borrowed slices (not PR'd yet)
<dirbaio[m]> and even then
<dirbaio[m]> the api surface is giant
<Ralph[m]> <dirbaio[m]> "I don't think heapless is..." <- i wasn't aware of that. that's actually why i had raised my ticket (same in a variety of other repos): to ask the maintainers to create tracking issues (where they're lacking) for anything needed for v1.0 and then assign them to a v1.0 milestone - this way it's clearly visible how far away a crate is from stabilisation and (potential) consumers can make an informed decision about whether
<Ralph[m]> they're ok with the current 0.x stability guarantees or if they'll likely be heavily impacted by upcoming changes.
<Ralph[m]> i think it'd be good if the heapless maintainers (not sure who that is, tbh) could do that (raise issues + create & assign milestone(s)). having a "v1.0" milestone for must-haves and optionally a "non-breaking post v1.0" milestone might help (or just consider anything not tagged as the latter)
<dirbaio[m]> maintainers are the WG libs team (newAM, reitermarkus, me) currently
ragarnoy[m] has quit [Quit: Idle timeout reached: 172800s]
<JamesMunns[m]> Added a comment, tbh I want heapless to make a 1.0 release, but also a 2.0 release some day, and tbh we shouldn't make heapless part of anyones public API
<dirbaio[m]> what's the point of a 1.0 if we plan to do 2.0 later then?
<JamesMunns[m]> tbh it should have been 1.0 since like 0.7
<dirbaio[m]> it'd be the same as now, a major release every 1-2 years
<JamesMunns[m]> yeah
<JamesMunns[m]> I don't think that's unreasonable
<dirbaio[m]> just the optics of having them be 1.0, 2.0, 3.0... instead of 0.7, 0.8, 0.9....
<JamesMunns[m]> yep
<JamesMunns[m]> I don't think versions should stop at 1.x
<JamesMunns[m]> but also that's fully in the "opinions and vibes" camp and not like, actual arguments
<dirbaio[m]> thing is
<dirbaio[m]> when people are asking "please do 1.0"
<dirbaio[m]> what people REALLY are asking is "please commit to not doing more breaking changes"
<JamesMunns[m]> yep, totally fair, I fell into that case when I wrote my first comment, and now realize that is an unreasonable ask and that's why I'm walking back my old comments
<dirbaio[m]> i.e. "please stop evolving your library because its current state is already good enough for me and I don't want to have to update my code for breaking changes"
<JamesMunns[m]> "don't make a 2.0 ever" just means "someone else makes a totally different crate with a different name but does 80% of the same thing and that's not actually better
<JamesMunns[m]> * actually better"
<JamesMunns[m]> * same thing" and
<JamesMunns[m]> like, if someone wants some different API, or get tired of papercuts that are now unfixable, they just release "unheapable" or whatever until it hits some critical mass, and on and on
<JamesMunns[m]> maybe that's fine and better and people can handle that better. it's all actually about the same, and still all vibes
<JamesMunns[m]> just stating my weak preference that people get over the concept of "forever stable" code that isn't in the stdlib
<dirbaio[m]> and anyway, heapless is a really bad fit for using in public APIs. using a Vec in arg or return value is a nice way to blow up your stack very quickly
<dirbaio[m]> so
<dirbaio[m]> IMO the value of heapless 1.0 is not that high, and the downside of not being able to evolve is high
<dirbaio[m]> it's like the complete opposite of embedded-hal, where the whole point of the crate is a 1.0 stable api
<JamesMunns[m]> agree to disagree, but you're a maintainer and I'm not, so my vote doesn't count for anything :)
<dirbaio[m]> (also this is my opinion, I don't speak for the team)
<JamesMunns[m]> might be good to document the design goals/plan somewhere tho, just to avoid asks like this in the future.
<dirbaio[m]> yeah
<JamesMunns[m]> like, I totally agree its all vibes
<JamesMunns[m]> theres no difference between 0.x releases and x.y releases, it's still a breaking change, and if someone wants to use 1.x as a sentinel for "we'll deprecate before making a breaking change", that's cool too.
<JamesMunns[m]> I should probably add a "don't be surprised if breaking change every 1-2 years" to postcard'd docs, for expectation management too.
adamgreig[m] has joined #rust-embedded
<adamgreig[m]> <vollbrecht[m]> "adamgreig: for the meeting..." <- > <@vollbrecht:matrix.org> adamgreig: for the meeting tomorrow i would like to add a topic if it would fit into it. Is there already a place where it could be added?... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/suarDAQhZTgblzkTNJHHoidn>)
<Ralph[m]> <dirbaio[m]> "and anyway, heapless is a really..." <- how would you then model an API which returns a list of things in a consumer-friendly way (in `no_std` land)? sure, i could ask the caller to allocate the memory for me and just give me a mutable slice, but that feels ugly? though now it's also not particularly great as the caller has to specify at compile-time how many entries he'd like to receive at most 😐️
<dirbaio[m]> yes. pass a mut slice in, return length
<dirbaio[m]> > though now it's also not particularly great as the caller has to specify at compile-time how many entries he'd like to receive at most 😐️
<dirbaio[m]> isn't that the case with heapless too?
<JamesMunns[m]> downside of that is for nontrivial items: the slice has to contain valid items
<dirbaio[m]> yeah it starts to get ugly when you do slice of maybeuninits
<JamesMunns[m]> like, if you are returning some struct, you almost need to pass in `&mut [MaybeUninit<T>]`, and get back `&mut [T]`
<JamesMunns[m]> ¯\_(ツ)_/¯
<JamesMunns[m]> I'd say use tinyvec, which is 1.0, but that probably means most people will have tinyvec and heapless in their dep tree
<Ralph[m]> <dirbaio[m]> "IMO the value of heapless 1.0 is..." <- there's no reason not to evolve after a 1.0. 1.0 just says "this API is now ready to be used productively, we follow semantic versioning (ok, that's not a statement of 1.0, that's a statement in your README - hopefully)".... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/JPXWffTpBlEKEDYRCOiuXWNA>)
<JamesMunns[m]> and that's the same as having heapless 0.7 and 0.8 in your dep tree
<dirbaio[m]> returining vecs by value is a bad practice and will blow up your stack
<dirbaio[m]> just don't do it
<dirbaio[m]> find something else
<JamesMunns[m]> fwiw: I agree with what you quoted Ralph, but if 0.7 -> 1.0 is blocking you, 1.0 -> 2.0 will block you too.
<dirbaio[m]> either mut slice, or invent another crate that makes it nicer
<dirbaio[m]> heapless is not the tool for this
<Ralph[m]> dirbaio[m]: > <@dirbaio:matrix.org> > though now it's also not particularly great as the caller has to specify at compile-time how many entries he'd like to receive at most 😐️... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/itJulADtUYgzSNjvWvvwvnhf>)
<dirbaio[m]> neither is tinyvec
<dirbaio[m]> not sure I follow. both with heapless and with mut slices you have to set some compile-time max length... that's the whole point of not using alloc
<JamesMunns[m]> huh, suprised tinyvec doesn't have a `&mut [MaybeUninit<T>] -> SliceVec` option
<JamesMunns[m]> dirbaio[m]: I think you agree
<dirbaio[m]> ah you mean it's worse wth heapless because you need the const generic. yes, I agree
<JamesMunns[m]> he was saying "even still, that still sucks with heapless"
<Ralph[m]> yep, exactly (see link to code above for details). sorry for not having written this clearer in the first message
<adamgreig[m]> <JamesMunns[m]> "It was "Shall" back in my day..." <- everything I've seen recently is still "shall", sometimes with a note about 'must' like
explodingwaffle1 has joined #rust-embedded
<explodingwaffle1> <Ralph[m]> "> <@dirbaio:matrix.org> > though..." <- maybe you want/need a https://docs.rs/managed/latest/managed/enum.ManagedSlice.html style abstraction (of smoltcp fame)
<MatthieuDartiail> <vollbrecht[m]> "a interface adapter with some..." <- Thanks I will have a look
<explodingwaffle1> <JamesMunns[m]> "huh, suprised tinyvec doesn't..." <- i guess it's because tinyvec is forbid(unsafe_code)? which is an interesting design choice, especially since it means ArrayVec<T> needs T: Default
<explodingwaffle1> SliceVec seems like a nice thing to have to avoid generics and suchlike while being able to track size instead of just having a capacity. 🤔
<JamesMunns[m]> explodingwaffle1: > <@explodingwaffle101:matrix.org> i guess it's because tinyvec is forbid(unsafe_code)? which is an interesting design choice, especially since it means ArrayVec<T> needs T: Default
<JamesMunns[m]> > SliceVec seems like a nice thing to have to avoid generics and suchlike while being able to track size instead of just having a capacity. 🤔
<JamesMunns[m]> maybe we need a 10th "stack allocated buffer with a vec-like api" crate these days.
<explodingwaffle1> s/unsafe_code/unsafe\_code/, s/<T>//
<explodingwaffle1> * i guess it's because tinyvec is forbid(unsafe\_code)? which is an interesting design choice, especially since it means the default impl for ArrayVec needs T: Default
<explodingwaffle1> SliceVec seems like a nice thing to have to avoid generics and suchlike while being able to track size instead of just having a capacity. 🤔
<explodingwaffle1> * i guess it's because tinyvec is forbid(unsafe\_code)? which is an interesting design choice, especially since it means the default impl for ArrayVec needs T: Default
<explodingwaffle1> SliceVec seems like a nice thing to have to avoid const generics while being able to track size instead of just having a capacity. 🤔
spinfast[m] has joined #rust-embedded
<spinfast[m]> <MatthieuDartiail> "I discussed with the FPGA people..." <- I use yaml and chiptool to map something like that in Linux before
<spinfast[m]> * Linux before, writing the yaml chiptool wants is nicer than the xml svd eants
<spinfast[m]> * Linux before, writing the yaml chiptool wants is nicer than the xml svd wants
<spinfast[m]> > <@mdartiailh:matrix.org> I discussed with the FPGA people but apparently there is no obvious way for them to generate SVD. So I was considering mostly writing Rust directly. Thanks for the link to chiptool I will have a look.
<spinfast[m]> * I used yaml and chiptool to map something like that in Linux before, writing the yaml chiptool wants is nicer than the xml svd wants
dne has quit [Remote host closed the connection]
dne has joined #rust-embedded
Dr_Who has quit [Quit: So long and thanks for all the bits.]
crabbedhaloablut has quit [Ping timeout: 256 seconds]
crabbedhaloablut has joined #rust-embedded
crabbedhaloablut has quit [Ping timeout: 252 seconds]
crabbedhaloablut has joined #rust-embedded
IlPalazzo-ojiisa has quit [Remote host closed the connection]