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
GuineaWheek[m] has quit [Quit: Idle timeout reached: 172800s]
pflanze has quit [Read error: Connection reset by peer]
pflanze has joined #rust-embedded
thejpster[m] has joined #rust-embedded
<thejpster[m]> does anyone have any good examples of an application that runs on a RISC-V core and uses peripheral interrupts?
<thejpster[m]> I understand the HAL would need to do some SoC-specific stuff to dispatch the interrrupt to the relevant hander, and I wanted to see the various ways people had done that
<JamesMunns[m]> (RV64 with a PLIC)
ivmarkov[m] has joined #rust-embedded
<ivmarkov[m]> Have you guys seen [this](https://github.com/Rust-for-Linux/pinned-init) and played with it? (Don't pay attention to the `pinned-` part, the crate also has an `Init` trait and `init!` macro sugar, that allows to safely placement-initialize `Unpin` values too) Took me ~ 2 hours [to retrofit `rs-matter` to use it](https://github.com/ivmarkov... (full message at
<ivmarkov[m]> * Have you guys seen [this](https://github.com/Rust-for-Linux/pinned-init) and played with it? (Don't pay attention to the `pinned-` part, the crate also has an `Init` trait and `init!` macro sugar, that allows to safely placement-initialize `Unpin` values too) Took me ~ 2 hours [to retrofit `rs-matter` to use... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/GFEiTYjQgGwJuMyUgeOikpiH>)
vancz has quit [Remote host closed the connection]
<JamesMunns[m]> Hadn't seen that before, will take a peek! I have hand-written in-place constructors before
<ivmarkov[m]> Comes from the RfL project, and they are using this stuff for real, in the kernel. Currently still needs the unstable allocator-api, but only because of AllocError :D. The author promised to remove this dependency, and then it will only depend on Rust stable.
<JamesMunns[m]> Neat!
<thejpster[m]> <JamesMunns[m]> "We use some on the Allwinner..." <- ah, run-time interrupt initialisation. Yeah, that bypasses having to work out what an `#[interrupt]` macro would do
<JamesMunns[m]> thejpster[m]: Yeah, at least on this chip, there's only one "real" interrupt line for periperals, the "External" interrupt. This means you need to "bring your own vectoring"
<thejpster[m]> yeah, I guess I was looking for a HAL that hid that issue and made it work like cortex-m-rt from an application point of view
<JamesMunns[m]> JamesMunns[m]: The plic is sort of a "second order" interrupt handler, it handles the muxing and priority of many peripheral interrupts, but the CLIC, connected to the CPU, only has a single or'd together interrupt line
<thejpster[m]> because a HAL could totally just emulate the NVIC in software and give you an #[interrupt] macro
dirbaio[m] has joined #rust-embedded
<dirbaio[m]> Esp32c3 maybe? But iirc they're moving to runtime registration too
jannic[m] has joined #rust-embedded
<jannic[m]> From a usability point of view, I'd say having to do a single interrupt_init call at startup would be fine. A bunch of unsafe initialization calls is less nice.
<JamesMunns[m]> yeah, the mnemos code is still very "proof of concept make it work" wrt interrupts, it's not great UX as-is.
<jannic[m]> It's also totally fine as an option if you want to do something special. I'd just prefer to have a simpler option for firmwares without special needs.
<thejpster[m]> it's also nice of the 'magic' you have to learn is portable across Arm and RISC-V
<thejpster[m]> s/of/if/
<dirbaio[m]> runtime registration is nicer especially with async, so hal drivers can register the interrupt on creation and deregister it on drop
<dirbaio[m]> but it needs putting the vectors in RAM
<dirbaio[m]> which is not great if you have little of it, like in a 4kb stm32, but is fine on esp32's which have 400kb+ of ram
<dirbaio[m]> so it makes somewhat sense to design the "magic" differently based on which chips you have ... 🥲
<JamesMunns[m]> <thejpster[m]> "it's also nice of the 'magic..." <- It might be tractable, but interrupt controllers aren't standard in RISC-V land
<thejpster[m]> right, but the idea of "here's the name of my interrupt" and "here's a freestanding function I want you to call when the interrupt fires" is fairly universal.
<thejpster[m]> so the user-facing API (like an #[interrupt] attribute) can be consistent. But the dispatch mechanism under the hood will vary.
<dirbaio[m]> But if you also want dynamic registration then you need two apis for the same thing, which is a downside
<thejpster[m]> currently cortex-m-rt doesn't support dynamic registration though, right?
vancz has joined #rust-embedded
<thejpster[m]> I think HALs all do their own VectorTable thing, like https://docs.rs/rp2040-hal/latest/rp2040_hal/vector_table/struct.VectorTable.html
<thejpster[m]> So 2 APIs is better than N.
<thejpster[m]> it probably makes sense for cortex-m / cortex-m-rt to offer a dynamic registration API. NVIC is just NVIC after all.
<M9names[m]> <JamesMunns[m]> "It might be tractable, but..." <- they are standard, it's just that there are plenty of standards :)
ithinuel[m] has joined #rust-embedded
<ithinuel[m]> Hey there, I haven’t followed the whole conversation but from the past few messages it seems to relate to APIs around interrupts their vector tables.
vancz has quit [Remote host closed the connection]
<ithinuel[m]> From the experience I have on other framework, including Zephyr RTOS, there are some quite quirky hardware designs so I can assure that there’ll always be N APIs required (eg second stage irq handlers, external IRQ controllers etc).
<ithinuel[m]> Vector tables and their alignment requirements aren’t super trivial to handle at runtime.
vancz has joined #rust-embedded
ryan-summers[m] has quit [Quit: Idle timeout reached: 172800s]
<ithinuel[m]> Cortex-Ms have NVIC and VTOR well defined so that helps but I don’t think cortex-m/cortex-m-rt can (nor should try to) have a one-size fits all solution.
<ithinuel[m]> so, 2 APIs (for static & dynamic registration) seems to be the best approach for cortex-m/cortex-m-rt IMHO.
<ithinuel[m]> also, Cortex-M0/+ do not always have a VTOR. So dynamic registration will require a not-so-zero-cost software indirection.
<thejpster[m]> I think I'd be inclined to just not offer dynamic IRQ dispatch on a CPU without support for putting the vector table in RAM. That just seems like a lot of work, when you could just design in a better CPU.
Rustnoob[m] has quit [Quit: Idle timeout reached: 172800s]
<ithinuel[m]> What would be the naming convention for sum-types & traits covering the same set of types (where the sum-type may itself be covered by the trait) ?
* ithinuel[m] wishes ær had some academic haskell background
<JamesMunns[m]> ithinuel[m]: You mean like enum-dispatch style? Not sure I understand
<ithinuel[m]> Ideally, the enum would be named AccessPort too, or the trait named differently 🤷
<JamesMunns[m]> what does being an access port let you *do*?
<JamesMunns[m]> (btw, while I have you ithinuel, I'd be interested in your thoughts on https://github.com/jamesmunns/bbq2 )
<ithinuel[m]> In the case of This trait, It’s only letting us get the address of that access port.
<JamesMunns[m]> Is the idea to use an enum so you can avoid box dyn trait?
<JamesMunns[m]> I'm kind of scratching around "why does it need to be a trait and an enum", but tbh I don't have any blanket naming suggestions :)
<ithinuel[m]> In that case yes. Well, I could use dyn trait but I’d still need to Any::downcast in places anyways.
<JamesMunns[m]> If it's all in an enum, how does the trait help then?
<ithinuel[m]> The Enum is to avoid needing downcasts in places and the Trait is to still allow generic methods to be used for any AccessPort.
<ithinuel[m]> The code base already exists, so I’m trying to minimise the required changes too.
<ithinuel[m]> ((it’s for probe-rs btw))
<JamesMunns[m]> Gotcha! Not sure if I have more helpful suggestions than calling the enum "AllAccessPorts" or "AnyAccessPort"
<ithinuel[m]> Thanks, I thought of plural forms would fit better collections and Any* makes me think of the AnyPin model we use in rp2040-hal (heavily inspired but atsam’s own AnyPin model).
<ithinuel[m]> Would `AddressableAccessPort` make sense for a trait that only has `fn ap_address(&self) -> &ApAddress` ?
<ithinuel[m]> The embedded-hal has "ErrorKind"
<ithinuel[m]> s/"/`/, s/"/` and `ErrorType`/
<ithinuel[m]> So, It could be AccessPortKind and AccessPortType but I really don’t know if that’d make sense in a language theory mind. 😄
<ithinuel[m]> or maybe do they refer to completely different thing and I’m missing the whole point.
pronvis has quit [Ping timeout: 264 seconds]
haobogu[m] has quit [Quit: Idle timeout reached: 172800s]
<thejpster[m]> what about calling the trait HasApAddress?
<thejpster[m]> you could take any T where T: HasApAddress
subtlename has quit [Ping timeout: 240 seconds]
subtlename has joined #rust-embedded
<thejpster[m]> I finally looked at replacing my unsound use of SpiDevice in embedded-sdmmc. The one card I tested seemed to tolerate having its CS pin toggled between an SD Card command and reading the reply, but can people help me out and try it on a bunch of other cards?
<thejpster[m]> Several HALs have SD Card examples (like the rp2040-hal I think, in the Pico BSP)