ChanServ changed the topic of #rust-embedded to: Welcome to the Rust Embedded IRC channel! Bridged to and logged at, code of conduct at
GenTooMan has quit [*.net *.split]
GenTooMan has joined #rust-embedded
<re_irc> <newam> macro_rules! const_concat_bytes {
<re_irc> const A: &[u8] = $a;
<re_irc> ($a:expr, $b:expr $(,)*) => {{
<re_irc> const B: &[u8] = $b;
<re_irc> <Kiran Shila> I hope this is the appropriate place, but I just finished up a new driver crate for a spankin-new power monitor IC from Microchip here:
starblue has quit [Ping timeout: 256 seconds]
starblue has joined #rust-embedded
explore has joined #rust-embedded
<re_irc> <sajattack> you can post it to if you feel so inclined.
emerent has quit [Ping timeout: 260 seconds]
emerent has joined #rust-embedded
explore has quit [Quit: Connection closed for inactivity]
_whitelogger has joined #rust-embedded
x56 has joined #rust-embedded
xnor has quit [*.net *.split]
hifi has quit [*.net *.split]
jr-oss_ has quit [*.net *.split]
re_irc has quit [*.net *.split]
re_irc has joined #rust-embedded
hifi has joined #rust-embedded
jr-oss has joined #rust-embedded
xnor has joined #rust-embedded
gsalazar has joined #rust-embedded
m5zs7k has quit [Ping timeout: 272 seconds]
m5zs7k has joined #rust-embedded
tokomak has joined #rust-embedded
starblue has quit [Ping timeout: 272 seconds]
starblue has joined #rust-embedded
<re_irc> <James Munns> So, I've been writing a little general purpose operating system, aimed at running on microcontrollers (currently targets the nRF52, because that's what I have around). It has hit a level of "actually works" where I'm ready to publish a v0.1.0 version, but I could use a little help with a name :)
<re_irc> I wrote up some context here:, if anyone has naming suggestions, feel free to reply or me here with your thoughts :D
<re_irc> <James Munns> (the code is here, if you're interested, though it's not particularly well documented yet, so you might want to wait until later in the week to take a peek!):
<re_irc> <James Munns> The kernel is built on top of RTIC, and the userspace communicates with the kernel via RPC, using serde+postcard
<re_irc> <MathiasKoch> I have something that looks like this (stm32l4xx-hal)
<re_irc> pub fn serial_isr(&mut self) {
<re_irc> // Check for character match
<re_irc> if self.rx.is_character_match(true) {
<re_irc> <MathiasKoch> I have something that looks like this (stm32l4xx-hal)
<re_irc> #[allow(non_upper_case_globals)]
<re_irc> SerialDmaPool: DMAFrame<32>
<re_irc> pool!(
<re_irc> <James Munns> Not too familiar with that chip, but if you haven't, it might be worth looking at the errata for your specific chip, to see if there is something there for it
<re_irc> <MathiasKoch> good idea 👍️
<re_irc> <James Munns> or, if it's something like "DMA is working on words instead of bytes, which means it re-reads the % 4 overflow"
<re_irc> <James Munns> (as blind guesses, with no actual context)
<re_irc> <James Munns> I've been bitten by little lines in reference manuals for stuff like "DMA must always be on word-aligned boundaries", and that causing all kinds of weirdness (because I didn't implement that in my driver)
<re_irc> <James Munns> Now my QSPI driver has lots of:
<re_irc> #[repr(align(4))]
<re_irc> struct AlignBuf {
<re_irc> bytes: [u8; 256]
<re_irc> <MathiasKoch> Is this the actual way to do this?
<re_irc> // 1. If DMA not done and there was a character match interrupt,
<re_irc> } else if character_match_interrupt {
<re_irc> // let the DMA flush a little and then halt transfer.
<re_irc> <yruama_lairba> It may worth to to write a function that return directly an aligned buffer of byte
<re_irc> <James Munns> I'm not actually sure. It did look a little sus, you might want to double check the impl vs the reference manual or what their C HAL does
<re_irc> <ryan-summers> I'm getting a strange HardFault with "cortex-m"'s "singleton!()" macro. The item stored in the singleton has a custom "Drop" implementation, and it looks like the initial singleton "None" value is getting dropped, but the "Drop" code is then run as if the "Option" had data, so the "Drop" code is then run on some uninitialized data. Given that the drop implementation uses references, that causes a ton of undefined...
<re_irc> ... references etc that are pointing to 0xFFFFFFFF
<re_irc> <ryan-summers> Anyone ever had any experience with this?
<re_irc> <ryan-summers> Hmm, looking at the latest cortex-m Singleton, it looks like there have been changes due to some niche optimization...
<re_irc> <yruama_lairba> niche optimization or niche fix ?
<re_irc> <ryan-summers> Not sure. In any case, with no unsafe code on my side, I'm getting some HardFaults, so _something_ is very wrong here
<re_irc> <tgomersall> Hi all, I'm hoping someone might be able to help me. I'm cross compiling code for a risc-v soft core which uses some custom operations. I've found a crate ( which implements those custom operations but I need to fix a few issues. Whilst working on these issues a few questions have arisen.
<re_irc> 1. The current design feature gates inline-asm. If inline-asm is not enabled (which is the default) then it uses some assembly from a pre-compiled blob. It seems strange to have this feature gate. Is this a legacy design from before the stabilisation of "asm!()"?
<re_irc> 2. Is it best to remove the pre-compiled assembly now that "asm!()" is stable?
<re_irc> 3. In the case of the pre-compiled assembly, the registers are hard coded (a0 and a1). Unlike the inline case, those registers are never specified as inputs or outputs so how does the compiler know to write to and read from those registers?
<re_irc> <ryan-summers> Hmm, seems my issues was caused by an old version of cortex-m - the latest 0.7 version does not produce the same issue
<re_irc> <korken89> MathiasKoch: I wrote that one in a long time ago
<re_irc> <korken89> The original issue what that if the memory bus was under heavy load the writes of the DMA could be delayed
<re_irc> <korken89> So the easiest was "to check a few times"
<re_irc> <korken89> This reduces the load on the memory bus and allows the DMA to do its writes
<re_irc> <korken89> And it worked in practice :)
<re_irc> <MathiasKoch> I guess that makes sense :)
<re_irc> Have you ever experienced the "race-condition" described in my OP?
<re_irc> <korken89> Hmm, not sure I need to find your message
<re_irc> <MathiasKoch> 13:06
<re_irc> <korken89> Ah
<re_irc> <korken89> I have never seen that happen
<re_irc> <korken89> Could be a race condition somewhere
<re_irc> <adamgreig> tgomersall: asm was only stabilised very very recently, before that (and still today) it was very common to ship pre-built binary blobs that egt linked against, yea
<re_irc> <MathiasKoch> Yeah, only thing is. i tried to wrap the entire "serial_isr" in " cortex_m::interrupt::free(|_| { .... }" but it still happens :/
<re_irc> <adamgreig> I would replace the inline-asm feature and pre-built blobs with asm!(), yes
<re_irc> <adamgreig> and the use of a0 and a1 is presumably (I'm not familiar enough with risc-v to say for sure) the platform ABI: in other words, the standard says that the first two arguments are placed into a0 and a1, so the compiler knows that's how to call the function
<re_irc> <korken89> MathiasKoch: I don't think it's a race condition as in the interrupts racing, more that the index handling might not "do the right thing" depending on how data comes
<re_irc> <MathiasKoch> That seems to fit with my observations
<re_irc> <korken89> I've not seen any issue though (I stress tested it over several days at maximum speed the UART could provide)
<re_irc> <korken89> But that is not a guarantee that it is correct
<re_irc> <MathiasKoch> with both character matching and receiver timeouts?
<re_irc> <korken89> Yeah
<re_irc> <korken89> We are heavily dependent on both in our product
<re_irc> <adamgreig> ryan-summers: hmm, troublesome, I guess it could be due to the niche change but I thought that was just to allow the static to go in bss, rather than as a bug fix
<re_irc> <ryan-summers> Yeah, the niche change doesn't seem present in the code that fixes it - that's all unreleased
<re_irc> <adamgreig> assuming you didn't have any uninit memory storing it that could have somehow ended up as the none niche :/
<re_irc> <adamgreig> hmm
<re_irc> <ryan-summers> But even the niche change doesn't have to do with "drop" semantics
<re_irc> <ryan-summers> Why would rust be calling "drop" on an "Option::None"?
<re_irc> <ryan-summers> Or rather, I guess it seems to be treating the "Option" as "Some", but the data is totally uninitialized
<re_irc> <korken89> MathiasKoch: If you find what's going wrong I can give some help in fixing it
<re_irc> <adamgreig> is the data in a memory section that should-but-isn't getting initialised / anything funky in your memory.x?
<re_irc> <adamgreig> especially 0.6->0.7 changed the linker script such that "INSERT AFTER .bss" which people used in slightly odd ways before changed behaviour iirc
<re_irc> <ryan-summers> Nothing fancy in this linker except adding a 1KB panic-persist page at the end of RAM
<re_irc> <ryan-summers> Otherwise just standard flash/data sections
<re_irc> <MathiasKoch> korken89: That sounds great. 👍️
<re_irc> Down the rabbit hole we go! I'll reach out if i figure something out.
<re_irc> Thanks
<re_irc> <adamgreig> ryan-summers: which version of cortex-m showed the problem?
<re_irc> <ryan-summers> I think it was 0.6.3 - I was specifically just constructing a list a "heapless::spsc::Queue<>" of Box<T> from heapless's "pool"
<re_irc> <korken89> MathiasKoch: Good luck!
<re_irc> <ryan-summers> Then the T impl'd Drop to return the T back to the pool
<re_irc> <ryan-summers> Let me see if I can get a minimal example going
<re_irc> <adamgreig> singleton itself doesn't seem to have changed at all so my suspicion is on the linker script I guess
<re_irc> <ryan-summers> Hmm. also very possible there's a stack overflow going on here
<re_irc> <ryan-summers> Aha, false alarm. Looks like there might be a stack overflow causing the singleton's static memory to get overwritten, so the drop logic thinks it's Some
<re_irc> <adamgreig> aha
<re_irc> <adamgreig> in embedded rust i guess stack overflow really should be first guess for mysterious memory issues :P
<re_irc> <adamgreig> I wish the stklim stuff had been added to armv7-m
<re_irc> <James Munns> I should probably have my OS move the app stack to the bottom
<re_irc> <James Munns> I already have the app memory region live at 0x2000_0000 for portability reasons, and the app has to declare a stack size, so I could totally do that in the linker script without flip-link
<re_irc> <MathiasKoch> korken89:
<re_irc> It seems to always correspond with this part:
<re_irc> Think i found something.
<re_irc> let diff = if len < got_data_len {
<re_irc> <korken89> Hmm
<re_irc> <korken89> Oh
<re_irc> <MathiasKoch> got_data_len 5, diff: 3
<re_irc> "b"\r\n+CG""
<re_irc> "b"+CGREG: 5,\"5A0C\",\"000B4AFB\",4,\"2""
<re_irc> <korken89> Hmm, I have to check the context
<re_irc> <korken89> Ahh yes
<re_irc> <korken89> I see the bug
<re_irc> <korken89> MathiasKoch: We don't remove "diff" from the length of this buffer:
<re_irc> <MathiasKoch> Ahh.. makes sense 👍️
<re_irc> <korken89> Nice catch
<re_irc> <korken89> * catch!
<re_irc> <MathiasKoch> What would the correct way of doing that be?
<re_irc> <MathiasKoch> given its a generic "BUFFER"
<re_irc> <tgomersall> adamgreig: Thanks!
<re_irc> unsafe { old_buf.set_len(got_data_len - diff) };
<re_irc> <korken89> Add this
<re_irc> <adamgreig> tgomersall: see for example in cortex-m a month or so ago
<re_irc> <korken89> I wonder how our testing did not catch that error..
<re_irc> <MathiasKoch> No idea, but that line seems to fix it 👍️
<re_irc> <korken89> Nice!
<re_irc> <korken89> Could you make a PR on that?
<re_irc> <MathiasKoch> Yeah, i will upstream it 👍️
<re_irc> <korken89> Thanks!
<re_irc> <korken89> As soon as CI passes I'll merge it
<re_irc> <korken89> Oh, could you update the CHANGELOG and bump the version number?
<re_irc> <korken89> I'll release it as well
<re_irc> <korken89> MathiasKoch:
<re_irc> <MathiasKoch> :+1
<re_irc> <korken89> * MathiasKoch
<re_irc> <korken89> Thanks!!
<re_irc> <MathiasKoch> patch should be alright, right?
<re_irc> <MathiasKoch> +bump
<re_irc> <MathiasKoch> * enough,
<re_irc> <korken89> Yeah
<re_irc> <korken89> MathiasKoch: Published 🎉
<re_irc> <riskable> Anyone have any suggestions for good ways to do inter-core communications via a fifo? I can send integers back and forth nooooo problem but what if I want to send structs? I'm using the multicore stuff in "rp-hal" BTW.
Rahix has quit [Quit: ZNC -]
Rahix has joined #rust-embedded
<re_irc> <newam> riskable: If you have w heap a VecDeque works well. You'll need to add a hardware mutex ontop of it though.
<re_irc> <newam> * a
tokomak has quit [Ping timeout: 240 seconds]
<re_irc> <riskable> newam: Well the problem is that "rp2040_hal::sio::Sio::SioFifo" only takes "u32" so I'd need to encode my structs somehow (I think). Or maybe there's a way I can setup a fifo that takes my own structs?
<re_irc> <newam> I'm unfamiliar with the RP2040, but if there is shared memory maybe you can pass pointers to a heap / static buffer via that fifo?
<re_irc> <riskable> newam: Yeah I have no idea how to do that, haha. I'm looking for examples/reference/documentation on how to do such a thing
<re_irc> <newam> There's also the channel that may be able to help you 🙂
<re_irc> <newam> riskable: Ahhh gotcha, let me see if I can find something
<re_irc> <riskable> This _should_ be relatively safe: "The plan" is to have one core do all the write operations (storing ADC values) and the other core only needs to be able to read them.
Amadiro__ has quit [Ping timeout: 240 seconds]
<re_irc> <riskable> That's neat: I made a mistake with my code that runs on the second core and it caused a panic... But because the panic was only on core1 (not core0) the rest of my code just kept chugging away 👍
<re_irc> <dirbaio> riskable: make a "static QUEUE: Mutex<heapless::Deque<MyStruct, 16>>"
<re_irc> <riskable> dirbaio: Haha that's exactly what I did... I got it working 👍
<re_irc> <dirbaio> * Mutex<RefCell<heapless::Deque<MyStruct, 16>>>"
<re_irc> <dirbaio> and make sure you're using the multicore-safe critical_section impl
<re_irc> <riskable> Well I just used a Deque on one core and send the values one-at-a-time through the fifo and just counted them with a start and end value
<re_irc> <dirbaio> ah
<re_irc> <dirbaio> you can actually touch the queue from both cores
<re_irc> <dirbaio> just make sure to use "critical_section::with()" instead of "cortex_m::interrupt::free()"
<re_irc> <riskable> dirbaio: (and everyone else) this is the gist of the multi-core code:
Amadiro has joined #rust-embedded
<re_irc> <dirbaio> ah you're building a separate FW for each core?
<re_irc> <dirbaio> it's much easier if you build a single FW
<re_irc> <dirbaio> that makes it so that all "static"s are shared between both cores
<re_irc> <dirbaio> so you can push values from core0, pop values from core1
<re_irc> <dirbaio> works with arbitrary Rust structs
<re_irc> <dirbaio> no need to use SIO FIFO at all
<re_irc> <riskable> dirbaio: Oh I didn't know you could just declare a static up top and then access it from both cores. haha
<re_irc> <riskable> dirbaio: No, this code is all in the same Not separate firmwares.
<re_irc> <dirbaio> ah okay!
<re_irc> <dirbaio> then yup, "static"s are shared
<re_irc> <dirbaio> just like they're shared across two threads in "std" targets :D
<re_irc> <riskable> Haha I thought the "SioFifo" was _literally_ the only mechanism I had to pass messages between cores 😄
<re_irc> <riskable> Regardless, I made that work anyway haha
<re_irc> <GrantM11235> riskable: In that case, you may want to try something like "heapless::spsc" (
<re_irc> <riskable> GrantM11235: Yeah that's ultimately what I ended up using: heapless::spsc::Queue