<re_irc>
<James Munns> adamgreig: This is what postcard does 😅
<re_irc>
<chemicstry> are there any good alternatives to cargo xtask? My use case is to automatically convert elf file to binary, calculate checksum and insert it into the binary's bootloader info section. I don't like that xtask forces using a workspace and also prevents using default build target in ".cargo/config.toml"
emerent has quit [Ping timeout: 250 seconds]
emerent has joined #rust-embedded
Socke has quit [Ping timeout: 250 seconds]
Socke has joined #rust-embedded
vancz_ is now known as vancz
<re_irc>
<ryan-summers> Question on some MaybeUninit stuff: If you initialize a memory location, but never actually generate a valid reference to that now-initialized data, does the compiler guarantee that those maybe-uninit contents will never change?
<re_irc>
let initialized_data: [u32; 1024] = [...];
<re_irc>
let mut uninitialized_data: [MaybeUninit<u32>; 1024] = [MaybeUninit::uninit(); 1024];
<re_irc>
<ryan-summers> Or do you have to generate a valid reference to the "uninitialized_data" for the compiler to guarantee that it will never change?
<re_irc>
<dngrs (spookyvision@github)> thanks, I got confused by the presence of a "Read" trait but no "Write" and the docs saying write support is planned
<re_irc>
<m1cha1s> Does anybody know how to, for example load a compiled program from lets say SD card into RAM and execute it, on cortex-m microcontrollers?
<re_irc>
<K900> Depends on how your SD card is connected
<re_irc>
<m1cha1s> by SD card i mean that there is a binary file on a fat file system
<re_irc>
<K900> On a FAT file system located where?
<re_irc>
<K900> Like, you have three different problems here
<re_irc>
<K900> 1. you need to talk to your storage medium over whatever protocol it understands
<re_irc>
<K900> 2. you need to parse the filesystem
<re_irc>
<K900> 3. you need to load the executable in some known format and execute it
<re_irc>
<K900> There are multiple solutions for all of those
<re_irc>
<m1cha1s> i would like to focus on the problem of somehow loading the compiled executable into ram ent running it
<re_irc>
<K900> That depends on how your executable is actually compiled
<re_irc>
<K900> If it's just a blob of code, you probably just need to load it into a free spot in memory and then jump to it
<re_irc>
<K900> If it's something more complicated, like an ELF file, you'll need to do some parsing
<re_irc>
<K900> If you need to pass some data to the executable, or get some data back, you'll need to come up with an ABI for that
<re_irc>
<m1cha1s> i was thinking about a blob of code. And can i find somewhere an example of such ABI?
<re_irc>
<K900> Also, I'm assuming no OS/no_std for all of this
<re_irc>
<K900> If you have an OS, you'll have to play by its rules
<re_irc>
<K900> The ABI can be something very simple, like ""r1" contains a pointer to a struct that looks like this"
<re_irc>
<K900> Also, you'll need to preserve the state of your loader somewhere if you want the application to be able to return
<re_irc>
<m1cha1s> could i say that this blob of code is a function and use it as it? (yes of course no_std)
<re_irc>
<K900> You could, but then the blob of code will have to actually follow the ABI conventions Rust (or C) uses on your target
<re_irc>
<m1cha1s> ok. but how could i compile such a blob of code in rust?
<re_irc>
<K900> So you know that your program will be written in Rust?
<re_irc>
<m1cha1s> let's assume thst it will
<re_irc>
<K900> In that case it's probably easier to build it as a "dylib" crate and then use an ELF parser to load it
<re_irc>
<K900> It shouldn't be too difficult if you restrict the allowed subset of ELF to things that make sense on embedded
<re_irc>
<K900> Which is basically just relocations
<re_irc>
<m1cha1s> ok thats very cool. Thank you very much :)
<re_irc>
<K900> docs.rs/goblin might be a good starting point for loading ELF files
<re_irc>
<m1cha1s> Thanks again :)
<re_irc>
<dirbaio> is there any way to do an "OR" in Send/Sync impls?
<re_irc>
unsafe impl<T: ?Sized> Sync for Mutex<raw::ThreadMode, T> {}
<re_irc>
unsafe impl<T: ?Sized> Send for Mutex<raw::ThreadMode, T> {}
<re_irc>
<dirbaio> I want "Mutex<R, T>" to be "Send+Sync" if "T: Send" OR if "R=ThreadMode"
<re_irc>
<dirbaio> that gives "conflicting implementations of trait "core::marker::Send" for type ..." :(
<re_irc>
<James Munns> I think that's a "negative trait bounds" thing :/
<re_irc>
<James Munns> Also PSA, if a HAL you work on is full of macros, and you would like to see what it would look like without macros, please ping me here or on twitter. I'd be happy to help you with the patterns we use in the nrf52 HAL (generics + sealed traits) to expunge _most_ peripheral macros.
<re_irc>
<James Munns> Macros make me sad when I have to look at HAL code :(
<re_irc>
<dirbaio> James Munns: try doing that for stm32 😂
<re_irc>
<James Munns> Funnily enough, I'm looking at stm32g0xx hal, and that is what prompted this
<re_irc>
<James Munns> (not to pick on them! It's very idiomatic for the stm32 family!)
<re_irc>
<dirbaio> you still need an insane amount of cfg's for the pin/dma channel mappings and stuff
<re_irc>
<dirbaio> or code generation
<re_irc>
<James Munns> I mean, I don't mind a macro that impls the traits and stuff, but having the whole codegen be macros I think could be replaces
<re_irc>
<James Munns> (like, just the simple sealed trait/associated type stuff can be macros, but having the whole driver inside a macro is sad)
<re_irc>
<dirbaio> if you want an stm32 hal without cursed macros check out "embassy-stm32" :)
<re_irc>
<James Munns> * makes me
<re_irc>
<James Munns> does it support the stm32g030?
<re_irc>
<dirbaio> yep (it supports almost all chips)
<re_irc>
<James Munns> _sigh_, one of these days I'm _really_ going to have to learn embassy
<re_irc>
<dirbaio> you can also use it blocking
<re_irc>
<dirbaio> for blocking use it's mostly the same as the other hals, little learning required
<re_irc>
it impls the embedded-hal traits and all
<re_irc>
<dirbaio> James Munns: or specialization maybe...?
<re_irc>
<dngrs (spookyvision@github)> or does spi flash just work this way and will mutilate your buffer
<re_irc>
<dirbaio> dngrs (spookyvision@github): yes, it's a bit weird :(
<re_irc>
Maybe they did it so the driver requires just "SPI: Transfer<u8>" instead of "SPI: Transfer<u8> + Write<u8>", but that's not worth the forced "mut" IMO...
<re_irc>
<dirbaio> there's no other reason I can think of
<re_irc>
<dngrs (spookyvision@github)> dirbaio: ok, I'm just going to pretend the buffer will not be changed (I'm implementing another trait and that only passes a "&self" so ... time for "unsafe"!)
<re_irc>
<dirbaio> be careful, it _will_ overwrite your buffer with garbage
<re_irc>
<dngrs (spookyvision@github)> ...oh!
<re_irc>
<dngrs (spookyvision@github)> that's a bit unfortunate 😆
<re_irc>
<Pierre-Yves Aillet> dirbaio: Thank you for the feedback, I used to use shared-bus and it somehow led me to this questions.
<re_irc>
Glad to see I'm not alone in this case 😅
<re_irc>
<dirbaio> the last PR (disclaimer: I'm the author) fixes this by having different traits for "SPI bus" and "SPI device" (on a possibly shared bus), so drivers can use the "SPI device" one while letting the user choose which mutex is used (or no mutex at all)
<re_irc>
<dirbaio> * link is a PR (disclaimer: I'm the author) that
<re_irc>
<dirbaio> * trats
<re_irc>
<dirbaio> * traits
<re_irc>
<rahix> Pierre-Yves Aillet: I wrote something about the different solutions and why I think the owned approach is the only well composable one here: https://blog.rahix.de/001-shared-bus/
<re_irc>
<Pierre-Yves Aillet> rahix: Thank you, I did not know you wrote this and it was exactly the kind of deep comparison I was searching for :)
<re_irc>
<dngrs (spookyvision@github)> is there some crate providing ".mbit()", ".kbit()" etc?
<re_irc>
<wsalmon> in regard to owned vs mutex way to share a bus, i came up with a diffrent approch for my driver and wrote about it https://pointswaves.gitlab.io/blog/BitByteStructs-intro.html its also means i can easily write a driver for a chip which has a spi or i2c bus, and i can quicly swap back and forth between diffrent users of the spi bus while not worrying about which thing is using it but not needing the over head of a mutex...
<re_irc>
... :D Pierre-Yves Aillet Rahix
<re_irc>
<wsalmon> i have not used it masses and masses so i am very welcome to feed back but it seemed to work very nicely for me so far
<re_irc>
<James Munns> dngrs (spookyvision@github): Maybe not so terse, but maybe the uom crate or something based on it?
<re_irc>
<James Munns> "1024.into::<megabit>()" or something like that?
<re_irc>
<James Munns> use uom::si::information::megabit;
<re_irc>
use uom::si::f32;
<re_irc>
}
<re_irc>
fn main() {
<re_irc>
let x = f32::Information::new::<megabit>(5.0);
<re_irc>
<marmrt> ooo that's a cute crate
<re_irc>
<James Munns> oh, or with the "u32" feature:
<re_irc>
<chmanie> I would like to write a driver for an SPI DAC. Are there some examplary drivers that can serve as some guidance for using rust embedded best practices?
<re_irc>
<marmrt> I found this blog post to be a decent source of inspiration https://hboeving.dev/blog/rust-i2c-driver-p2/ there's also several examples in the awesome-embedded-rust list
<re_irc>
<chmanie> Oh yeah! Good point thanks for reminding me of that list!
<re_irc>
<thejpster> uom looks interesting. rust-measurements does it differently.
Subaudible has quit [Remote host closed the connection]