<takkaryx[m]>
design question. What is the recommended way to start introducing rust modules into a C embedded env? We're wanting to start modularizing out C code for an STM32F4 with some rust code, I'm getting started on it, but I'm not... (full message at
<i509vcb[m]>
I find that trying to manage ownership of something like a peripheral between C and Rust can be a challenge
<i509vcb[m]>
Usually I see people either doing business logic in Rust or trying it out with a select peripheral or two
<i509vcb[m]>
* a challenge (not just in embedded, userspace in Linux can be especially hairy)
<i509vcb[m]>
I guess another question is are you using an RTOS from C or some form of "superloop"?
<takkaryx[m]>
FreeRTOS is already present in the C, so I guess it will still be there. my argument for Embassy was shot down.
<i509vcb[m]>
Right so you'd probably be doing business logic or tasks in Rust then
<takkaryx[m]>
So, it will be FreeRTOS initializing things, and then could have a FreeRTOS 'task' that is basically all rust, that might work. But I'm unclear on how I would then share a 'peripherals' module from the stm_hal to pass around? does that set up any registers?
<i509vcb[m]>
If freertos gives you full ownership of the peripheral you can probably just from_raw it into stm_hal
<i509vcb[m]>
I unfortunately am not very familiar with freertos
<takkaryx[m]>
I think you can set it up to give full ownership, I usually handle that all in the tasks, but doing across a c<->Rust boundry is confusing me.
<i509vcb[m]>
I'm not sure what issue you are having with the C <-> rust boundary. Declaring a task from Rust? Communication between the two ends?
<takkaryx[m]>
it's more conceptually about generating the data structs needed to pass to the Rust side from C. I'm looking into the `from_raw` calls now. but for example, a `SpiDevice` trait, is it possible to have a struct in C that will satisfy that trait requirement to make the rust side happy when I compile it together? or is it sharing libraries and linking, and handle it there, it feels like a lot of the safety and verbosity I enjoy
<takkaryx[m]>
about using rust is lost because I have to do this work to share peripherals across the language line.
<takkaryx[m]>
also, unfamiliarirty with how the HAL's operate, if I have 2 different rust modules that use peripherals, will they both attempt to overwrite each other? since the compiler can't tell they are shared, right?
<takkaryx[m]>
maybe I'm just venting that I'd rather just do it in rust than figure this out, but I'm not being allowed to XD
<i509vcb[m]>
Two modules both using the same peripheral would probably be undefined behavior
<takkaryx[m]>
not the same peripheral as in the same spibus or gpio, but the overall 'peripherals' struct that the hals return when you init them
<i509vcb[m]>
takkaryx[m]: That I'm not actually sure about
<i509vcb[m]>
For the cross language talk you could probably just do impl Trait for c_whatever and speak across with C types. Although do beware of the orphan rule
<takkaryx[m]>
same, hence my apprehension, and wanting to know about using the c side to init everything, and then just passing pointers to the peripherals to the rust. But I'm also unclear on how to do that.
<i509vcb[m]>
* for c_whatever Rust side and speak
<takkaryx[m]>
yea, I've read about the Orphan rule, but haven't come across it myself, I'll try to keep an eye out for it.
<i509vcb[m]>
takkaryx[m]: If you do a freertos-api-sys crate and the do the actual Rust code in another crate you might be an orphan rule issue
<i509vcb[m]>
* If you do a freertos-api-sys crate and the do the actual Rust code in another crate you might encounter an orphan rule issue
<takkaryx[m]>
I see that now, thanks!
<i509vcb[m]>
I personally don't encounter it in the nrf70 driver for Embassy I am working on since I keep the C types which are bindgened in the same crate
<takkaryx[m]>
yea, I'm a bit unclear still on how this is going to play out for me, I'm betting I'll run into it at some point in this whole process, here's hoping I remember this when I do
sroemer has joined #rust-embedded
sroemer has quit [Ping timeout: 248 seconds]
igiona[m] has joined #rust-embedded
<igiona[m]>
<takkaryx[m]> "I think you can set it up to..." <- Usually FreeRTOS needs only a timer as peripheral.
<igiona[m]>
You could use/own all other peripherals in Rust. Couldn't you?
<igiona[m]>
* Usually FreeRTOS needs to own only a timer as peripheral, often one would use the systick.
<igiona[m]>
You could use/own all other peripherals in Rust. Couldn't you?
caclamity_struck has joined #rust-embedded
caclamity_struck has quit [Ping timeout: 265 seconds]
kenny has quit [Ping timeout: 276 seconds]
kenny has joined #rust-embedded
emerent has quit [Ping timeout: 260 seconds]
emerent has joined #rust-embedded
sroemer has joined #rust-embedded
sroemer has quit [Changing host]
sroemer has joined #rust-embedded
<nickez[m]>
<diondokter[m]> "> <@nickez:matrix.org> I fixed..." <- > <@diondokter:matrix.org> Not sure what the implications are...
<nickez[m]>
> One thing that would at least make it a bit safer is by requiring `T: Send`, but maybe even then everything is bad enough that that doesn't really help anywhere
<nickez[m]>
I realized that I read the compiler error message slightly wrong. It was a different `PhantomData` than I first thought. Another solution to my problem was to simply add `unsafe impl Sync for Da14531Peripherals {}`. If I do that I don't have to patch `Grounded`.
sroemer has quit [Ping timeout: 246 seconds]
thejpster[m] has quit [Quit: Idle timeout reached: 172800s]
crabbedhaloablut has quit []
Ralph[m] has quit [Quit: Idle timeout reached: 172800s]
crabbedhaloablut has joined #rust-embedded
crabbedhaloablut has quit []
crabbedhaloablut has joined #rust-embedded
sroemer has joined #rust-embedded
sroemer has quit [Changing host]
sroemer has joined #rust-embedded
sirhcel[m] has quit [Quit: Idle timeout reached: 172800s]
sroemer has quit [Ping timeout: 244 seconds]
Makarov has joined #rust-embedded
danielb[m] has quit [Quit: Idle timeout reached: 172800s]
Makarov has quit [Quit: Ping timeout (120 seconds)]
Makarov has joined #rust-embedded
jsolano has quit [Quit: leaving]
jsolano has joined #rust-embedded
Makarov has quit [Quit: Ping timeout (120 seconds)]
Makarov has joined #rust-embedded
Makarov has quit [Client Quit]
almindor[m] has quit [Quit: Bridge terminating on SIGTERM]
JamesMunns[m] has quit [Quit: Bridge terminating on SIGTERM]
rafael[m] has quit [Quit: Bridge terminating on SIGTERM]
dirbaio[m] has quit [Quit: Bridge terminating on SIGTERM]
VaradShinde[m] has quit [Quit: Bridge terminating on SIGTERM]
_catircservices has quit [Quit: Bridge terminating on SIGTERM]
i509vcb[m] has quit [Quit: Bridge terminating on SIGTERM]
diondokter[m] has quit [Quit: Bridge terminating on SIGTERM]
igiona[m] has quit [Quit: Bridge terminating on SIGTERM]
kentborg[m] has quit [Quit: Bridge terminating on SIGTERM]
AdinAck[m] has quit [Quit: Bridge terminating on SIGTERM]
takkaryx[m] has quit [Quit: Bridge terminating on SIGTERM]
okhsunrog[m] has quit [Quit: Bridge terminating on SIGTERM]
nickez[m] has quit [Quit: Bridge terminating on SIGTERM]
ivmarkov[m] has quit [Quit: Bridge terminating on SIGTERM]
AlexandrosLiarok has quit [Quit: Bridge terminating on SIGTERM]
berkus[m] has quit [Quit: Bridge terminating on SIGTERM]
Beregond[m] has quit [Quit: Bridge terminating on SIGTERM]
whitequark[cis] has quit [Quit: Bridge terminating on SIGTERM]
adamgreig[m] has quit [Quit: Bridge terminating on SIGTERM]
<JamesMunns[m]>
therealprof[m]: This is why postcard-rpc is still pre-1.0 :)
<JamesMunns[m]>
(postcard is not changing at all for this, btw! Changes are specific to postcard-rpc)
<adamgreig[m]>
ok, let's begin! other announcements from me: critical-section 1.2 was released, removing the Sync+Send auto traits from the CriticalSection to stop it being sent to other threads which was unsound (https://github.com/rust-embedded/critical-section/issues/55)
<JamesMunns[m]>
Yep! I added some comments, I think it impacts embedded less than we originally discussed, but @aliceryhl is pushing the rfc forward and is looking for any feedback
<JamesMunns[m]>
(in general it seems that hard/soft float is the only common thing that causes abi breakage, if you disagree please sound off :) )
<JamesMunns[m]>
* abi breakage for most embedded targets, if
<therealprof[m]>
Interesting.
<adamgreig[m]>
I think that's the only thing that commonly breaks abi, and I think (?) the point of the new target-modifiers is to better detect and prevent such breakage?
<therealprof[m]>
The target architecture itself is already covered then?
<adamgreig[m]>
if this can also more or less replace or supplement compiler flags for things like "use double precision floats" or "enable vector extensions" or whatever that's nice, but I'm not sure that's the intent (when such flags don't break ABI, that is)
jannic[m] has joined #rust-embedded
<jannic[m]>
adamgreig[m]: Yes, that's also how I understand it. The current RFC doesn't allow anything new, it only detects and rejects incompatible combinations.
<adamgreig[m]>
so, I think with target-modifiers the feeling atm is it would nicely solve our "floating point compiler flags can cause broken builds if mixed", but probably doesn't apply much beyond that at the moment?
<JamesMunns[m]>
adamgreig[m]: Yeah, and tbh the linker catches that pretty often already in my experience
<adamgreig[m]>
I think it might still be more widely applicable if it is also a sort of "global-target-feature" thing whereby adding the target modifier for "use vector extension" makes sure that's used everywhere in the build for instance
<adamgreig[m]>
but that's sort of already the case once you have -Zbuild-std etc going?
<adamgreig[m]>
I guess it's rarer for us to be linking together multiple separately-built items
<JamesMunns[m]>
adamgreig[m]: Yeah, I think so
<therealprof[m]>
adamgreig[m]: That's mostly interesting in case there's special initialisation required or registers are overlapping.
<JamesMunns[m]>
therealprof[m]: I think the eabi (for cortex m) defines who is required to stack regs in general, and isn't specific to any feature other than hard/soft floats ("do you have FP regs at all")
<JamesMunns[m]>
But JP certainly knows it better than I do and he didn't seem fussed about it
<therealprof[m]>
Indeed, but sometimes that's not well defined so it's important to use the same compiler flags for all compilation units.
<JamesMunns[m]>
therealprof[m]: If you can name any situations/specifics it would probably be welcome on the rfc motivations section!
<therealprof[m]>
And if you need initialisation, it would also be bad if the start code was compiled with the wrong configuration.
<therealprof[m]>
JamesMunns[m]: Hm, would need to do some research, I think MIPS and RISC-V are most likely to be affected.
dirbaio[m] has joined #rust-embedded
<dirbaio[m]>
therealprof[m]: this "target modifiers" proposal is the attempt to fix exactly that, to make it well defined.
<dirbaio[m]>
- "target modifiers" are flags that must be equal in all compilation units
<dirbaio[m]>
- "target features" are flags that are explicitly OK to set differently in different compilation units
rmsyn[m] has joined #rust-embedded
<rmsyn[m]>
therealprof[m]: I think all of the RISC-V target features are additive, and don't change ABI of existing targets in a subtractive way, so they shouldn't break things the same way
romancardenas[m] has joined #rust-embedded
<romancardenas[m]>
rmsyn[m]: E extension might be different
<dirbaio[m]>
and as a bonus, once it's well specified, the compiler can check target modifiers match or refuse to link. unlike what we have now which is it links anyway (because i'ts the same target) and eexplodes at runtime
<adamgreig[m]>
let's move on to the next item, aliceryhl if there's anything else you want to talk about for target-modifiers please shout :)
<JamesMunns[m]>
Nothing much to add, just saw it was coming down the pipeline on zulip :)
<adamgreig[m]>
I like your three suggestions, is it just a "bring them up on zulip" situation atm?
<rmsyn[m]>
<romancardenas[m]> "E extension might be different" <- since this is a reduced `I` extension, wouldn't it become a new target like `riscv32e...`, `riscv64e...`?
<JamesMunns[m]>
adamgreig[m]: I think the process is documented in the public docs, lemme find it
<rmsyn[m]>
rmsyn[m]: guess not, looks like it is a target feature...
<romancardenas[m]>
rmsyn[m]: There is an E extension coming, in fact. However we should study the RISC-V ecosystem and try to reduce the number of available targets. Otherwise, it will become sort of unbearable
<dirbaio[m]>
uh aren't project goals "I commit time to work on X, will need asistance from T-whatever for review/rfc/etc"?
<dirbaio[m]>
they're not "hey T-whatever, please do X for me"
<adamgreig[m]>
the goals need an owner to be accepted, but not to be proposed, I think?
<adamgreig[m]>
there's also provisional goals which are accepted without an owner yet
<JamesMunns[m]>
Yeah, that's about what I understand.
<JamesMunns[m]>
But being accepted also means there will likely be funding available to people working on that goal, if accepted
<dirbaio[m]>
so i'm not sure what "proposing" would do for us. I mean, I'm all for improving async fn future sizes but I can't commit time to doing that myself...
<jannic[m]>
(Currently, there are no ongoing grants related to rust embedded, as far as I am aware.)
<JamesMunns[m]>
jannic[m]: There have been in the past, but not for project goals
<jannic[m]>
I know, I was one of the grantees :)
<JamesMunns[m]>
Also working on these goals could be an opportunity to get embedded folks on various project teams, if there is availability to contribute to them
<adamgreig[m]>
so, do we need someone who's interested in working on one of these things before it's worth proposing it as a goal?
<adamgreig[m]>
even if that interest is maybe conditional on it being accepted, funding being available, stuff like that
<JamesMunns[m]>
I think it would help
<JamesMunns[m]>
I don't know for certain if it's required
<JamesMunns[m]>
I agree with dirbaio that just adding wishlist items probably won't get us anywhere.
<jannic[m]>
It probably doesn't make sense to define a goal if none of us plans to work on it. It's not like someone else will magically show up and do it for us.
<jannic[m]>
But if there are topics where we think that there is enough momentum that we (as a group) will make progress even if there's no single person responsible, it may make sense to propose it.
<adamgreig[m]>
given the goals are all around things in rustc and we don't have much rustc momentum at the moment, I don't think there's any we could expect to get worked on without someone personally being interested in digging in
<adamgreig[m]>
I like the idea of "variant of write() which returns the value written", but I'm not sure that _and is the best name for it, since it sounds like other stdlib _and methods that take a closure etc
<adamgreig[m]>
(cc AdinAck )
AdinAck[m] has joined #rust-embedded
<AdinAck[m]>
haha agreed, came up with it last minute this morning
<AdinAck[m]>
i'm open to any and all suggestions of a better name
<adamgreig[m]>
I agree changing write to return the value is probably quite an annoying breaking change, so a new method seems like it makes sense, just yea.. what to call it
<dirbaio[m]>
i'd just change the normal modify/write functions
<AdinAck[m]>
i did that, and it took a very long time to update stm32g4xx-hal in my case, probably other HAL maintainers will not want to deal with that
<AdinAck[m]>
well usually that would be a chain with no braces and no semicolon
<jannic[m]>
What kind of breakage did it cause? Were there fixable easily or were some cases tricky?
<AdinAck[m]>
it is trivial to fix, but time consuming
<AdinAck[m]>
it's just adding braces and semicolons
<adamgreig[m]>
is it because previously people would have returned w from the closure and with the change write would return that w up, but fail because of lifetimes?
<adamgreig[m]>
so you have to add ; to each call to prevent the w being returned from the closure?
<AdinAck[m]>
exactly
<burrbull[m]>
dirbaio[m]: these new functions add advanced generic parameter, not only return value
<jannic[m]>
Personally I wouldn't mind doing that for the rp2040/rp235x-hal, and I agree with dirbaio that it would be nicer to change the existing functions than to add new ones with ugly names.
<dirbaio[m]>
adamgreig[m]: chains are super awkward as well, rustfmt flattens them to a huge vertical list of method calls and in the middle of it you have no visual cue of what's a key and what's a value.
<dirbaio[m]>
AdinAck[m]: chains are super awkward as well, rustfmt flattens them to a huge vertical list of method calls and in the middle of it you have no visual cue of what's a key and what's a value.
<AdinAck[m]>
yeah i personally don't do it that way, but it is done that way in a lot of places
<AdinAck[m]>
hey i guess if everyone is ok with patching all the HALs we could just change write and modify
<adamgreig[m]>
probably among the easier of the changes needed to update to a newer pac anyway :p
<AdinAck[m]>
we could make a feature gate or something... to avoid this
<adamgreig[m]>
if that's at the svd2rust config level, we just have more variations in emitted api that's harder to document, and if it's preserved into the pac, it would be a nightmare if end users try to toggle it and their hal doesn't exist it
<AdinAck[m]>
so the update would be in one place rather than 9000
<adamgreig[m]>
yea, but if an application crate depends on the PAC and enables new-style-reg, and the HAL is build with old-style-reg...
<adamgreig[m]>
s/build/written/, s/with/using/
<AdinAck[m]>
at that point it's time to migrate, but at least HALs as they are now won't break when rebuilding the PAC... although i think that's already broken because registers have () now
<AdinAck[m]>
it seems the consensus is we'd rather change the existing methods, i'll update the PR
<adamgreig[m]>
if there was a catchy name for a new method then maybe...
<adamgreig[m]>
it doesn't make write or modify worse to return the result of the closure I think (I hope?), it's just the pain of changing to it
<AdinAck[m]>
i have used it in an application and the binary did not change, so i don't think there is any drawback, but yes it is quite a pain
<adamgreig[m]>
I don't know if I quite followed the example in the PR though
<adamgreig[m]>
is State::set(w.field1()) some custom method that returns something of interest?
<AdinAck[m]>
that's because it's wound into a bunch of HAL work i'm doing
<adamgreig[m]>
<adamgreig[m]> "I like the idea of "variant of..." <- I said this, but I don't think it's accurate to say "returns the value written" actually
<AdinAck[m]>
yes my idea is that type-states can only be created by setting the field value they represent
<jannic[m]>
adamgreig[m]: `scribble` and `alter` π
<rmsyn[m]>
instead of changing the current method names, we could also use the `.and_then(<closure>)` syntax
<AdinAck[m]>
adamgreig[m]: true, it *could* be used for that, that is not my use case though
<AdinAck[m]>
rmsyn[m]: can you show an example of this?
<burrbull[m]>
I still prefer new methods and watch how people will use them.
<rmsyn[m]>
it's fairly common other places in core and std
<adamgreig[m]>
yea, I'm not sure I really understand how widespread the use-case is after all
<burrbull[m]>
so what the names?
<AdinAck[m]>
i was only using it internally, but burrbull expressed a desire to maybe make field writers return the value they write, which would require an additional change
<adamgreig[m]>
write_returning and modify_returning are a bit of a mouthful
<AdinAck[m]>
while the scope of my use-case is rather small right now as i slowly update HALs, i believe it is the correct direction for making the HALs safe, and it would require this change
<AdinAck[m]>
adamgreig[m]: yeah, i'll ask around and keep thinking about it
<adamgreig[m]>
ok, that's all we have time for this week then, thanks everyone!
<thejpster[m]>
Havenβt tried it but looks like they want to add Rust support to the Raspberry Pi Pico VS Code extension, including shelling out to defmt-print. That seems pretty cool.
M9names[m] has joined #rust-embedded
<M9names[m]>
<rmsyn[m]> "since this is a reduced `I..." <- That would make sense to me (I and E are not extensions), but it probably makes sense for us to follow what other compilers do here