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
<salsasteve[m]> <adamgreig[m]> "that's correct. you could..." <- thank you, setting up the serial port sounds like a great idea
IlPalazzo-ojiisa has quit [Quit: Leaving.]
user1__ has quit [Ping timeout: 255 seconds]
GenTooMan has quit [Read error: Connection reset by peer]
bpye has quit [Quit: Ping timeout (120 seconds)]
bpye has joined #rust-embedded
notgull has quit [Ping timeout: 260 seconds]
notgull has joined #rust-embedded
cybernaut has joined #rust-embedded
cybernaut has quit [Read error: Connection reset by peer]
GenTooMan has joined #rust-embedded
notgull has quit [Ping timeout: 260 seconds]
sashin has quit [Quit: sashin]
notgull has joined #rust-embedded
notgull has quit [Ping timeout: 260 seconds]
notgull has joined #rust-embedded
<ragarnoy[m]> <adamgreig[m]> "> <@ragarnoy:matrix.org> Hey, i..." <- yes
IlPalazzo-ojiisa has joined #rust-embedded
ryan-summers[m] has quit [Quit: Idle timeout reached: 172800s]
<thejpster[m]> I don't think you can write such functions in Rust
<thejpster[m]> Which is why tinyrlibc has its sprintf function written in C. You can write a function in Rust which takes a va_args value though.
<thejpster[m]> Oh, wait, that's not stable: https://doc.rust-lang.org/std/ffi/struct.VaList.html
<thejpster[m]> wrapping string log functions with defmt doesn't make a lot of sense anyway - defmt relies on macros to intern the strings so they don't end up in flash or RAM. If your C code has strings in flash/ram, you'll probably just want to render the string to a byte buffer and then defmt that.
<adamgreig[m]> https://doc.rust-lang.org/beta/unstable-book/language-features/c-variadic.html is the relevant feature, but yea, going through defmt is probably a lost cause. Could still rtt them though
<thejpster[m]> I was sure there was a workaround where the C program was (char * fmt, ...) and you made a va_list object and passed that to Rust.
<ragarnoy[m]> the logs are private, as in they're in the proprietary part of the library i'm using, the hal is the only way to get these logs to print basically
<ragarnoy[m]> <adamgreig[m]> "https://doc.rust-lang.org/beta/..."; <- if possible i'd like to not have to use that feature since all I want to do is pipe the string from the library , check the log level and print through defmt
<ragarnoy[m]> (if that makes any sense)
<Socke> hey guys! my esp32c3 does not show up as a usb device when pin GPIO18 is high (~2V). am I doing something wrong?
<Socke> I connected a voltage divider (with a photo resistor but thats not important) between 3.3V and GND to this pin and whenever the voltage gets too high, the usb device disappears
<Socke> shall I use a different pin?
<Socke> oh I see from the docs that this pin is used for jtag :/
<Socke> wasn't mentioned in the pinout picture that I saw -.- damnit
Noah[m]1 has joined #rust-embedded
<Noah[m]1> Socke doing their mischief again :P
<Socke> :(
<thejpster[m]> ragarnoy: yeah that should be fine. Although note if you pass 256 to snprintf, it might fill all the bytes and leave it non-null terminated. Also you need to expressly null-initialise buffer `= {0}`;
<thejpster[m]> so I would zero-init and then pass sizeof(buffer) - 1 to snprintf as the length.
<adamgreig[m]> snprintf already subtracts one and adds a null terminator, doesn't it?
Guest7282 has joined #rust-embedded
<thejpster[m]> > The functions snprintf() and vsnprintf() write at most size bytes (including the terminating null byte ('\0')) to str.
<thejpster[m]> Hmm, maybe it does and I'm used to an older version.
<thejpster[m]> I definitely had a C library on a platform that would not add the NUL if it ran out of space. Fun times.
<thejpster[m]> > sprintf is like printf, except that output is directed to the buffer str, and a terminating NUL is output. Behavior is undefined if more output is generated than the buffer can hold.
<Socke> hmm now my cargo run hangs -.-
<Socke> it uses espflash flash --monitor as the runner command
<FreeKill[m]> <thejpster[m]> "I definitely had a C library..." <- That is how the behaviour is defined i believe ๐Ÿ™ƒ๐Ÿ™ƒ
<FreeKill[m]> Eh maybe not... Though I have also used an implementation which did, which is grand
Guest7282 has left #rust-embedded [Error from remote client]
<vollbrecht[m]> Socke: yes you do something wrong, gpio 18/19 is the usb + / - in. So the complete usb-acm/jtag thing runs over that two pins. So you can use this two pins for flashing/debugging/serial monitoring.
<vollbrecht[m]> are you currently using that connection also for flashing/monitoring or are you using gpio20/21 over an uart/usb converter?
<vollbrecht[m]> if you use the traditional setup via an external uart/usb converter, there is an option to use pin 18/19 as regular gpio pins. But by default they are usb/jtag
<Socke> yeah I switched to GPIO6 that works fine
Guest7282 has joined #rust-embedded
marmrt[m] has quit [Quit: Idle timeout reached: 172800s]
notgull has quit [Ping timeout: 260 seconds]
jessebraham[m] has quit [Quit: Idle timeout reached: 172800s]
notgull has joined #rust-embedded
<ragarnoy[m]> Hey, I have a C function such as
<ragarnoy[m]> ```c
korken89[m] has joined #rust-embedded
<korken89[m]> Does anyone know if it's possible to get the size of an anonymous type? I'd like to know the size of the future returned by an async function without first constructing the future.
<ragarnoy[m]> * Hey, I have a C function such as... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/fnKnNtpgJYVCDkMPfDrxcZGG>)
<ragarnoy[m]> and it needs to use a SPI transfer function
<korken89[m]> Or, is it "ok" to create the future without awaiting it with bogus data, only to get its size?
<korken89[m]> Bogus data = transmute or similar
<ragarnoy[m]> * and it needs to use a SPI transfer function, so the best I could do was this, any idea ?... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/OoEuxmoBmvqCluNOPbwyfXDy>)
<ragarnoy[m]> * and it needs to use a SPI transfer function, so the best I could do was this, any idea ?... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/JMWEgyuBrtYvKyOxgROiDiqe>)
<korken89[m]> What I want to do is too get the size of the futures in RTIC to add support for allocating them all before init
<thejpster[m]> ragarnoy: you might want want to check the pointer is non-null. You should also try and avoid static mut variables (see docs.rs/grounded for some ideas or docs.rs/static-cell)
lehmrob has joined #rust-embedded
<Noah[m]1> <korken89[m]> "What I want to do is too get the..." <- doesn't embassy do this?
<JamesMunns[m]> It does on nightly
<JamesMunns[m]> That's why they switched to the pool allocator on stable. To get the size, you need nightly features, like TAIT or one or two others
<korken89[m]> I want the size, so RTIC can work on stable
<korken89[m]> Else i don't know how to allocate space for the future
<JamesMunns[m]> So does embassy, but afaik, you can't on stable.
<korken89[m]> As I understand the task allocator is specifically for stable support
<JamesMunns[m]> Maybe we're talking past each other: there's no stable+static way to get the size. It's pick one right now
<JamesMunns[m]> So the pool allows you to get the size at runtime and allocate that.
<korken89[m]> I don't need a static way, only some way to get the size :)
<korken89[m]> I want to do the allocations before I we jump to init
<JamesMunns[m]> Probably core::mem::size_of_val or something
<JamesMunns[m]> But yeah you could look at how embassy does it.
<korken89[m]> So users get nice errors before an app starts, if the allocator does not have enough memory
<korken89[m]> I'm digging :)
<Noah[m]1> <JamesMunns[m]> "That's why they switched to..." <- ohh, TIL!
<korken89[m]> So embassy constructs the future when it's supposed to be spawned and allocates then
<JamesMunns[m]> Noah[m]1: Yeah sorry I should have said "to get the size **statically** you need nightly features"
<korken89[m]> Indeed, this is what RTIC does today
<Noah[m]1> JamesMunns[m]: no worries, I got you just right :)
<korken89[m]> And one could do the alloc at spawn-time, but then you don't get any guarantees that your allocation pool is large enough or not
<Noah[m]1> I did not know they switched to get stable support. Somehow I thought all the required features were stabilized even though I never saw an announcement lol :D
<ragarnoy[m]> <thejpster[m]> "ragarnoy: you might want want..." <- i can't seem to be able to call write on the spi when it's behind the static cell :/
<JamesMunns[m]> Yeah, async fn in trait was the highest blocker, the rest was workaroundable
<JamesMunns[m]> There's like 2-3 different nightly features that let you calculate the size, TAIT is the most direct or most likely to stabilize iirc
<JamesMunns[m]> Dirbaio will know the real answer :D
<dirbaio[m]> Yeah in the case of rtic thanks to the macro it feels like you should be able to allocate everything in initย 
<korken89[m]> I feel so as well
<korken89[m]> Just trying to conjure the future enough to get its size and alignment xD
<dirbaio[m]> So OOM can only happen right at boot, never later. Which is really nice, and not possible in embassy.ย 
<korken89[m]> Soooo, the asm if you just yolo MaybeUninit::uninit().assume_init() does give the correct answer xD
<dirbaio[m]> Yea but you have to somehow be able to name the typeย 
<korken89[m]> I mean like htis https://rust.godbolt.org/z/bcEhTx1E4
<korken89[m]> Probably 99.9% UB
<JamesMunns[m]> korken89[m]: This is pretty much always ub
<JamesMunns[m]> The docs specifically say "don't do that"
<korken89[m]> Yeah, it's not something I'd recommend
<korken89[m]> But I am getting desperate :P
<JamesMunns[m]> You don't need to assume init
<JamesMunns[m]> Maybe uninit T is guaranteed to be the same size as T
<korken89[m]> Oh?
<dirbaio[m]> actually
<JamesMunns[m]> It's repr transparent
<dirbaio[m]> you can just stack-allocate everything on init
<dirbaio[m]> can't you?
<dirbaio[m]> no unsafe hacks required
<JamesMunns[m]> dirbaio[m]: Yeah, and then use size_of_val by ref like I mentioned :p
<ragarnoy[m]> <thejpster[m]> "ragarnoy: you might want want..." <- could you explain how one is supposed to get a &mut T back after initializing a staticcell ?
<dirbaio[m]> if you stack-allocate it and leave it on the stack forever throughout the execution you don't even need the size
<korken89[m]> dirbaio[m]: Hmm, not quite sure how I'd do this. It would require the same where I know the size of the future right?
<dirbaio[m]> yea but you can use generics in that case to know it
<korken89[m]> Oh
<dirbaio[m]> ah maybe you need unstable feature(unboxed_closures) to do F::Output or something
<dirbaio[m]> uhh
<korken89[m]> Hmm
<korken89[m]> <JamesMunns[m]> "Maybe uninit T is guaranteed..." <- But how to get the future when the values are uninit? If I transmute them to T it seems just as UB to me as `assume_init`, no?
<JamesMunns[m]> korken89[m]: I'm not sure I understand. I thought you just needed the size to move it to a static allocation pool or something
<korken89[m]> Yes, that is correct
<korken89[m]> But to do that I need input parameters to the future, which I do not have
<JamesMunns[m]> Like your code creates the future on the stack, you allocate space, you move from stack to uninit allocation using ptr::write
<korken89[m]> So I need to conjure them soehow
<korken89[m]> s/soehow/somehow/
<korken89[m]> As I want the size of the future before a user creates the same future
<korken89[m]> So I can pre-allocate it before init
<korken89[m]> I can allocate them at call time from the user, but I really want the feature of making sure the allocators pool size is large enough at init
<JamesMunns[m]> I'm not sure I understand, it seems like you would need to calculate it statically then. But maybe I'm just not imaginative enough.
<korken89[m]> Statically give the answer indeed (this is what RTIC does today), but I'm fine with run-time as long as I can conjure the inputs so size_of_val can be used
<korken89[m]> The UB way does give the right answer, but I'm looking for some other way that is at least technically not UB :)
<JamesMunns[m]> korken89[m]: If you have load bearing UB I'd probably stop recommending RTIC :p
<korken89[m]> dirbaio[m]: Neat!
<korken89[m]> JamesMunns[m]: Yeah, it's not really something we'd do :P
<dirbaio[m]> use generics in Task to name the future. then you can simply own a `Fut`.... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/opxkJyiuVArbLVwmKuSdfyDe>)
<dirbaio[m]> I think the erase/un-erase should be good? in both cases they're the same type
<dirbaio[m]> miri doesn't complain
<dirbaio[m]> and
<dirbaio[m]> as long as main doesn't return, the stack-allocated Task lives forever, so it's fine to store a pointer in a static.
<dirbaio[m]> and RTIC's macro controls main, so it should be easy to enforce it never returns I guess
<korken89[m]> That was a really neat way of doing it
<dirbaio[m]> it feels a bit ugly
<dirbaio[m]> but it's the least ugly way I can think of so... ๐Ÿคท
<korken89[m]> It gave me inspiration for more heinous crimes to the compiler :D
<dirbaio[m]> lol
<dirbaio[m]> btw, there's talks to stabilize ATPIT soon (associated-type-position impl Trait), before the full TAIT
<korken89[m]> Oh
<dirbaio[m]> it's TAIT but only in associated types: `impl Foo for Bar { type Future = impl Future<Output=...>; }`
<dirbaio[m]> which seems unlikely to have issues getting stabilized, because ATPIT is not affected by the defining scope issues the full TAIT has
<dirbaio[m]> * not affected as much by the
<dirbaio[m]> and
<dirbaio[m]> you can almost always convert code from TAIT to ATPIT, you just need a dummy trait and dummy struct ๐Ÿคฎ
<dirbaio[m]> but that's not an issue for macros :D
<dirbaio[m]> so I think just stable ATPIT would work for RTIC or embassy-executor
<dirbaio[m]> so I hope all these hax will become obsolete soon ๐Ÿ™
<korken89[m]> That's actually true!
<korken89[m]> I did not think ATPIT was enough
<dirbaio[m]> make a dummy trait, impl it for a dummy struct returning the fut in the ATPIT, then you can name it as `<DummyStruct as DummyTrait>::Future` in the static ๐Ÿ’ฉ
<dirbaio[m]> should work
<korken89[m]> Seems like it!
<korken89[m]> Also, this is not horrible: https://rust.godbolt.org/z/sEhrzb7an
<korken89[m]> Generate the SizeOf for all sizes needed in the macro
<dirbaio[m]> hah
<korken89[m]> But if once can allocate on the stack is neater hough
<korken89[m]> s/hough/though/
<korken89[m]> * But if once can allocate on the stack of main is neater though
<dirbaio[m]> if you go the allocator route don't forget about align too
<korken89[m]> Indeed, just align_of there :)
<dirbaio[m]> i'm not sure what's best though.
<dirbaio[m]> in the stack the user doesn't need to tune the arena size, it'll grow as needed. but if it grows too much it'll stack-overflow which is UB
<dirbaio[m]> with an arena, the user has to manually tune the size which is annoying, but you can give a nice error message if it fills up
<dirbaio[m]> * fills up, instead of UB
<korken89[m]> Yeaha
<korken89[m]> Tbh I'm not sure there. If the tuning is easy I'd see it as a win as wll
<korken89[m]> s/wll/well/
<korken89[m]> E.g. be able to access the_amount_of_space_actually_used_by_the_allocations()
<korken89[m]> Does not feel horrible at least
<dirbaio[m]> ๐Ÿฅฒ
<korken89[m]> xD
<korken89[m]> projectile vomit
<korken89[m]> I guess one can go the ENV variable way as well
<korken89[m]> Not sure if better though
<korken89[m]> Haha
<korken89[m]> Ahh, nice ๐Ÿ”ฅ
<JamesMunns[m]> I wonder if you could make it tunable by having the structs be actual powers of two. Like, one feature for each bit. So if you want 192 bytes you could select the 128 feature and the 64 feature
<dirbaio[m]> lol!
<dirbaio[m]> just convert the size you want to binary, then enable the features corresponding to the bits
<dirbaio[m]> easy peasy
<dirbaio[m]> then you got two crates depending on embassy-executor in your tree, and now the arena size is accidentally the bitwise OR of them ๐Ÿ’€
<korken89[m]> :D
<JamesMunns[m]> :D :D
<JamesMunns[m]> truly additive features
<JamesMunns[m]> <ragarnoy[m]> "could you explain how one is..." <- btw, you just call `init()` and it gives you back a `&'static mut T`?
<korken89[m]> Thanks for the discussions! I think I'll make one "main as allocator" and one "real allocator" test implementation for RTIC to see where they land
<ragarnoy[m]> JamesMunns[m]: this initializes the cell, but how do i get a mutable reference to its content ?
<JamesMunns[m]> ragarnoy[m]: What do you mean?... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/MqsjMaGoUeORQMuRWRefbdFb>)
<JamesMunns[m]> JamesMunns[m]: > <@jamesmunns:beeper.com> What do you mean?... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/QLDhallGNYtMSyGwRvAlyvNF>)
<ragarnoy[m]> but what if you want to use it else where ? and you can't pass the reference by argument
<JamesMunns[m]> then you need to make it something like a `StaticCell<Mutex<..., u32>>`
<JamesMunns[m]> (or RefCell, or otherwise). It's two concerns: StaticCell makes it "live forever", Mutex allows it to be shared (if it needs to be mutable in multiple places)
<dirbaio[m]> ragarnoy[m]: StaticCell gives you a `&'static mut T` the instant you initialize it, then nothing else. you have to pass that `&'static mut T` to the places you need it, for example as task arguments. If you need to pass it to multiple places you can convert it to `&'static T` first, so you can copy it first.
<dirbaio[m]> you can not get a second reference to the contents after you have initialized it
<dirbaio[m]> this is what allows StaticCell to work with !Send, !Sync data, and allows it to give you a `&'static mut T`. if you could get more refs out of it, it'd be unsound
<dirbaio[m]> if this doesn't work for you then you want something else
<dirbaio[m]> like a OnceCell
<dirbaio[m]> OnceCell allows you to get many references out multiple times, but only `&'static`, not `&'static mut`
<dirbaio[m]> * a OnceCell or OnceLock
<dirbaio[m]> and if you need to get multiple references, and get mut references, then you need a full Mutex
PhilMarkgraf[m] has quit [Quit: Idle timeout reached: 172800s]
<ragarnoy[m]> dirbaio[m]: I'm working with a Rust library that requires a custom hardware abstraction layer (HAL) implementation in C. This implementation includes a transfer function as part of the HAL interface, the signature is inflexible but internally it needs to perform SPI transfers
<ragarnoy[m]> is this what you mean then ? :... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/yRFdKPDfFJzBcCZqHUgidUXz>)
<ragarnoy[m]> s/get_mut().//
<dirbaio[m]> static mut SPI_INSTANCE: Mutex<CriticalSectionRawMutex, Cell<Option<&'static mut dyn SpiDevice<u16, Error=Infallible>>>> = StaticCell::new();
<dirbaio[m]> * ```rust
<dirbaio[m]> static mut SPI_INSTANCE: Mutex<CriticalSectionRawMutex, Cell<Option<&'static mut dyn SpiDevice<u16, Error=Infallible>>>> = StaticCell::new();
<dirbaio[m]> * ```rust
<dirbaio[m]> ```
<dirbaio[m]> static mut SPI_INSTANCE: Mutex<CriticalSectionRawMutex, Cell<Option<&'static mut dyn SpiDevice<u16, Error=Infallible>>>> = Mutex::new(Cell::new(None));
<dirbaio[m]> I think that's what yo uwant
<dirbaio[m]> s/yo/you/, s/uwant/want/
<JamesMunns[m]> Does it need to be static mut if it's a mutex?
<dirbaio[m]> on main, lock it and set it to Some(my_spi). on transfer16_function lock it, use it
<dirbaio[m]> ah yeah just static. edited
<dirbaio[m]> * ```rust
<dirbaio[m]> static SPI_INSTANCE: Mutex<CriticalSectionRawMutex, Cell<Option<&'static mut dyn SpiDevice<u16, Error=Infallible>>>> = Mutex::new(Cell::new(None));
<dirbaio[m]> ```
<dirbaio[m]> it's odd that the C HAL doesn't allow you passing a "context pointer" through it
<dirbaio[m]> it's typical to do it, so you can pass "things that my function needs" to it
<dirbaio[m]> like this SPI
<dirbaio[m]> or perhaps acc_sensor_id_t is the "context pointer"?
<dirbaio[m]> what type is that, can you use it to somehow store arbitrary data?
<ragarnoy[m]> dirbaio[m]: nope, just an id
<dirbaio[m]> what C code is this, is it opensource?
<JamesMunns[m]> dirbaio[m]: google and grep-app return zero results for `transfer16_function`, impressive.
<ragarnoy[m]> dirbaio[m]: nope, that's the catch
<ragarnoy[m]> i can share if you want, otherwise you need to go on the acconeer website and sign up to have the code
<ragarnoy[m]> but this is their transfer implementation exampl
<dirbaio[m]> wow so really a 0..n ID. no context pointer
<dirbaio[m]> yay
<dirbaio[m]> yeah you'll have to use globals then :(
<ragarnoy[m]> <dirbaio[m]> "static mut SPI_INSTANCE: Mutex<..." <- > <@dirbaio:matrix.org> ```rust... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/UgmzjUivJlQfEZDkHBAuEVpO>)
<GrantM11235[m]> Add + Send
<ragarnoy[m]> GrantM11235[m]: static SPI_INSTANCE: Mutex<CriticalSectionRawMutex, Cell<Option<&'static mut (dyn SpiDevice<u16, Error = Infallible> + Send)>>> = Mutex::new(Cell::new(None));
<ragarnoy[m]> ?
<GrantM11235[m]> I think so
<dirbaio[m]> maybe you want to use the actual HAL SPI type instead of dyn
<dirbaio[m]> what HAL are you using? stm32?
<ragarnoy[m]> dirbaio[m]: stm32, but in theory the antenna can be put on any type of processor
<ragarnoy[m]> hence the SpiDriver
<dirbaio[m]> ah you're writing a hardware-independent driver, so using only embedded-hal
<dirbaio[m]> I see
<dirbaio[m]> yeah :(
lehmrob has quit [Ping timeout: 256 seconds]
<ragarnoy[m]> i guess i'm kind of screwed lol
<GrantM11235[m]> Are you sure you don't want to just rewrite the whole c library in rust? ๐Ÿ™ƒ
<JamesMunns[m]> ragarnoy[m]: You have certainly chosen a fairly challenging set of requirements
<JamesMunns[m]> like, it's probably not impossible to do, decently well. It's just not a very fun + easy challenge, especially for volunteer effort lol
<GrantM11235[m]> btw, I don't think you need to use dyn, but it is probably the easiest option. You can probably optimize it a bit more later if you want to
<ragarnoy[m]> GrantM11235[m]: well, i'm making the layer between the hal and the phy implementation, which is private, what i'm using is the api that they give you
<ragarnoy[m]> GrantM11235[m]: what's the alternative ?
<GrantM11235[m]> doing fun tricks with generics
<JamesMunns[m]> ragarnoy[m]: I can't think of any if you want it to be generic over any impl AND has to go through statics like that
<JamesMunns[m]> GrantM11235[m]: if you can name those fun tricks I'd be interested.
<ragarnoy[m]> btw is this how I can acquire the content ? doesn't seem to compile... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/wOKALTPCIasyYYqCHnJWCfsl>)
<GrantM11235[m]> On option would involve fn ptrs and context ptrs, but that is basically just dyn-lite
<ragarnoy[m]> * btw is this how I can acquire the content ? doesn't seem to compile... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/gEkSWqOCNhoLZZMtgsXPJaGK>)
<ragarnoy[m]> ragarnoy[m]: > <@ragarnoy:matrix.org> btw is this how I can acquire the content ? doesn't seem to compile... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/DzyfOUwzcRNwRQAJBObqlElX>)
<JamesMunns[m]> uhh, something like SPI.lock().unwrap().as_mut().write(...).expect()?
<JamesMunns[m]> like mutex has a lock method probalby.
<GrantM11235[m]> You need to `.take().unwrap()` the `Cell<Option>`, and remember to put it back when you are done
<JamesMunns[m]> oh it's a Cell AND and Option
<JamesMunns[m]> oh no its so many containers lol
<ragarnoy[m]> JamesMunns[m]: yes, it's the worst lol
<dirbaio[m]> > SPI_INSTANCE.get_mut();
<dirbaio[m]> you're using `static mut`, aren't you :)
<dirbaio[m]> use just static
<dirbaio[m]> the whole point of using a mutex is you can do it with just static, and therefore no unsafe a tlal
<dirbaio[m]> * the whole point of using a mutex is you can do it with just static, and therefore no unsafe at all
<ragarnoy[m]> hmm then how... ? lock ?
<dirbaio[m]> and actually I didn't realize you'd have this "take out, put back" problem with Cell. I'd say RefCell makes it cleaner
<ragarnoy[m]> dirbaio[m]: in terms of performance or just esthetics ?
<JamesMunns[m]> "less of a pain in the ass to use/implement"
<JamesMunns[m]> I wouldn't call it aesthetically pleasing, but less aesthetically offensive, for sure!
<dirbaio[m]> ragarnoy[m]: it's less "risky", you can't "forget to put it back"
<dirbaio[m]> with Cell it's easy to forget, if the function returns early, for example with an error you propagate with ?
<Ecco> What's the equivalent of CMSIS' "__set_PRIMASK" in Rust?
<ragarnoy[m]> <dirbaio[m]> "with Cell it's easy to forget..." <- yeah, last question, `SpiDevice<u16, Error = Infallible>` is infallible correct here or what should I put for the library users ?
<Ecco> I found a way to *read* primask in the cortex-m crate, but no way to set it
<JamesMunns[m]> ah no that's basepri not primask?
<dirbaio[m]> ragarnoy[m]: yeah it's infallible, but most HALs's SPIs are *not* infallible. So the user will have to "adapt" from "fallible SPI" to "infallible SPI" to use your driver...
<dirbaio[m]> I don't see any way around it. with `dyn` you have to specify the error type, just `dyn SpiDevice<u16>` doesn't work.
<dirbaio[m]> so yeah... perhaps you can provide the "infallible adapter" to make things easier for the user.
<dirbaio[m]> * yeah it's infallible, but most HALs's SPIs are _not_ infallible. So the user will have to "adapt" from "fallible SPI" to "infallible SPI" to use your driver...
<dirbaio[m]> I don't see any way around it. with `dyn` you have to specify the error type, just `dyn SpiDevice<u16>` doesn't work.
<dirbaio[m]> so yeah... perhaps you can provide the "infallible adapter" yourself to make things easier for the user.
<dirbaio[m]> PRIMASK is the "disable all interrupts" bit
<dirbaio[m]> so cortex_m::interrupt::disable(), cortex_m::interrupt::enable()
<dirbaio[m]> or more idiomatic cortex_m::interrupt::free() so you can't forget to reenable
<Ecco> dirbaio[m]: but AFAIK those issue a cpsie/cpsid instruction
<Ecco> whereas CMSIS's set_primask actually write to the primask register
<ragarnoy[m]> last question, for my library, the hal also requires an alloc and free function, any tips on how to handle it and how to give a static evaluated pool size ?... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/harEJgeZhSdUExJjwCQBMuYc>)
<dirbaio[m]> whyyyyyy why do C HALs often require alloc? ๐Ÿ’€
<dirbaio[m]> if you need something fancier look into linked-list-allocator, which is what embedded-alloc uses
<dirbaio[m]> it's a "full" implementation of malloc/free
<ragarnoy[m]> hmmm for now i think i'll keep it simple
<thejpster[m]> Thereโ€™s a PR on tinyrlibc the might do what you want
kenny has quit [Remote host closed the connection]
<ragarnoy[m]> thejpster[m]: wdym ?
kenny has joined #rust-embedded
<GrantM11235[m]> <ragarnoy[m]> "last question, for my library..." <- > <@ragarnoy:matrix.org> last question, for my library, the hal also requires an alloc and free function, any tips on how to handle it and how to give a static evaluated pool size ?... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/XwAedzzfYjDmMmquMENUebHL>)
<ragarnoy[m]> GrantM11235[m]: how so ?
<GrantM11235[m]> ragarnoy[m]: mem_alloc always returns a pointer to the first byte of MEM
<GrantM11235[m]> GrantM11235[m]: if there is more than one allocation, they will all be at the same address
<GrantM11235[m]> GrantM11235[m]: And it is only byte-aligned, which might not be enough
<GrantM11235[m]> GrantM11235[m]: and mem_free just zeros all the bytes *before* the pointer to be freed, which is a no-op since the pointer is always at the start of MEM
<Socke> hmm. whenever I (accidentally) press the enter key in the espflash monitor window, it hangs up and I can't even terminate it using ctrl-c
<Socke> (does not happen when running "espflash monitor" but only when running it through cargo run, which runs espflash flash --monitor)
<Socke> is this a known issue or am I doing something wrong?
<Socke> wait. last info was wrong. also happens with "espflash monitor"
<ragarnoy[m]> <GrantM11235[m]> "and mem_free just zeros all..." <- oh yeah i didn't expect this to be this annoying actually
<ragarnoy[m]> ragarnoy[m]: that free function is non trivial
notgull has quit [Ping timeout: 252 seconds]
notgull has joined #rust-embedded
<ragarnoy[m]> <thejpster[m]> "https://github.com/rust-embedded..."; <- but this requires alloc ?
<dirbaio[m]> it forwards c's malloc/free to rust's global alloc, yes
<dirbaio[m]> so you do need an alloc on the rust side
<ragarnoy[m]> <dirbaio[m]> "if you need something fancier..." <- and on that end, i can't really find how to implement a decent free function
holo[m] has quit [Quit: Idle timeout reached: 172800s]
<vollbrecht[m]> <Socke> "hmm. whenever I (accidentally..." <- i am not sure, best is to create a small issue on github for it.
<GrantM11235[m]> <ragarnoy[m]> "and on that end, i can't..." <- Allocators are complicated. [linked-list-allocator](https://github.com/rust-osdev/linked-list-allocator) is one of the simplest possible implementations, and it is about 1000 lines
corecode has quit [Quit: ZNC - http://znc.in]
emerent has quit [Killed (zinc.libera.chat (Nickname regained by services))]
emerent has joined #rust-embedded
<dirbaio[m]> ๐Ÿฆ€
<firefrommoonligh> <dirbaio[m]> "or more idiomatic cortex_m::..." <- A note for anyone reading: It seems this is being deprecated in favor of `critical_section::with`. So, if writing new code, consider that. Adv: It's more cross-MCU maybe
<firefrommoonligh> (The ecosystem churn is real, but worth it to make stuff better)
<dirbaio[m]> lol churn ๐Ÿ”ฅ
<adamgreig[m]> I don't think cortex_m::interrupt::free will be removed, because it still makes sense to provide "execute a closure with interrupts disabled"
<adamgreig[m]> but I think it will stop giving out a CriticalSection token, that's what critical_section::with is for
<adamgreig[m]> but yea, if what you want is a critical section where you can be sure only one instance of it is running at a time, use the critical_section crate, and as a bonus it's architecture-independent