Guest7282 has left #rust-embedded [Error from remote client]
Ralph[m] has joined #rust-embedded
<Ralph[m]>
<Ralph[m]> "> <@rursprung:matrix.org> a..." <- i probably won't be able to attend tomorrow at the meeting, but may i nominate this issue for discussion tomorrow? i really think that this should have a general answer so that all drivers follow the same pattern. as there are now already some drivers ported to 1.0 the experience is now hopefully here (both for maintaining the drivers and using them). however there are still a lot of
<Ralph[m]>
drivers to port, so answering it now would help to standardise the pattern for the drivers.
<Ralph[m]>
also i'd like to finally get ripytide's PR merged, but we'd need this guidance first.
korken89[m] has joined #rust-embedded
<korken89[m]>
A not super embedded related, but maybe adjacent. I'm testing to handle incoming connections for 100s of IoT devices with tokio and would like to abstract the TcpStream to allow for unit testing. But the traits that tokio implement are tokio-only. How do you guys abstact over sockets to allow for unit testing? Feels like I will be reinventing the wheel here :)
IlPalazzo-ojiisa has joined #rust-embedded
<JamesMunns[m]>
Do you need more control than a real tcp stream gives you? You can totally just use one tcp stream to localhost in each unit test
<JamesMunns[m]>
Like, are you trying to mock weird tcp failure states? Or just avoid opening Real Sockets in unit tests?
<diondokter[m]>
<korken89[m]> "A not super embedded related..." <- You could also just use tokio in your unit tests. There's nothing in std yet that does async streams...
<diondokter[m]>
Maybe tokio has compat with the futures crate?
<dirbaio[m]>
write the tests with tokio::io::::{AsyncRead, AsyncWrite} yeah. if your code is tokio-only it's probably fine for the tests to be tokio-only too?
Guest7282 has joined #rust-embedded
crabbedhaloablut has quit []
crabbedhaloablut has joined #rust-embedded
<korken89[m]>
Sorry I got stuck in meetings, the thing I want to do is make sure I can mock the IoT devices easily and the {AsyncRead, AsyncWrite} traits were a bit cumbersome to work with. So nothing fancy really :)
<dirbaio[m]>
you can create pipes that also impl Asyncread/AsyncWrite and have the test control the other 'side' of it
<dirbaio[m]>
so instead of supplying a custom impl of the traits, your "fake device" code does plain old reads/writes just like the real firmware would do
<dirbaio[m]>
not sure if that's the issues you were having with the asyncread/asyncwrite traits?
<JamesMunns[m]>
Probably less strange than what I chose in Mnemos for roughly this: "BidiChannel` (for BiDirectionalChannel)
<JamesMunns[m]>
s/"/`/
<dirbaio[m]>
it's also weird that you must have a duplex pipe (both ends read and write) even if you don't need it, there's no simplex pipe (one end writes, the other end reads). embassy-sync's is simplex
Lumpio- has quit [*.net *.split]
bpye has quit [*.net *.split]
Ekho has quit [*.net *.split]
bpye has joined #rust-embedded
Ekho has joined #rust-embedded
KennethKnudsen[m has joined #rust-embedded
<KennethKnudsen[m>
Hello everyone i'm very new to this channel. I have an issue with an rtic task with priority 1 that blocks my other task with priority 2 where im awaiting an gpio interrupt. I have created a very simple example to show you my problem: https://gist.github.com/KennethKnudsen97/807869126e234f051d016a536e1bd7b6
<KennethKnudsen[m>
It works normally when i remove the gpio await and just use an embassy_time::Timer::after.
<KennethKnudsen[m>
From what I could see when embassy initialize gpio's it defaults to P3 which should be good enough to interrupt the task.
<JamesMunns[m]>
> The new async software tasks are allowed to run forever, on one precondition: there must be an await within the infinite loop of the task.
<JamesMunns[m]>
I dunno WHY that precondition exists, but I wonder if they basically take a critical section until you yield?
<JamesMunns[m]>
you code doesn't have an await
<diondokter[m]>
Wait, but that doesn't make sense for rtic...
<JamesMunns[m]>
yeah, I haven't used rtic2 at all honestly
<JamesMunns[m]>
I wonder if you have to use a hardware task or something?
<JamesMunns[m]>
Does seem sorta footgunny\
<JamesMunns[m]>
* Does seem sorta footgunny
<diondokter[m]>
Do all async tasks run on one executor?
<diondokter[m]>
I'd have thought it would do one executor per priority
<JamesMunns[m]>
it might but idk how they do interleaving or context switching? like embassy multiprio would (should?) definitely handle this right, but idk enough about rtic to jnow whats up
<JamesMunns[m]>
s/jnow/know/
<diondokter[m]>
Hardware tasks are still the same, but all software tasks are now async
<diondokter[m]>
Dunno
<JamesMunns[m]>
Kenneth Knudsen I would definitely say ask in the RTIC room. It seems like you are doing something the docs say *not* to do, but it might be worth asking them *why* the docs say not to do that, and how to get around that
<JamesMunns[m]>
If the answer is "pre-emption can only happen when a task is yielded", that certainly would seem to be suboptimal!
Lumpio- has joined #rust-embedded
<dirbaio[m]>
<JamesMunns[m]> "I dunno WHY that precondition..." <- it's just the good old "if you block forever then tasks at lower or equal prio get starved' restriction
<dirbaio[m]>
tasks at higher prio should still preempt
<dirbaio[m]>
AFAICT
<JamesMunns[m]>
but the lower prio task is starving the higher prio task
<JamesMunns[m]>
that's the weird thing
<dirbaio[m]>
* AFAIK
<JamesMunns[m]>
and they aren't even sharing anything (overtly) so it's not prio inversion or something tricky
<dirbaio[m]>
yeah it's weird
<JamesMunns[m]>
like they are implicitly sharing embassy-time and defmt, but if you grab + release mutexes the pre-emption should fire asap
<dirbaio[m]>
it might be starving the GPIO interrupt instead though
<JamesMunns[m]>
how is this handled for other drivers, like a UART or other hw?
<dirbaio[m]>
the user has to do the set_priority thing
<dirbaio[m]>
* the user has to do the set_priority thing too
<JamesMunns[m]>
(just default prio level?)
<dirbaio[m]>
yeah default prio is 0
<dirbaio[m]>
these go through bind_interrupts!
<JamesMunns[m]>
yeah
<dirbaio[m]>
the exception is gpio and dma irqs which the HAL registers for you without going through bind_interrupts!
<JamesMunns[m]>
I didn't know if b_i! had a hidden prio param, or if you have to use the set_priority interface
<dirbaio[m]>
it doesn't
<dirbaio[m]>
maybe it should
<dirbaio[m]>
or maybe it shouldn't, and the main config shouldn't have gpio/dma irq prio config
<dirbaio[m]>
* prio config either
<dirbaio[m]>
because it's inconsistent that you have to set some irq prios with set_priority yourself and others are through config fields
<JamesMunns[m]>
+1 to consistency and documentation either way
<JamesMunns[m]>
tbh, when I'm not in rtic I don't think about isr prio that much unless I'm really doing something near system limits
<dirbaio[m]>
the config fields are a relic from the old "owned interrupts" stuff, where you couldn't do set_priority without owning the irq, and the gpio/dma irqs were owned by the HAL (actually you could but it was discouraged)
<JamesMunns[m]>
I wonder if set_priority should be unsafe
<JamesMunns[m]>
but probably not if critical sections are used consistently, and not something More Clever like what RTIC does.
<dirbaio[m]>
it is
<JamesMunns[m]>
"it is" unsafe? or "it is" (uses CS everywhere)