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
duderonomy has joined #rust-embedded
sknebel has quit [Server closed connection]
sknebel has joined #rust-embedded
<re_irc> <@crespum:matrix.org> I'm using "shared-bus" for interfacing with several I2C devices but I'm running into version compatibility problems because it's not been updated to "alpha.10". While digging in I've found "embedded-hal-bus", is that supposed to be a replacement?
<re_irc> <@ryan-summers:matrix.org> : As far as I understand it, yes. The alpha releases are trying to solve the sharing problem without external crates, but I have not used them yet so I'm not the foremost authority here
duderonomy has quit [Ping timeout: 240 seconds]
IlPalazzo-ojiisa has joined #rust-embedded
duderonomy has joined #rust-embedded
Lumpio- has quit [Server closed connection]
Lumpio- has joined #rust-embedded
WSalmon_ has quit [Server closed connection]
WSalmon_ has joined #rust-embedded
emerent has quit [Ping timeout: 240 seconds]
emerent has joined #rust-embedded
dc740 has joined #rust-embedded
dc740 has quit [Remote host closed the connection]
dc740 has joined #rust-embedded
Dr_Who has joined #rust-embedded
<re_irc> <@htms:matrix.org> Hello, if I write FLASH_OPTR register in my code, values doesn't change. Pointer looks good, because read values are ok and correspond to reference manual. Here is my function:
<re_irc> pub fn go_to_bootloader() {
<re_irc> free(|cs| {
<re_irc> let optr = OPTR_SPEC;
<re_irc> flash.optr.modify(|_, w| w.n_boot0().bit(false).n_boot1().bit(true).n_swboot0().bit(false));
<re_irc> let flash = unsafe { &(*FLASH::ptr()) };
<re_irc> let sr = flash.sr.read();
<re_irc> let wrperr = sr.wrperr().bit();
<re_irc> info!("Write protection is set: {:?}", wrperr); // <-- false
<re_irc> let mut cd_ref = CUSTOM_DELAY.borrow(cs).borrow_mut();
<re_irc> info!("wait");
<re_irc> if let Some(delay) = cd_ref.deref_mut() {
<re_irc> delay.delay_ms(1000u32)
<re_irc> }
<re_irc> info!("done");
<re_irc> let r = flash.optr.read();
<re_irc> let rr = flash.optr.read().bits();
<re_irc> info!("{=u32:b}", rr);
<re_irc> // 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
<re_irc> // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
<re_irc> // 1 1 1 1 1 0 0 0 1 0 1 0 1 0 1 0
<re_irc> // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
<re_irc> let n_boot1 = r.n_boot1().bit();
<re_irc> let n_boot0 = r.n_boot0().bit();
<re_irc> let n_swboot0 = r.n_swboot0().bit();
<re_irc> info!("NOW nBoot0 {:?} nBoot1 {:?} nBoot0_SW {:?}", n_boot0, n_boot1, n_swboot0); // <-- true, true, true
<re_irc> }
<re_irc> What can cause this problem?
<re_irc> <@htms:matrix.org> Hello, if I write FLASH_OPTR register in my code, values doesn't change. Pointer looks good, because read values are ok and correspond to reference manual. Here is my function:
dc740 has quit [Remote host closed the connection]
<re_irc> pub fn go_to_bootloader() {
<re_irc> free(|cs| {
<re_irc> let flash = unsafe { &(*FLASH::ptr()) };
<re_irc> let optr = OPTR_SPEC;
<re_irc> flash.optr.modify(|_, w| w.n_boot0().bit(false).n_boot1().bit(true).n_swboot0().bit(false));
<re_irc> let sr = flash.sr.read();
<re_irc> let wrperr = sr.wrperr().bit();
<re_irc> info!("Write protection is set: {:?}", wrperr); // <-- false
<re_irc> let r = flash.optr.read();
<re_irc> let rr = flash.optr.read().bits();
<re_irc> info!("{=u32:b}", rr);
<re_irc> // 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
<re_irc> // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
<re_irc> // 1 1 1 1 1 0 0 0 1 0 1 0 1 0 1 0
<re_irc> // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
<re_irc> let n_boot1 = r.n_boot1().bit();
<re_irc> let n_boot0 = r.n_boot0().bit();
<re_irc> let n_swboot0 = r.n_swboot0().bit();
<re_irc> info!("NOW nBoot0 {:?} nBoot1 {:?} nBoot0_SW {:?}", n_boot0, n_boot1, n_swboot0); // <-- true, true, true
<re_irc> }
<re_irc> What can cause this problem?
<re_irc> <@htms:matrix.org> Hello, if I write FLASH_OPTR register in my code, values doesn't change. Pointer looks good, because read values are ok and correspond to reference manual. Here is my function:
<re_irc> pub fn go_to_bootloader() {
<re_irc> free(|cs| {
<re_irc> let flash = unsafe { &(*FLASH::ptr()) };
<re_irc> flash.optr.modify(|_, w| w.n_boot0().bit(false).n_boot1().bit(true).n_swboot0().bit(false));
<re_irc> let sr = flash.sr.read();
<re_irc> let wrperr = sr.wrperr().bit();
<re_irc> info!("Write protection is set: {:?}", wrperr); // <-- false
<re_irc> let r = flash.optr.read();
<re_irc> let rr = flash.optr.read().bits();
<re_irc> info!("{=u32:b}", rr);
<re_irc> // 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
<re_irc> // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
<re_irc> // 1 1 1 1 1 0 0 0 1 0 1 0 1 0 1 0
<re_irc> // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
<re_irc> let n_boot1 = r.n_boot1().bit();
<re_irc> let n_boot0 = r.n_boot0().bit();
<re_irc> let n_swboot0 = r.n_swboot0().bit();
<re_irc> info!("NOW nBoot0 {:?} nBoot1 {:?} nBoot0_SW {:?}", n_boot0, n_boot1, n_swboot0); // <-- true, true, true
<re_irc> }
<re_irc> What can cause this problem?
<re_irc> <@ryan-summers:matrix.org> : Is the flash manager actually clocked? A lot of STM32 peripherals need some reset/clock bits set before writes will "stick"
<re_irc> <@ryan-summers:matrix.org> Not sure about the FLASH block personally
<re_irc> <@thejpster:matrix.org> Anyone around familar with ELF? When I look at a binary I made, I have a spurious extra LOAD segment in the program header.
<re_irc> <@htms:matrix.org> : Yes, also I can read and write flash without any problems in other places with "prog.keyr.unlock_flash()" which returns "FlashProgramming".
<re_irc> <@ryan-summers:matrix.org> Read/write flash is different than being able to access the flash manager control registers
<re_irc> <@ryan-summers:matrix.org> Not sure what "unlock_flash()" is doing? Is that part of the FLASH peripheral?
<re_irc> <@thejpster:matrix.org> LOAD off 0x00000000 vaddr 0x20000000 paddr 0x20000000 align 2**16
<re_irc> filesz 0x00000004 memsz 0x00000004 flags r--
<re_irc> LOAD off 0x00001000 vaddr 0x20001000 paddr 0x20001000 align 2**16
<re_irc> filesz 0x00000114 memsz 0x00000114 flags r--
<re_irc> LOAD off 0x00001004 vaddr 0x20001004 paddr 0x20001004 align 2**16
<re_irc> filesz 0x00000444 memsz 0x00000444 flags r-x
<re_irc> The the second one is my entry point address (4 bytes of data) and the third segment is my executable code. But the first one shouldn't be there, and doesn't appear in an objcopy.
<re_irc> <@htms:matrix.org> : but didn't they use same FLASH::ptr() under the hood?
<re_irc> <@ryan-summers:matrix.org> No clue, do they? I don't know your chip :)
<re_irc> <@dirbaio:matrix.org> : try adding --nmagic to linker args
<re_irc> <@htms:matrix.org> : STM32L451CCU6
<re_irc> <@htms:matrix.org> : unlocks flash via KEYR registers according to commentaries, it's a recommended way to write flash which I saw in examples
<re_irc> <@ryan-summers:matrix.org> : Did you take precautions as outlined in section 3.4.2 of the STM32L4+ RM?
<re_irc> <@ryan-summers:matrix.org> You have to enable the option registers first in the CR
<re_irc> <@thejpster:matrix.org> : great! that makes it go away. But why is it there and how do I know to ignore it if my users didn't compile their ELF with "--nmagic"
<re_irc> <@dirbaio:matrix.org> I've never fully understood what it is
<re_irc> <@dirbaio:matrix.org> the linker defaults to align 2^16, and it does weird stuff if your memory doesn't align to that
<re_irc> <@dirbaio:matrix.org> (that weird stuff might be bugs, no idea)
<re_irc> <@thejpster:matrix.org> > Turn off page alignment of sections, and disable linking against shared libraries.
<re_irc> <@dirbaio:matrix.org> --nmagic sets align to 4
<re_irc> <@thejpster:matrix.org> Hmm
<re_irc> afaik you can't, you have to get the users to use --nmagic :(
<re_irc> <@dirbaio:matrix.org> > how do I know to ignore it if my users didn't compile their ELF with "--nmagic"
<re_irc> <@dirbaio:matrix.org> the elf without --nmagic is broken
<re_irc> <@dirbaio:matrix.org> +simply
<re_irc> <@thejpster:matrix.org> It certainly seems broken. A weird segment of 276 bytes at an address that's not in my linker script.
<re_irc> <@htms:matrix.org> : It must be it, thanks a lot, I'll give it a try.
<re_irc> <@thejpster:matrix.org> --nmagic also make the PHDR segment go away
<re_irc> <@thejpster:matrix.org> which is fine, because it's at a well known place (I must be looking in the PHDR segment to see the program header entries at all...)
<re_irc> <@thejpster:matrix.org> I think I can filter out the bad segments because their file offset is within the program header itself.
<re_irc> <@dirbaio:matrix.org> what tool is this that needs to deal with the broken ELFs?
<re_irc> <@dirbaio:matrix.org> I'm not sure if lack of --nmagic always results in an ELF that's broken _thart particular way_
<re_irc> <@dirbaio:matrix.org> * _that
<re_irc> <@dirbaio:matrix.org> it might be safer to reject the broken elfs instead of trying to fix them up, telling the user to add --nmagic
<re_irc> <@dirbaio:matrix.org> will save the user pain, since other tools most likely haven't implemented your "auto fix0up"
<re_irc> <@dirbaio:matrix.org> * fix-up"
dc740 has joined #rust-embedded
Dr_Who has quit [Quit: ZZZzzz…]
Dr_Who has joined #rust-embedded
Amanieu has quit [Server closed connection]
Amanieu has joined #rust-embedded
Dr_Who has quit [Quit: ZZZzzz…]
Dr_Who has joined #rust-embedded
<re_irc> <@thejpster:matrix.org> https://github.com/Neotron-Compute/neotron-loader
<re_irc> <@thejpster:matrix.org> The ELF loader I literally just wrote from scratch for my OS
<re_irc> <@jamesmunns:beeper.com> congrats!
dc740 has quit [Remote host closed the connection]
Dr_Who has quit [Quit: ZZZzzz…]
Dr_Who has joined #rust-embedded
Dr_Who has quit [Quit: ZZZzzz…]
dc740 has joined #rust-embedded
dc740 has quit [Remote host closed the connection]
<re_irc> <@whitequark:matrix.org> first time using embassy today :)
<re_irc> <@whitequark:matrix.org> it's been so long since i touched embedded rust
IlPalazzo-ojiisa has quit [Quit: Leaving.]
<re_irc> <@whitequark:matrix.org> where does the probe-run binary live?
<re_irc> <@whitequark:matrix.org> oh I see it's not a part of embassy
<re_irc> <@jamesmunns:beeper.com> also things like atomic compare and swap could be bad on memory mapped registers - CAS operations may write/read multiple times to the same register, which might have side effects.
<re_irc> <@dirbaio:matrix.org> yep in ARM it's technically UB to use LDREX/STREX on device memory according to the ISA reference manuals
<re_irc> <@jamesmunns:beeper.com> : Nice, I remember we looked it up a while ago, and it was sorta uhhhhhhhh)
<re_irc> <@dirbaio:matrix.org> though we investigated it a while ago and the conclusion was "it probably works in all of today's cortex-m's" because they implement LDREX/STREX as a single global monitor over all address space
<re_irc> <@dirbaio:matrix.org> > you're not supposed to mix volatile and atomic access (I think it's undefined behavior? less sure about that)
<re_irc> <@dirbaio:matrix.org> also
<re_irc> <@dirbaio:matrix.org> but yeah, uhhhhhhh indeed
<re_irc> volatile and atomic accesses can get reordered past each other, so yes, it's something to be aware of too
<re_irc> <@romancardenas:matrix.org> I see... I was reading the RISC-V PLIC specification and it states that you could do atomic ands etc.
<re_irc> <@dirbaio:matrix.org> and there's no such thing as "volatile atomic" accesses
<re_irc> <@romancardenas:matrix.org> Perhaps it is better to have two different drivers like plic and atomic_plic or something like that
<re_irc> <@dirbaio:matrix.org> anyway
<re_irc> <@jamesmunns:beeper.com> Yeah, having some "extra" functions that lower to risc-v inline asm seems reasonable
<re_irc> <@dirbaio:matrix.org> IMO the "make a Rust struct with the same layout as a register block" is an antipattern
<re_irc> <@jamesmunns:beeper.com> I don't think C/Rust really have a concept of "volatile + atomic", so probably addressing it via a library API is probably better
<re_irc> <@dirbaio:matrix.org> there was this problem of taking a "&" to it, and Rust marking all "&"s as "dereferenceable", which allowed LLVM to insert spurious reads
<re_irc> <@dirbaio:matrix.org> which got kinda "solved" by Rust changing to do "not mark it as "dereferenceable" if the type contains an "UnsafeCell""
<re_irc> <@dirbaio:matrix.org> but it's more of a "just in case it's unsound in the Rust memory model that we don't know what it is yet"
<re_irc> <@dirbaio:matrix.org> not because "Rust memory model says it's unsound"
<re_irc> <@dirbaio:matrix.org> So I'd recomemnd people to NOT use crates like "volatile_register" or "vcell" (or this proposed "atomic_register"
<re_irc> <@dirbaio:matrix.org> and NOT make structs overiapping register blocks intead
<re_irc> <@dirbaio:matrix.org> * either
<re_irc> <@dirbaio:matrix.org> use raw pointer maths instead
<re_irc> <@dirbaio:matrix.org> and ".volatile_load()" / ".volatile_store()"
<re_irc> <@dirbaio:matrix.org> and then with "asm!" with the right clobbers you can emulate "volatile atomics" without soundness issues
<re_irc> <@jamesmunns:beeper.com> , on memory mapped structs:
<re_irc> <@dirbaio:matrix.org> svd2rust and cortex-m and everyone else does these memory-mapped structs right now 😭
<re_irc> <@jamesmunns:beeper.com> : Honestly, write a blog post "memory mapped structures considered harmful", so we have one place to link back to it every time the conversation comes up.
<re_irc> <@dirbaio:matrix.org> hahaha
<re_irc> <@dirbaio:matrix.org> yeah, they work fine for now
<re_irc> <@dirbaio:matrix.org> and probably will keep working fine
<re_irc> <@romancardenas:matrix.org> Probably I'll try to develop an atomic PLIC driver following the pointer arithmetics approach and see how it looks like
<re_irc> <@dalepsmith:matrix.org> Something that really messes with mapping a struct over registers, is i've seen devices that a read and a write do different things, You can not read back what you wrote..
<re_irc> <@jamesmunns:beeper.com> Just might want to be careful if you're using core::sync::atomic and not inline asm - just because it supports "atomic and" to registers, the compiler might not always generate the specific operations you want if optimized!
<re_irc> <@dalepsmith:matrix.org> read & write to the same register address
<re_irc> <@dirbaio:matrix.org> ".volatile_load()" / ".volatile_store()" for an e.g. u32 is supposed to compile to a "ldr"/"str" which is atomic
<re_irc> <@dirbaio:matrix.org> by "atomic volatile" we meant "volatile atomic CAS"
<re_irc> <@dirbaio:matrix.org> I guess?
<re_irc> <@dirbaio:matrix.org> like, atomically set a bit or something
<re_irc> <@dirbaio:matrix.org> what atomic ops does the PLIC need ? 👀
<re_irc> <@jamesmunns:beeper.com> I'm guessing it supports some kind of "&=" or "|=" operation to avoid cortex-m's cursed bitbanding or incurring a RMW?
<re_irc> <@romancardenas:matrix.org> Mainly set/reset bits on registers that are shared accross multiple HARTs
<re_irc> <@romancardenas:matrix.org> I guess atomic load/stores wouldn't be harmful too
<re_irc> <@romancardenas:matrix.org> I'll probably try to use assembly directly and avoid the core library (already suffered weird situations with RTIC...)
<re_irc> <@dirbaio:matrix.org> how do you make a "dummy" section in a linker script, only for holding metadata?
<re_irc> <@jamesmunns:beeper.com> NOLOAD?
<re_irc> <@dirbaio:matrix.org> that doesn't get flashed to the target
<re_irc> <@dirbaio:matrix.org> i'm trying:
<re_irc> #[link_section = ".teleprobe.target"]
<re_irc> #[used]
<re_irc> static TELEPROBE_TARGET: [u8; b"rpi-pico".len()] = *b"rpi-pico";
<re_irc> .teleprobe.target (NOLOAD) :
<re_irc> {
<re_irc> KEEP(*(.teleprobe.target));
<re_irc> }
<re_irc> <@dirbaio:matrix.org> but it says: "rust-lld: error: no memory region specified for section '.teleprobe'"
<re_irc> <@dirbaio:matrix.org> which means it's missing ">FLASH" or similar, but I don't want to put it in RAM nor FLASH
<re_irc> <@mabez:matrix.org> .teleprobe.target (INFO) :
<re_irc> {
<re_irc> KEEP(*(.teleprobe.target));
<re_irc> }
<re_irc> <@jamesmunns:beeper.com> .teleprobe (NOLOAD) :
<re_irc> {
<re_irc> KEEP(*(.teleprobe) *(.teleprobe.target));
<re_irc> }
<re_irc> maybe ?
<re_irc> <@jamesmunns:beeper.com> TIL: INFO section: https://github.com/knurling-rs/defmt/blob/main/defmt/defmt.x.in#L14
<re_irc> <@jamesmunns:beeper.com> : No worries! It's still a conversation. I'd probably agree with dirbaio, but you're doing what everyone else has done in Rust (for the last 5 years) and in C (for decades)
<re_irc> <@grantm11235:matrix.org> : I've probably mentioned this before, but I don't actually think that "volatile + _non-atomic_" makes any sense
<re_irc> <@jamesmunns:beeper.com> : Hey, take THAT fight up with C/C++'s memory model, not folks here :D
<re_irc> <@dirbaio:matrix.org> yeah, TIL too :o
<re_irc> <@dirbaio:matrix.org> now to read it from "teleprobe" :D
<re_irc> <@dirbaio:matrix.org> (for context: I want to give a bunch of ELFs to teleprobe and have it automatically know the right targets for each)
<re_irc> <@dirbaio:matrix.org> * run it in the right target
<re_irc> <@dirbaio:matrix.org> * each one in the right target, without me having to tell it)
<re_irc> <@zacck:matrix.org> Hey team, in an effort to get familiar with embedded rust, I'd love to work on contributing to the Embedded book. I noticed that section 2.8 is in a TODO state and has been so for quite a while. Can anyone perhaps spotlight on what needs to be covered and how to do so with accordance to the book. Any pointers at where I should focus my efforts would be amazing! Thank you!
<re_irc> <@9names:matrix.org> Section 2.3: "Memory-mapped registers" already describes memory-mapped IO, so it's not obvious what should be there.
<re_irc> I think the fact that this topic has been in this state for so long indicates that it should be removed.
<re_irc> <@romancardenas:matrix.org> : would a memory-mapped peripheral look like this according to your perspective?
<re_irc> use core::marker::PhantomData;
<re_irc> #[derive(Default, Debug)]
<re_irc> pub struct PERIPHERAL<const BASE: usize> {
<re_irc> _marker: PhantomData<*const ()>,
<re_irc> }
<re_irc> impl<const BASE: usize> PERIPHERAL<BASE> {
<re_irc> /// Pointer to the register
<re_irc> pub const PTR: *const u64 = BASE as *const _;
<re_irc> /// Creates a new interface for the register.
<re_irc> pub const fn new() -> Self {
<re_irc> Self {
<re_irc> _marker: PhantomData,
<re_irc> }
<re_irc> }
<re_irc> /// Performs a volatile read of the peripheral register.
<re_irc> ///
<re_irc> /// # Note
<re_irc> ///
<re_irc> /// Beware of what "volatile" means in Rust.
<re_irc> /// For more information, check [`core::ptr::read_volatile`].
<re_irc> #[inline]
<re_irc> pub fn read() -> u64 {
<re_irc> // Safety: peripheral is a well-aligned RW register.
<re_irc> unsafe { core::ptr::read_volatile(Self::PTR) }
<re_irc> }
<re_irc> /// Performs a volatile write of the peripheral register.
<re_irc> ///
<re_irc> /// # Note
<re_irc> ///
<re_irc> /// Beware of what "volatile" means in Rust.
<re_irc> /// For more information, check [`core::ptr::write_volatile`].
<re_irc> #[inline]
<re_irc> pub fn write(value: u64) {
<re_irc> // Safety: peripheral is a well-aligned RW register.
<re_irc> unsafe { core::ptr::write_volatile(Self::PTR as _, value) };
<re_irc> }
<re_irc> }
<re_irc> <@romancardenas:matrix.org> Regarding atomic operations using assembly... it starts getting messy when you need to provide support to 32 and 64-bit archs. You must be aware of memory address alignment etc. depending on the target
<re_irc> <@dirbaio:matrix.org> yeah, just raw pointers + read_volatile/write_volatile 👍️👌
<re_irc> <@dirbaio:matrix.org> depending on what you want to do, maybe it's better to have the pointer as a field in "Self", instead of a const generic
<re_irc> <@dirbaio:matrix.org> so you can create register blocks pointing to different instances of the same peripheral
<re_irc> <@dirbaio:matrix.org> this is what "chiptool" generates, for example: https://github.com/embassy-rs/rp-pac/blob/main/src/uart.rs#L2
<re_irc> <@romancardenas:matrix.org> Great, thanks! So... What about making them Copy? Am I going too far? 😂
<re_irc> <@romancardenas:matrix.org> I see your example is Copy, so I guess it's not that bad
<re_irc> <@dirbaio:matrix.org> yeah, it's just copying the value of the pointer
<re_irc> <@dirbaio:matrix.org> so it's fine
<re_irc> <@dirbaio:matrix.org> (it wouldn't be fine in the "memory-mapped struct" case, there Copy would make it actually read register memory, without volatile)
<re_irc> <@romancardenas:matrix.org> Nice! I guess that the example uses self instead of &self because it is cheaper to copy the struct than dealing with references, right?
<re_irc> <@dirbaio:matrix.org> the struct is just a pointer
<re_irc> <@dirbaio:matrix.org> "&self" would pass a pointer to the pointer
<re_irc> <@dirbaio:matrix.org> it's nicer to just pass the pointer
<re_irc> <@dirbaio:matrix.org> (even if you did "&self" the compiler would probably be smart enough to optimize it well, but it doesn't hurt to do "self")
<re_irc> <@dirbaio:matrix.org> ("self" hurts usability if the struct is not Copy, but it is in this case)
<re_irc> <@romancardenas:matrix.org> I see. What about pointer maths with offset? Would you use generic parameters or do you prefer regular arguments?
<re_irc> My guess is that, being just an inline volatile read/write, generics won't increase the size of the binary, but may be faster than regular arguments
<re_irc> <@dirbaio:matrix.org> like, accessing register index "i" out of an array of identical registers?
<re_irc> <@romancardenas:matrix.org> Yep
<re_irc> <@dirbaio:matrix.org> regular args https://github.com/embassy-rs/rp-pac/blob/main/src/pads.rs#L15
<re_irc> <@dirbaio:matrix.org> the problem with const generics is the index has to be fixed at compile time
<re_irc> <@dirbaio:matrix.org> so you can't even do do stuff like "for i in 0..4 { regs.foo(i).write(...) }"
<re_irc> <@dirbaio:matrix.org> accessing a reg by an index known only at runtime
<re_irc> <@romancardenas:matrix.org> Oh you're right! I didn't think about it
<re_irc> <@dirbaio:matrix.org> : oooh this was the trick, thanks! :D
<re_irc> <@mabez:matrix.org> : .teleprobe.target (INFO) :
<re_irc> {
<re_irc> KEEP(*(.teleprobe.target));
<re_irc> }
<re_irc> ```?
<re_irc> <@zacck:matrix.org> : Ah thank you for the clarification that makes a tonne of sense
<re_irc> <@k900:conduit.0upti.me> It's in probe-rs which is a separate thing
<re_irc> <@whitequark:matrix.org> right, I was actually looking for probe-rs-cli
<re_irc> error[E0425]: cannot find function `__basepri_r` in module `crate::asm::inline`
<re_irc> --> /home/whitequark/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cortex-m-0.7.7/src/register/basepri.rs:6:15
<re_irc> <@whitequark:matrix.org> I'm hitting:
<re_irc> 6 | call_asm!(__basepri_r() -> u8)
<re_irc> |
<re_irc> | ^^^^^^^^^^^ not found in `crate::asm::inline`
<re_irc> and a few others in the similar vein; what am I doing wrong?
<re_irc> <@adamgreig:matrix.org> That's pretty odd but are you possibly not building for a thumb target?
starblue has joined #rust-embedded
<re_irc> <@whitequark:matrix.org> oh!
<re_irc> <@whitequark:matrix.org> there's .cargo/config.toml with [build] target = "thumbv7em-none-eabi"
<re_irc> <@whitequark:matrix.org> that seems sufficient?
<re_irc> <@whitequark:matrix.org> I removed inline-asm from cortex-m features
<re_irc> <@whitequark:matrix.org> that seems to help
<re_irc> <@dirbaio:matrix.org> missing resolver=2 in the cargo workspace
<re_irc> <@whitequark:matrix.org> oh!
<re_irc> <@whitequark:matrix.org> thank you, this helped
<re_irc> <@whitequark:matrix.org> so now I'm trying to use DMA on STM32F302R8 (which seems to be the only board with a DAC in the huge pile of boards I have) and there seems to be no embassy_stm32::dac
<re_irc> <@whitequark:matrix.org> I'm pretty certain the device does have a DAC, unless ST is bluffing here https://www.st.com/en/microcontrollers-microprocessors/stm32f302r8.html
<re_irc> <@dirbaio:matrix.org> hmm it's missing in stm32-data
<re_irc> <@dirbaio:matrix.org> registers seem to be the same as dac_v1
<re_irc> " (".*:DAC:F3_dacif_v1_1_Cube", ("dac", "v1", "DAC")),"
<re_irc> <@dirbaio:matrix.org> unfortunately stm32 adc/dac versions are all over the place
<re_irc> <@whitequark:matrix.org> what do I do next?
<re_irc> <@whitequark:matrix.org> i.e. where is stm32-data pulled in?
<re_irc> <@dirbaio:matrix.org> run "./d ci", this'll generate "build/stm32-metapac"
<re_irc> then in "embassy-stm32/Cargo.toml" change stm32-metapac to point there with a "path" dep (in both "[dependencies]" and "[build-dependencies]")
<re_irc> <@whitequark:matrix.org> context: I decided to introduce my girlfriend to Rust by working on a project that generates CVBS signals on an STM32 (we got a cute small mono CRT)
<re_irc> <@whitequark:matrix.org> I was absolutely convinced it'll come to patching one of the bits of Rust embedded stack :p
<re_irc> <@thejpster:matrix.org> how many elfs can can elf loader load if an elf loader could load elfs?
<re_irc> <@whitequark:matrix.org> : ohh nice! congrats
<re_irc> <@whitequark:matrix.org> writing an ELF loader is always satisfying for me
<re_irc> <@thejpster:matrix.org> it's such a nice format!
<re_irc> <@thejpster:matrix.org> It's my first. I'm impressed.
<re_irc> <@whitequark:matrix.org> it really is quite well thought out
<re_irc> <@thejpster:matrix.org> I can see why literally everyone except Apple and Microsoft use it.
* re_irc @thejpster:matrix.org looks at four computers that are not Microsoft nor Apple, and don't use ELF.
<re_irc> <@whitequark:matrix.org> let's see... in inverse chronological order, I wrote one for unfork, one for ARTIQ that loads shared objects on bare metal (requiring cursed toolchain hacks and a lot of patching of clang and binutils bugs), and then one for zytokine storm that was doing Linux ELF loading on macOS hosts
<re_irc> <@thejpster:matrix.org> pretty much anything from the last 20 years anyway.
<re_irc> <@whitequark:matrix.org> I think there were several I wrote before that but I don't remember them all, too many
<re_irc> <@thejpster:matrix.org> oof. I tried making relocations work for thumbv6m in Rust and ... yeah.
<re_irc> <@whitequark:matrix.org> it's like 200 lines in artiq, I think
<re_irc> <@whitequark:matrix.org> but I didn't implement all OR1K relocations
<re_irc> <@whitequark:matrix.org> only those that were necessary for PLT and exception handling
<re_irc> <@whitequark:matrix.org> yes, I did exception handling on bare metal with dynamically loaded shared objects
<re_irc> <@whitequark:matrix.org> it uncovered a _truly spectacular_ amount of binutils and clang bugs in the process
<re_irc> <@thejpster:matrix.org> I can imagine.
<re_irc> <@whitequark:matrix.org> I think my favorite one was when Rust print!() statements would randomly start printing from 1st to 3rd character of the format string
<re_irc> <@whitequark:matrix.org> can you guess why?
<re_irc> <@thejpster:matrix.org> I think I might have one of the only projects where relocatable code makes sense on thumbv6m.
<re_irc> <@whitequark:matrix.org> everything else worked (until the code got complex), it was just the printf format strings that got offset
<re_irc> <@thejpster:matrix.org> did you relocate things out of alignment?
<re_irc> <@whitequark:matrix.org> no, but good guess!
<re_irc> <@whitequark:matrix.org> for some incomprehensible reason, binutils had .got and _GLOBAL_OFFSET_TABLE_ unhinge from one another, and it calculated some offsets off .got and some off _G_O_T_
<re_irc> <@whitequark:matrix.org> for some incomprehensible reason, binutils had .got and _GLOBAL_OFFSET_TABLE_ unhinge from one another, and it calculated some offsets off .got and some off _G_O_T_
<re_irc> <@dngrs:matrix.org> I would also have guessed alignment
<re_irc> <@whitequark:matrix.org> for some incomprehensible reason, binutils had .got and _GLOBAL_OFFSET_TABLE_ unhinge from one another, and it calculated some offsets off .got and some off _G_O_T_
<re_irc> <@dngrs:matrix.org> single backticks prevent matrix formatting
<re_irc> <@whitequark:matrix.org> and format strings were loaded using gotpcrel or something like that
<re_irc> <@dngrs:matrix.org> if that's what you're after
<re_irc> <@whitequark:matrix.org> so "_GLOBAL_OFFSET_TABLE_" would always be within .got+0 to .got+3, usually at least +1
<re_irc> <@whitequark:matrix.org> I never managed to figure out exactly why despite dedicating several days of full-time work to divining it out
<re_irc> <@thejpster:matrix.org> nightmare fuel
<re_irc> <@whitequark:matrix.org> I ended up writing a linker script pinning "_G_O_T_" to ".got" in the end
dc740 has joined #rust-embedded
<re_irc> <@thejpster:matrix.org> my worst ever compiler bug was testing function pointers for null-ness. I added some code and my DSP callbacks stopped working. I added _more_ code and it was fine. I took all the code out and it was fine. But adding just a couple of lines of code broke everything.
<re_irc> <@dngrs:matrix.org> inlining? :)
<re_irc> <@thejpster:matrix.org> This was a fully Harvard machine with 24-bit flash and 16-bit data. And NULL was defined as "(void*) 0".
<re_irc> <@whitequark:matrix.org> : the nightmare fuel for me was figuring out why exception handling segfaults. it turned out to be clang thinking a relocation is non-pc-relative and the linker thinking it was pc-relative, or something like that, and it only happened for shared objects
<re_irc> <@whitequark:matrix.org> what made it better was that gdb crashed trying to get a backtrace
<re_irc> <@whitequark:matrix.org> so I had to run gdb under gdb
<re_irc> <@thejpster:matrix.org> yo_dawg_meme.gif
<re_irc> <@whitequark:matrix.org> I got it all to work in about a week iirc
<re_irc> <@dngrs:matrix.org> I hope to never encounter any bug in this class ever
<re_irc> <@whitequark:matrix.org> honestly, I kind of like these
<re_irc> <@whitequark:matrix.org> at least it's not like one of the bugs a friend had to fix, which involved breaking the encryption on the vendor-shipped C code and then finding an exploit in their proprietary wireless stack to patch an issue in it or _something along those lines_
<re_irc> <@thejpster:matrix.org> If you were writing a compiler and you were comparing a 24-bit function pointer with a 16-bit data pointer (albeit the special case 0), would you expand the 16-bit value ... or would you truncate the top eight bits off the 24-bit value?
<re_irc> <@whitequark:matrix.org> or another of the bugs she had to fix that involved, as far as I remember, looking at silicon microphotography of a DSP chip to find out things the TI FAE would refuse to tell her
<re_irc> <@dngrs:matrix.org> : oof
<re_irc> <@whitequark:matrix.org> i once asked her if i can have source code for cortex-m and she wrote a decryptor for vivado protected files in like 15 minutes because after issues like _that_, it doesn't even register anymore
<re_irc> <@thejpster:matrix.org> turns out on that platform, ((void(_)(void) 0x030000) == (void_) 0.
<re_irc> <@whitequark:matrix.org> nice
<re_irc> <@whitequark:matrix.org> : that builds at least! thank you
<re_irc> <@thejpster:matrix.org> * ((void)(*)(void) 0x030000) == (void*)
<re_irc> <@whitequark:matrix.org> so target/thumbv7m-none-eabi/debug/ has the ELF file, do we have tools in Rust-land to turn it into something openocd can consume?
<re_irc> <@whitequark:matrix.org> or do I use objdump here until i or someone else figure out why probe-rs-cli crashes picoprobe?
<re_irc> <@whitequark:matrix.org> I kind of really want to recommend picoprobe but it is very definitely broken here
<re_irc> <@dirbaio:matrix.org> openocd can't read elfs? wat
<re_irc> <@whitequark:matrix.org> oh wait it can?
<re_irc> <@whitequark:matrix.org> live and learn
<re_irc> <@joelsa:fehler-in-der-matrix.de> : Yeah
<re_irc> <@whitequark:matrix.org> yea just looked it up
<re_irc> <@whitequark:matrix.org> : wait, sorry, was building the wrong file
<re_irc> <@whitequark:matrix.org> that does not seem to expose the DAC
<re_irc> <@dirbaio:matrix.org> did it get the "registers" key in build/data/chips/xxx.json?
<re_irc> <@whitequark:matrix.org> the JSON file in build/data/chips/ seems to have it yea
<re_irc> <@dirbaio:matrix.org> did you change stm32-metapac in both deps and build-deps?
<re_irc> <@whitequark:matrix.org> yep
<re_irc> <@dirbaio:matrix.org> :|
<re_irc> <@whitequark:matrix.org> and I'm fairly sure I'm using the right embassy-stm32
<re_irc> <@whitequark:matrix.org> I'm a little lost in all the metaprogramming here
<re_irc> <@whitequark:matrix.org> what's the path that DAC JSON entry takes from the JSON?
<re_irc> <@whitequark:matrix.org> okay yeah I rebuilt everything and the cargo build log shows the right metapac and embassy-stm32 checkouts
<re_irc> <@dirbaio:matrix.org> stm32-metapac-gen converts it into Rust code, puts it in the "METADATA" const
<re_irc> embassy-stm32 build.rs reads that and codegens stuff and defines some cfgs
<re_irc> main embassy-stm32 code uses that
<re_irc> <@dirbaio:matrix.org> it's somewhat cursed
<re_irc> <@whitequark:matrix.org> does it have like... debug flags?
<re_irc> <@dirbaio:matrix.org> no :(
<re_irc> you can inspect the generated stuff somewhere under target/
<re_irc> <@dirbaio:matrix.org> this should define "cfg(dac)" https://github.com/embassy-rs/embassy/blob/main/embassy-stm32/build.rs#L26
<re_irc> <@whitequark:matrix.org> the DAC doesn't have kind set to dac, it seems
dc740 has quit [Remote host closed the connection]
<re_irc> <@dngrs:matrix.org> dac tales, woohoooo
<re_irc> <@whitequark:matrix.org> or, wait, it doesn't have a registers block at all
<re_irc> <@whitequark:matrix.org> it just has pins, interrupts, dma_channels
<re_irc> <@whitequark:matrix.org> but it does have address?
<re_irc> <@dirbaio:matrix.org> if it doesn't have registers it means no rule in "perimap" matched
<re_irc> <@whitequark:matrix.org> ah!
<re_irc> <@whitequark:matrix.org> perimap could use a docstring, I think
<re_irc> <@dirbaio:matrix.org> the whole codegen thing could use some docs yep
<re_irc> <@whitequark:matrix.org> it does seem to be using DAC instead of DAC1
<re_irc> <@whitequark:matrix.org> for which there's a hack for DMA
<re_irc> <@whitequark:matrix.org> <IP ClockEnableMode="__HAL_RCC_DAC1_CLK_ENABLE" ConfigFile="DAC-STM32F3xx" InstanceName="DAC" Name="DAC" Version="F3_dacif_v1_1_Cube"/>
<re_irc> <@whitequark:matrix.org> like, here, it's just DAC and not DAC1
<re_irc> <@dirbaio:matrix.org> regex matches "CHIPNAME:PERINAME:VERSION"
<re_irc> <@dirbaio:matrix.org> btw you might want to join #embassy-rs:matrix.org (https://matrix.to/#/#embassy-rs:matrix.org) so we don't spam here too much
Dr_Who has joined #rust-embedded
Dr_Who has quit [Ping timeout: 258 seconds]