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
<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
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.
<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?
<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]>
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?