<re_irc>
<thejpster> There’s a one liner in the readme to boot Linux on a LiteX SoC in verilator
<re_irc>
<thejpster> LiteX is like a “build your own SoC” Thing but all the parts are pluggable so it’s pretty easy. And the standard design should be fine for what you need? If not, shouldn’t be much tweaking.
<re_irc>
< (@korken89:matrix.org)> Looks nice
<re_irc>
< (@korken89:matrix.org)> Is there any CLIC impl for it? A bit of googling and I'm not really finding anything :/
<re_irc>
< (@korken89:matrix.org)> Seems like it's not that ready maybe
<re_irc>
< (@korken89:matrix.org)> I guess using critical section like locks for initial testing is fine though
<re_irc>
< (@chrysn:matrix.org)> Coming back briefly to the log-to-defmt topic of a few days ago: I've crated the snippet as log-to-defmt (https://crates.io/crates/log-to-defmt). It's not much code, but I hope it serves as a discoverable point, serves the right warnings (roughly "don't do this in production, it's beside the point of defmt"), but is also where users can spool their improvements (like, right now it completely disregards...
<re_irc>
... log levels).
<re_irc>
<thejpster> What does CLIC do? Is it like NVIC?
<re_irc>
< (@korken89:matrix.org)> Yes
<re_irc>
< (@korken89:matrix.org)> It's more or less an NVIC copy
<re_irc>
<thejpster> What do RV32 cores provide if not that? Something bespoke?
<re_irc>
< (@korken89:matrix.org)> Their own homecoocked interrupt controller :)
<re_irc>
<thejpster> A LiteX SoC can have a ton of peripherals so it must have some kind of interrupt controller.
<re_irc>
< (@korken89:matrix.org)> There standardization for interrupt controllers and RISC-V has been a bit of a wild west
<re_irc>
<thejpster> Ah. And you’re writing something for CLIC specifically? (Is it RISC-V RTIC?)
<re_irc>
< (@korken89:matrix.org)> Yes
<re_irc>
< (@korken89:matrix.org)> I'd like to support RTIC on CLIC to start with
<re_irc>
< (@korken89:matrix.org)> As it's close and has all the features on the NVIC
<re_irc>
< (@korken89:matrix.org)> And then I'd like to try the CH32V307, which also has all we need but is their own home cooked interrupt controller
<re_irc>
< (@chrysn:matrix.org)> thejpster: Isn't there also the option for cores to just have a CLINT (like, the light version of CLIC)?
<re_irc>
<duskmoon (Campbell He)⚡️> Is CLIC standard?
<re_irc>
<thejpster> Like the raiseable priority level bi can see how RTIC would be tricky without that.
<re_irc>
< (@korken89:matrix.org)> Yes, there is the CLINT
<re_irc>
< (@chrysn:matrix.org)> CLINT is barebones, but it's workable, right? I mean, sure, no nested interrupts or priorities, no multi-core, but at least it has multiple interrupts, so hey, there are chips with less :-)
<re_irc>
<thejpster> Seems there’s at least one implementation
<re_irc>
< (@korken89:matrix.org)> : I think we will support this as well (it's like the old AVR version of RTIC)
<re_irc>
<thejpster> But if you want to write some rust, building a SoC in verilog and running it in verilator is a hell of a rabbit hole
<re_irc>
< (@korken89:matrix.org)> Just I don't want to start with that 😅
<re_irc>
<thejpster> Like making a pcb to run your own OS on…
<re_irc>
< (@korken89:matrix.org)> Hehe
<re_irc>
< (@chrysn:matrix.org)> "From NAND to tetris and onwards to self-hosting Rust"?
<re_irc>
<thejpster> I mean you can run rustc on a LiteX SoC, so NAND to Rust seems doable.
<re_irc>
< (@korken89:matrix.org)> Maybe I'll try to find if I can simulate a core with CLINT
<re_irc>
< (@korken89:matrix.org)> Maybe a core exists for that
<re_irc>
<duskmoon (Campbell He)⚡️> I think is ok to just work on sifive’s implementation for now. Or finding a way to use only basic interrupt and clint. (Though there are chips without clint)
<re_irc>
< (@chrysn:matrix.org)> Hm, picorv32's interrupt controller seems not to have one of the standard interrupt controllers :-/
<re_irc>
< (@korken89:matrix.org)> Aww
<re_irc>
< (@chrysn:matrix.org)> * be
<re_irc>
< (@korken89:matrix.org)> I was just checking picorv32
<re_irc>
< (@korken89:matrix.org)> I once got that running so it was my goto xD
<re_irc>
< (@chrysn:matrix.org)> I'm still waiting for a project for which I'd do that on an ice40, but it hasn't happened yet. In the early years of the YoSys project, I've chatted with one of the authors about doing micropython stuff on the softcore, but that didn't pan out.
<re_irc>
< (@korken89:matrix.org)> :)
<re_irc>
< (@korken89:matrix.org)> For my usecase I don't really care if it fits in an FPGA as long as it follows the spec :)
starblue has quit [Ping timeout: 272 seconds]
starblue has joined #rust-embedded
<re_irc>
<michael.desilva> Hi anyone got an example of an I2c slave device please?
<re_irc>
<iliketurtles> Anyone know of a good overview of how critical-section relates to svd2rust? I'm new to rust, trying to get a simple example program going on a neorv32 (riscv32-imac) soft core (I wanna get UART serial output working). I've generated a pac from the svd that neorv32 supplies, but with the relevant features enabled it looks like I don't have a functional "critical section implementation" which I _thought_ was...
<re_irc>
... provided by the riscv crate. Specifically I'm getting "rust-lld: error: undefined symbol: _critical_section_1_0_acquire" during build.
<re_irc>
< (@ryan-summers:matrix.org)> I think that's actually telling you that you have an incorrect ciritical-section version. 1.0 just got released and there's some old stuff still using the 0.2 and older versions
<re_irc>
< (@ryan-summers:matrix.org)> Not 100% on that one though
<re_irc>
<thejpster> Maybe riscv crate puts the impl behind a feature flag
<re_irc>
<iliketurtles> It's behind "critical-section-single-hart" which afaict is enabled. It won't build without that feature ("::take()" doesn't exist without the critical section)
<re_irc>
< (@dirbaio:matrix.org)> iliketurtles: post the output of "cargo tree --format '{p} {f}'"
<re_irc>
< (@dirbaio:matrix.org)> it's probably somethign wrong with cargo features, with that we'll be able to see
<re_irc>
< (@duskmoon:matrix.org)> iliketurtles: The generated pac uses "critical-section" to prevent taking peripherals multiple times. Thus, an implementation is needed to use the pac. I hope this issue may help you.
<re_irc>
< (@dirbaio:matrix.org)> it has working code to call NS code from S code and returning back
<re_irc>
< (@dirbaio:matrix.org)> it says "TODO: interrupts" though, so it's not exactly the same as a bootloader that lets NS take over and everything
<re_irc>
< (@anand21:matrix.org)> Yeah I went through it. They are calling the NS app function. I want to jump to the NS firmware.
<re_irc>
< (@dirbaio:matrix.org)> I'm not sure if there's working pure-rust code for that anywhere, no..
<re_irc>
< (@anand21:matrix.org)> I guess there is difference in calling a NS function and Jumping to the NS firmware with vector table?
<re_irc>
< (@dirbaio:matrix.org)> there's more trustzone magic you need to do
<re_irc>
< (@dirbaio:matrix.org)> trustzone is like "2 chips in 1"
<re_irc>
< (@dirbaio:matrix.org)> each half (S and NS) has its own NVIC and VTOR
<re_irc>
< (@anand21:matrix.org)> Okay
<re_irc>
< (@dirbaio:matrix.org)> I dunno how it works, I think it's something like: you have to configure interrupts to go to the NS NVIC, then set the NS VTOR, then jump to NS code in NS mode (cortex_m bootload doesn't)
<re_irc>
< (@anand21:matrix.org)> Ok thanks for adding more clarity. Will go back to basics and revisit the code.
fooker has quit [Quit: WeeChat 3.5]
<re_irc>
< (@firefrommoonlight:matrix.org)> : Oh wow! I was more annoyed when surprised when writing a HAL internal-flash API for stm32 L5; most functionality and regs are duplicates with S/NS. What you described is weird
<re_irc>
< (@dirbaio:matrix.org)> yeah trustzone is very annoying
<re_irc>
< (@dirbaio:matrix.org)> luckily you can run everything in S mode and pretend trustzone doesn't exist
<re_irc>
< (@dirbaio:matrix.org)> because trustzone is not very useful with Rust anyway... (its main use is to protect against memory management vulns)
<re_irc>
< (@dirbaio:matrix.org)> ...except in the nrf91, because the C blob to use the modem can only run in NS mode (it's a limitation of the blob, not of the hardware 💩)
bjc has quit [Remote host closed the connection]
bjc has joined #rust-embedded
<wes_>
in a C application, i'd use a global buffer to store data coming in on UART, USB, etc. i'd wrap that buffer in a mutex during reading and writing. i know asset/mem management is completely different in Rust. what's the most natural way to handle data coming in from a hardware peripheral in an embedded Rust app?
<wes_>
i started looking for a mutex crate or similar, but realized that it is probably not necessary with Rust's built-in memory safety?
<wes_>
or do we lose the memory safety guarantees when we're dealing with hardware interrupts?
<re_irc>
< (@marmrt:matrix.org)> I'd start by looking at "heapless"
<wes_>
thanks. i'll start there
<re_irc>
< (@ryan-summers:matrix.org)> You lose memory safety guarantees when dealing with interrupts. There's a number of frameworks for dealing with this safety wes_ , such as RTIC
<re_irc>
< (@ryan-summers:matrix.org)> * safely
<re_irc>
< (@ryan-summers:matrix.org)> Essentially, a peripheral needs to "own" the memory buffer if it's modifying it. As such, your application and the peripheral should not both have mutable access to the same buffer in safe code, or you will violate Rust's safety guarantees
<re_irc>
< (@ryan-summers:matrix.org)> DMA presents a similar problem
<wes_>
right. the more i experiment with this, the more i'm seeing exactly what you're explaining. in C, i'd 'safely' pass pointers to and from different routines; but in my Rust app, i am struggling to find a way to do something similar.
<wes_>
i started looking into and implementing a 'heapless' pool as suggested above, but i'm already stuck. i have a pool that i can (presumably) access across multiple scopes (ie - hardware interrupt, main app), but the reference to the memory that i use is immediately dropped, and that memory space freed upon the exit of the interrupt routine!
<wes_>
i feel like i'm stuck thinking like an embedded C dev, and missing something critical to make the transition to Rust.
<re_irc>
< (@ryan-summers:matrix.org)> You have to have any memory that is shared between threads as a "static mut"
<re_irc>
< (@ryan-summers:matrix.org)> Which is obviously not great from a rust safety perspective. Hence the advent of frameworks to solve this, like RTIC and embassy
<re_irc>
< (@ryan-summers:matrix.org)> If you don't need concurrency, you can have everything live within a single "main", but cannot use ISRs in that sense
<re_irc>
< (@ryan-summers:matrix.org)> * case
<wes_>
okay... so by this logic, are most/all production embedded Rust apps running an RTOS or similar?
<re_irc>
< (@dirbaio:matrix.org)> you can share stuff safely between main and interrupt with no framework, using "critical_section::Mutex"
<re_irc>
< (@ryan-summers:matrix.org)> Don't get that discussion started ;) They're not really RTOS's, they're just supporting code to avoid manually writing all the mutex code
<re_irc>
< (@ryan-summers:matrix.org)> Essentially all RTIC does is handle the mutex wrapping of "static mut"s for you
<re_irc>
< (@ryan-summers:matrix.org)> Among other things
<wes_>
ohhhhh!
<re_irc>
< (@jamesmunns:beeper.com)> : I think that the RTIC folks are thinking about just calling RTIC and RTOS to avoid confusing people :D
<re_irc>
< (@jamesmunns:beeper.com)> * an
<re_irc>
< (@jamesmunns:beeper.com)> I guess we could see if we could convince to call embassy an "async rtos" just to be consistent :D
<wes_>
i didn't even consider RTIC, because i thought it would be like implementing FreeRTOS. i'll revisit RTIC then
<wes_>
i've never heard of 'embassy'. i'll check that out too
<wes_>
thanks for all the info
<re_irc>
< (@jamesmunns:beeper.com)> Yeah! RTIC and Embassy are both pretty full featured, and easy to get started with. They do let you tune things if you need to.
<re_irc>
< (@jamesmunns:beeper.com)> There is also https://www.tockos.org/, which is a more "traditional rtos", but the folks that work on that don't hang out here too much, and kinda do their own thing
<re_irc>
< (@jamesmunns:beeper.com)> AFAICT, it's mostly researchers and corporate folks (I've seen some google folks active there) that use tock-os.
<re_irc>
< (@jamesmunns:beeper.com)> Oh, there's Hubris too, though it is mainly targeted for server BMCs: https://hubris.oxide.computer/
<re_irc>
< (@jamesmunns:beeper.com)> (which may or may not match your intended use case(s))
<wes_>
my only use case is learning. trying to replicate things i've easily done in C for years.
<re_irc>
<rjmp> wes_: you can store the pool allocation reference in a local static var in the interrupt. FWIW, you also can access shared resources in interrupts with unsafe blocks ( i do it all the time), you just have to ensure it is safe because the compiler won't for you ( just like you did in C)
<re_irc>
<rjmp> Mostly this means either it is a thread safe data structure (like a heapless queue or atomics) or any other accesses are in lower priority contexts and wrapped in a critical section.
<wes_>
rjmp - good to know. feels very dirty to have 'unsafe' in my code. but i suppose i do it all the time in C.
<re_irc>
<rjmp> But actually it sounds like what you want is a heapless queue for incoming data streams. The IRQ accesses the Producer, and then you can get data from the Consumer in your main task. Accessing the Producer though will require moving it to a global. You can create something like 'static mut RX_Q_CONSUMER: Option<Consumer<u8, RX_Q_SIZE>> = None;' to store it in
<re_irc>
<rjmp> wes_: You can always wrap globals in a mutex. This leads to unneccessary critical sections and a few extra instructions, but and the unsafe
<re_irc>
<rjmp> * avoids
<wes_>
thanks very much for the help guys
<wes_>
and yes, queue is what i want. thanks for the hint about consumer/producer
<re_irc>
< (@ryan-summers:matrix.org)> I use SPSC and MPMC queues for interrupt safety a lot as well. Heapless has tons of useful datastructures to help with concurrency for sure :)
<re_irc>
< (@mehmet:grusbv.com)> I am experiencing this issue https://github.com/knurling-rs/defmt/issues/673, with defmt, where compilation of library tests fail that implement "defmt::Format" for the crate that requires it.
<re_irc>
< (@mehmet:grusbv.com)> I see that thejpster also stumbled on it.
<re_irc>
< (@mehmet:grusbv.com)> Any good ideas of a workaround?
<re_irc>
< (@jamesmunns:beeper.com)> that might break other things though maybe
<re_irc>
< (@mehmet:grusbv.com)> Ah, that might work.
<re_irc>
< (@mehmet:grusbv.com)> Didn'tknow that I could cherry pick attrs like that
<re_irc>
< (@mehmet:grusbv.com)> * Didn't know
<re_irc>
< (@jamesmunns:beeper.com)> It might be good for the upstream "Format" derive to do something like that internally as a workaround, not sure though.
<re_irc>
< (@jamesmunns:beeper.com)> lemme know if that works, if so I'll throw it up as a workaround on the issue tracker
<re_irc>
< (@mehmet:grusbv.com)> : I think I still have some dependency to defmt, I still get the link error.
<re_irc>
< (@mehmet:grusbv.com)> Need to take a better look, I might have some loose ends.
<re_irc>
< (@jamesmunns:beeper.com)> Yeah, it might be better to have a crate-wide "use-defmt" feature instead, that does a more complete job of not including defmt at all
<re_irc>
< (@mehmet:grusbv.com)> A way to check whether target_os = "none" is respected when cargo test is ran?
<re_irc>
< (@jamesmunns:beeper.com)> then you could toggle the derives with
<re_irc>
< (@mehmet:grusbv.com)> : yep, and then conditionally use defmt
<re_irc>
< (@mehmet:grusbv.com)> yep, explicit is good
<re_irc>
< (@jamesmunns:beeper.com)> : it should be, just "use defmt;" might be enough to bring in the symbols for defmt tho
<re_irc>
< (@mehmet:grusbv.com)> : hm..
<re_irc>
< (@jamesmunns:beeper.com)> so like, your derived Format isn't triggering the issue anymore, but something else in defmt might be. I don't have a windows pc handy to check tho
<re_irc>
<wes_ (@wes_:matrix.org)> rjmp : one more for you guys. i have a producer/consumer spsc queue working. looks like in my case, the producer enqueues a single u8 at a time. do either of you know the rusty way to enqueue a buffer of u8's instead of a single u8 at a time? would i need to create a my_struct and enqueue a single my_stuct at a time?
<re_irc>
<wes_ (@wes_:matrix.org)> * working (thanks).
<re_irc>
< (@thalesfragoso:matrix.org)> wes_: You could, could also probably use a fixed size array. However, it seems what you really want is the bbqueue crate
<re_irc>
<wes_ (@wes_:matrix.org)> : i'll check it out. thanks a lot
<re_irc>
< (@thalesfragoso:matrix.org)> It's basically a thread safe ring buffer
<re_irc>
<wes_ (@wes_:matrix.org)> does that mean it implements mutex/safety stuff under the hood?
<re_irc>
< (@ryan-summers:matrix.org)> Through ownership, yes. Bbqueue is a bip-buffer, isn't it? I.e. you can get a continuous grant of memory from the ring
<re_irc>
< (@thalesfragoso:matrix.org)> wes_: Yep, and it's even lock free if your core supports CAS
<re_irc>
< (@ryan-summers:matrix.org)> bip-buffer differs slightly in terms of semantics from the ring buffer, since it guarantees continuity of memory if it succeeds in getting the grant, where a ring buffer may have a wrapping point
<re_irc>
< (@ryan-summers:matrix.org)> tl;dr it's great if you want to quickly and easily copy into it and/or DMA. Otherwise, ring buffer is fine
<re_irc>
< (@mehmet:grusbv.com)> : I suspected that it was "Format" only, since I only "use defmt::Format" in this crate
<re_irc>
< (@mehmet:grusbv.com)> Therefore I think you can add that as a workaround
<re_irc>
< (@mehmet:grusbv.com)> +(can tag me as mehmetalianil)
<re_irc>
< (@jamesmunns:beeper.com)> Yeah, any use of the crate will cause it to get linked in
<re_irc>
< (@mehmet:grusbv.com)> : Thanks!
genpaku has quit [Remote host closed the connection]
genpaku has joined #rust-embedded
<re_irc>
< (@badrb:matrix.org)> I'm writing a embedded hal driver for a motor driver. It has an "nFault" pin, how would you model that? "embedded-hal" doesn't seem to support interrupts
<re_irc>
< (@dirbaio:matrix.org)> embedded-hal-async's gpio "wait_for_high", "wait_for_low" does abstract over gpio interrupts
<re_irc>
< (@dirbaio:matrix.org)> it does need async
<re_irc>
< (@dirbaio:matrix.org)> there's no trait for non-async gpio interrupts