emerent has quit [Killed (platinum.libera.chat (Nickname regained by services))]
emerent_ is now known as emerent
<bartmassey[m]>
Henk and I are thinking about an update to Rust Disco Book for MB2. Expect a bunch of stuff from us once Winter Break has passed.
<bartmassey[m]>
Belated thanks to everyone for the DTS/SVD info. I think I can see my way to maybe doing something with this fancy RISCV-64 chip on the Milk-V someday when I have time.
<M9names[m]>
<thejpster[m]> "That book is probably due an..." <- it's likely also due for a review and discussion on what the content of the book should look like 2024.
<M9names[m]>
> This project is developed and maintained by the Resources team.
<M9names[m]>
does this mean that someone would have to be on the Resources team to do this update?
<bartmassey[m]>
It has a fancy parser derive macro thing for input. But I'm off-topic, apologies
<bartmassey[m]>
On-topic, I've started working with Henk on Embedded Rust Course Notes, and it has turned into an mdbook. Will make public shortly after break when it's not a barely-started eldritch abomination anymore.
<bartmassey[m]>
I think my strat is to get that in shape, then see about the MB2 Disco Book and see what can be moved in there.
Guest7282 has joined #rust-embedded
Guest7282 has left #rust-embedded [Error from remote client]
marmrt[m] has quit [Quit: Idle timeout reached: 172800s]
djdisodo[m] has joined #rust-embedded
<djdisodo[m]>
i'm dealing with tiny ram(2048 bytes) on arduino uno, also as far as i know .data section loads up to SRAM before main starts
<djdisodo[m]>
and i found that .data section is full of strings that are probably for error messages, but i think these values should be constant, why are these loaded onto sram?
<djdisodo[m]>
that is quite painful since this kind of strings are using 1037 bytes worth of space now
<djdisodo[m]>
not all error message live in .data and some live in .LOAD tho
<djdisodo[m]>
* not all error message live in .data and some live in LOAD(code space) tho
<M9names[m]>
AVR is a harvard architecture. code and data address spaces are separate.
<M9names[m]>
for data (like strings) to be usable they have to be in RAM. that's just how it goes.
<djdisodo[m]>
M9names[m]: > <@9names:matrix.org> AVR is a harvard architecture. code and data address spaces are separate.
<djdisodo[m]>
> for data (like strings) to be usable they have to be in RAM. that's just how it goes.
<djdisodo[m]>
i think they can load right before use rather than loading them before main entry
<M9names[m]>
in theory, yes, that is possible, and the C SDK has a bunch of machinery to make that easier but it's still a manual process to store a string in PROGMEM and a special version of printf that will do the copy first
<djdisodo[m]>
M9names[m]: some of strings are in LOAD space so i think it's just that compiler decides
<djdisodo[m]>
is there any way to make compiler prefer PROGMEM
<M9names[m]>
i don't think so. how would it know what should live there and what should not?
<djdisodo[m]>
M9names[m]: if it's const or static, it's read only so put in progmem
<djdisodo[m]>
if it's static mut put in ram
<M9names[m]>
if it's const it's put directly where it's used.
<djdisodo[m]>
yes
<djdisodo[m]>
but i really think that strings are const, why would they be anything else?
<M9names[m]>
<djdisodo[m]> "if it's const or static, it's..." <- the problem is that both the C and Rust memory model assume that all memory is addressable. that isn't true for you, PROGMEM is on a completely separate bus from your RAM.
<M9names[m]>
so if the compiler automatically put things in PROGMEM you would immediately run into hard to debug errors, because your code would have pointers that don't actually point to your data.
<M9names[m]>
also those pointers to strings also have to live in RAM to be used even though they are const - same reason as above.
<djdisodo[m]>
ok
<M9names[m]>
those "error messages" in your screenshots are panic messages. i don't think there's any easy way to tell them where to live.
<M9names[m]>
you can get LTO to remove them if you use panic-immediate-abort
<djdisodo[m]>
oh
<M9names[m]>
you can find more avr-specific help in #avr-rust_Lobby:gitter.im. it's a pretty small community though, so answers might take a while
<djdisodo[m]>
tha sounds great tho maybe i should use simavr with mcu that has bigger ram when i need to enable panic message when i need to debug
Guest7282 has joined #rust-embedded
<djdisodo[m]>
rando thought but if i put #[inline(always)] on panic handler won't string be inlined as well?
IlPalazzo-ojiisa has joined #rust-embedded
<djdisodo[m]>
<M9names[m]> "those "error messages" in your..." <- > <@9names:matrix.org> those "error messages" in your screenshots are panic messages. i don't think there's any easy way to tell them where to live.
<djdisodo[m]>
> you can get LTO to remove them if you use panic-immediate-abort
<djdisodo[m]>
i used panic_halt and it eliminated most of them but there's still some which is from .expect("");
<Noah[m]1>
does anyone know if I can const transform (no runtime code) a `&'static str` into a `[u8; 128]`? I realize that the sizes might not match. in that case I would like to add this just the length the str has, but then still make the array in the struct that size.
<JamesMunns[m]>
`[u8; 128]` or `&[u8; 128]`?
<JamesMunns[m]>
and where are you getting the str from? `include_str!()`? Noah
<Noah[m]1>
JamesMunns[m]: nope, array, not slice, so `[u8; 128]`
<Noah[m]1>
JamesMunns[m]: from a string literal :)
<Noah[m]1>
thanks so much man! I will give it a go :)
<Lumpio[m]>
const fns can do surprising things already but it feels pretty... manual
<Noah[m]1>
yeah, I think it's fair to let the user know in the docs. worst case the string that is displayed is crooked.
<JamesMunns[m]>
so, probably you need to decide:
<JamesMunns[m]>
* do you stick with utf-8, and truncate early correctly
<JamesMunns[m]>
* do you stick with ASCII/c-strings, ensure everything is an ascii character (and replace non ascii chars), and ensure there's a zero terminator or something
<Lumpio[m]>
We have copy_from_slice but nooo it's not const implement memcpy by hand instead
<Noah[m]1>
I think the spec might suggest only ASCII is allowed since it tailors to C
<JamesMunns[m]>
There's a fun double trick you can do for turning include_bytes or include_str into arrays with compile time decided len, too
<Noah[m]1>
uii
<Noah[m]1>
yeah, I mean the flash algo api is up for debate :)
<Noah[m]1>
but so far it made a nice improession :)
<Lumpio[m]>
Noah @yatekii:matrix.org: Why not do a year of ruet adventures as a job
<JamesMunns[m]>
oh, for that it probably needs to be static TOML_ARR not const TOML_ARR, but works the same
<JamesMunns[m]>
This is pretty useful if you have some sort of header or metadata you can calculate in a build-rs, drop it to the filesystem, then include_bytes it into a specific flash location
<JamesMunns[m]>
useful for things like git hashes, tho not for CRC32 and such, as build-rs runs BEFORE compiling the binary.
<Lumpio[m]>
post_build.rs when
<Lumpio[m]>
...why does Element mobile think that is a domain name, it's not even valid
<JamesMunns[m]>
Lumpio[m]: doesn't help if you need the data AT build time :D
<JamesMunns[m]>
yeah, that's why I type build-rs lol
<Lumpio[m]>
A post_build.rs could maybe edit your binary afterwards to add a crc or whatnot
<adamgreig[m]>
For the short string can you just have something like `static X: [u8; 12] = *b"hello world";`?
<adamgreig[m]>
Not sure if there's an easy way to pad it out without writing the 0s though, I usually handled that separately when needed
<JamesMunns[m]>
Yeah, my tricks are specifically for when you are using a variably sized payload. Agreed you can do that if you know the existing size
<JamesMunns[m]>
no way to zero-fill tho, afaik
<JamesMunns[m]>
(other than using a const-fn, like I did)
<Noah[m]1>
<Lumpio[m]> "Noah @yatekii:matrix.org: Why..." <- if you wanna pay for it :)
<Noah[m]1>
<JamesMunns[m]> "This is useful because if you..." <- hmm I might need that, I am not sure
<Noah[m]1>
<adamgreig[m]> "For the short string can you..." <- ah lol true! but how would you zero pad that? :)
<Noah[m]1>
ah james already mentioned it :)
<Noah[m]1>
ofc :D
<Noah[m]1>
everybody giving me hard imposter syndrome
<adamgreig[m]>
Depends why it needs padding, could just manually write some extra \x00 or otherwise I'll often do the padding in firmware if it's just like "need to transmit 128 bytes starting with this string from flash", I'll transmit string then 128-len 0s or whatever. If you need a mutable buffer pre-init with some string at the start and the rest 0s it doesn't really work, james' const fn is best then I think
IlPalazzo-ojiisa has quit [Read error: Connection reset by peer]
IlPalazzo-ojiisa has joined #rust-embedded
hifi has left #rust-embedded [#rust-embedded]
AdrianGeipert[m] has quit [Quit: Idle timeout reached: 172800s]
<Noah[m]1>
<adamgreig[m]> "Depends why it needs padding..." <- yeah but here we need to basically fulfil the CMSIS-DAP standard :)
<Noah[m]1>
So I cannot just model it however I like :)
<Noah[m]1>
what the duck, copilot can autocomplete my complete macro syntax that I just wrote ...
danielb[m] has joined #rust-embedded
<danielb[m]>
sponsored by Big Macro?
<danielb[m]>
copilot is usually good enough with figuring out regularities so I guess this is some nice extra
Guest7282 has left #rust-embedded [Error from remote client]
<PeterHansen[m]>
<thejpster[m]> "Seems unlikely. Does objdump..." <- There are no functions there. I just checked and it's actually in the area allocated to HEAP. Target is thumbv7em-none-eabihf. Is it safe to say that one would expect that PC could *never* be in RAM in any normal code?
<diondokter[m]>
PeterHansen[m]: It could, but it's not common
<JamesMunns[m]>
it does seem unlikely. AFAIK nothing by default does that.
<JamesMunns[m]>
If you did have some kind of stack or other data corruption, it's possible you corrupted something else tho
<JamesMunns[m]>
like, if you are doing some UB somewhere else, and it corrupted some value, you could end up in the wrong place. Do you have a small example that reproduces this just by printing the None like you mentioned earlier?
<JamesMunns[m]>
and if so: could you post that full setup somewhere? like a GH repo other people could compile and debug? you're certainly seeing something very weird, outside of something we could probably wildly guess at
<PeterHansen[m]>
Note that the hardfault occurs only when I do anything that tries to format! an Option that is a None. Not a Some. And by checking the stack a bit it seems that it is indeed occurring in the midst of it attempting to format an Option, and looks like it's trying to grow a Vec in the middle of that. It's nearly certain this is nothing I'm doing wrong... but I'm still trying to reduce this to code that someone else could run
<PeterHansen[m]>
that reproduces this. It's one of those problems where just changing the layout of the code by removing stuff seems to affect it.
<JamesMunns[m]>
PeterHansen[m]: are you maybe overflowing your stack while growing the vec?
<PeterHansen[m]>
Definitely not.
<JamesMunns[m]>
or, is your heap misconfigured and corrupting your stack?
<diondokter[m]>
It's on the heap, right? Could you increase the heap size?
<PeterHansen[m]>
At this point I'm doing little more than initializing Embassy, spawning two tasks that both then sleep forever, and doing these formats. Unfortunately if I try to strip all the other code out, even though it's not being called, it can make the problem vanish, so I'm still working on that reduction.
<JamesMunns[m]>
i'd be interested in how you setup your heap, and what your linker script looks like
<PeterHansen[m]>
HEAP is 128K, but this is the first and only thing being allocated now.
<diondokter[m]>
PeterHansen[m]: Ah, then the size not an issue
<PeterHansen[m]>
HEAP setup is the generic embedded-alloc setup.
<PeterHansen[m]>
I'll continue working to reduce this (not my first rodeo), but I did just want confirmation that a PC in RAM is simply wrong... i.e. there's no chance that a compiler optimization, or memcpy implementation could be running self-generated code in RAM.
<JamesMunns[m]>
So you're doing the exact thing in this example?
<PeterHansen[m]>
In this case, now that I've noticed the address is in my heap, I think it's safe to say that's simply not possible.
merFurkanDemirci has quit [Quit: Idle timeout reached: 172800s]
<PeterHansen[m]>
Yes, identical to that, modulo the fact I have the code spread across more modules and lots of irrelevant stuff still being compiled and linked in, even though it's no longer called.
Guest7282 has left #rust-embedded [Error from remote client]
<diondokter[m]>
Is it always the same PC address?
<diondokter[m]>
If so, maybe you can find the jump by using a conditional watchpoint on the PC in GPB.
<diondokter[m]>
This is super mega awfully slow, but it might help
<diondokter[m]>
s/GPB/GDB/
<JamesMunns[m]>
> there's no chance that a compiler optimization, or memcpy implementation could be running self-generated code in RAM
<JamesMunns[m]>
I have never heard of Rust doing that ever, no. If you are running code in Ram, you'd know (and have to set it up yourself)
<PeterHansen[m]>
I had originally mentioned this in this channel several months ago, before I'd discovered it was a hard fault. At the time I meant to post in the embassy channel because I thought it likely it was related to that somehow. Then yesterday I posted in the embassy channel asking for helping analyzing hard faults, but shortly after I realized this is likely nothing to do with embassy (when I narrowed it down to Option::None debug
<PeterHansen[m]>
formatting). What I originally found when I first posted is the same now though: this fails with 2023-08-09 or later, but works fine with 2023-08-08 or earlier. And always the same address, same stack trace.
<PeterHansen[m]>
diondokter: I could probably do that, but I have no GDB-fu... never used it.
<diondokter[m]>
PeterHansen[m]: Mine is bad too, but with a bit of google-fu it's doable
<JamesMunns[m]>
Formatting is somewhat interesting in that it uses dynamic dispatch. It could be a miscompilation of that. The code will still be in flash, but the vtable will be in RAM.
<PeterHansen[m]>
I got as far yesterday as running probe-rs gdb, then running gdb and trying some attach statement that appeared to connect to the probe-rs process, but at that point I had no idea what to do next... so in theory if that would be the best way to proceed, with a little guidance I could do it.
<PeterHansen[m]>
That said, when I first brought this up someone suggested a rustc bisect procedure. At the time it was infeasible for me since reproducing this required an awkward procedure, but now that I know it's a hard fault I can get instant positive indication of the failure so bisect is an option. Especially if I don't have to automate it... I assume I can give manual input to the procedure.
<PeterHansen[m]>
James Munns: But the address is in my HEAP, 4 bytes after the start. I think the vtable would be in data somewhere, not heap.
<JamesMunns[m]>
yeah, I mean something has gone terribly wrong
<JamesMunns[m]>
the vtable itself wouldn't end up in the LR
<PeterHansen[m]>
Does cargo bisect-rustc require using a script, or can you give manual input? If script, I guess I just need to make a dummy script that waits for me to enter a response, while I take the generated code and download elsewhere (different host... compile on fast laptop, deploy from raspberry pi with SWD hooked up).
<PeterHansen[m]>
Unfortunately I have a family matter to deal with until Tuesday so I'll need to park this very shortly, but I appreciate all suggestions.
<PeterHansen[m]>
(For more context, in addition to embassy-nrf, I still have nrf-softdevice linked in and am using its critical-section impl, but because I have almost no real code running it is not initializing the SoftDevice or using any peripherals, or really anything except some embassy_time timers, and rtt-target with an up and down channel initialized (but only output being used actively).)
<JamesMunns[m]>
I think it's reasonable to bisect rustc (not sure on your question), but also reasonable to ensure your code is not doing any UB, or something that would otherwise corrupt the running state of your processor.
<PeterHansen[m]>
Pretty sure I have no UB or unsafe code being actively called here, though some could theoretically still be in what's linked but not executed.
<diondokter[m]>
Yeah, embassy might. It's very good, but not always perfect ;)
<PeterHansen[m]>
of my own that is... there are still lots of outside crates being linked in too, though again very little code being executed now.
<diondokter[m]>
Maybe compare the generated assembly yourself between the two compiler versions?
<PeterHansen[m]>
also using opt_level "z". I tried with all others and none fail except "s", so it could be related to s/z optimization.
<PeterHansen[m]>
diondokter: umm. very good thought. Wish I'd had it. :)
<PeterHansen[m]>
diondokter: There are very significant differences in the compiler builtin aeabi_memset routine, which is the one that appears to be causing the hard fault... interesting.
<diondokter[m]>
Huh
<JamesMunns[m]>
what's the date on the first broken nightly?
<PeterHansen[m]>
The one before that works is rustc 1.73.0-nightly (03a119b0b 2023-08-07)
therealprof[m] has quit [Quit: Idle timeout reached: 172800s]
<PeterHansen[m]>
(Caveat re my comment above about optimization levels: I don't really believe it's related to that... I think it's just that those rearrange the code in such a way that it can cause/remove the failure, just as removing some of my code that isn't even being called can remove the failure... Link order etc shifting things around in memory perhaps.)
<PeterHansen[m]>
Anyone have caveats about running rustc-bisect in a WSL2 (Windows System for Linux) debian host? I've never built rustc or anything like that before...
<PeterHansen[m]>
James Munns: Yes, when I first brought this up several months ago I had identified there was a major change there. I noticed it because my code size had also changed relatively significantly between the two nightlies.... like 1-2K on a 200K code base, which I found a tad surprising.
<JamesMunns[m]>
I wonder if something the memcpy is pulling from is not aligned
IlPalazzo-ojiisa has quit [Quit: Leaving.]
<JamesMunns[m]>
you'd get a different unaligned fault, but if that was unhandled it might escalate to a hardfault?
<JamesMunns[m]>
you probably don't have a specific unaligned fault handler
<PeterHansen[m]>
James Munns: The hard fault register output seemed to me to imply it wasn't an alignment issue, since I think there's a different bit set for that than INVSTATE. The page I was looking at suggested INVSTATE was only (or primarily?) when the low bit of the address wasn't set or was set incorrectly for a Thumb instruction or something like that.
<diondokter[m]>
Might fall under the memfault exception?
<diondokter[m]>
You might be able to enable stuff with that
<JamesMunns[m]>
Can you try adding a handler for UsageFault specifically?
<adamgreig[m]>
invstate might make sense if somehow pc was loaded with a ram address that didn't have lsb set
<adamgreig[m]>
like someone really messed up a branch
<PeterHansen[m]>
James Munns: If I do that with the generic HardFault handler in place it gives the same failure as before. I can try removing that and leaving just yours.
<adamgreig[m]>
you want to have the UsageFault and you also need to enable usagefault not escalating to hardfault iirc
<PeterHansen[m]>
Yeah, with just that UsageFault but not enabling anything it goes to HardFault still.
<PeterHansen[m]>
Is INVSTATE a configurable UsageFault? I had the impression only alignment and another were configurable.
<PeterHansen[m]>
or is the idea that an alignment issue may not immediately cause the failure, so enabling the usage fault may show a more localized source for the failure?
<adamgreig[m]>
I don't think enabling usagefault handling will change anything significant, right now if it's generating a usagefault due to invstate it's just immediately escalating to the hardfault handler
<adamgreig[m]>
if the fault status register says it was an escalated usagefault, you can still read the usagefault bits out of cfsr I believe
<JamesMunns[m]>
yeah, my hope was to see if it was some other fault that was being escalated to a hardfault
<PeterHansen[m]>
I would have thought that would still leave the other bit set in the CFSR. This has only the one bit.
<adamgreig[m]>
yea, CFSR has the INVSTATE bit set then it was a UsageFault, and HFSR has FORCED set then it escalated usagefault to hardfault since usagefault handling wasn't enabled
<JamesMunns[m]>
I'm certainly not an expert! I'd trust Adam's knowledge over mine :D
<adamgreig[m]>
if you set USGFAULTENA in SHCSR I'd expect it to start calling the UsageFault handler
<adamgreig[m]>
but I don't think that would tell you anything new, the question is why did pc get loaded with an address from sram that happened to not have the LSb set? maybe?
<adamgreig[m]>
does that actually trigger INVSTATE or does only BX style instructions do it though...
<JamesMunns[m]>
ah, but I see what you are saying, the UNALIGNED flag isn;'t set but the INVSTATE flag is
<JamesMunns[m]>
so even if we get a specific usagefault handler, that doesn't change the fact we didn't get triggered by an UNALIGNED read
<PeterHansen[m]>
I guess I have to have it do a build then somehow wait for feedback while I install it and run it.
<adamgreig[m]>
if you've already bisected it to a specific nightly I don't know how much you'll learn from rustc-bisect
<adamgreig[m]>
especially when that nightly includes a "bump llvm version" commit :p
<PeterHansen[m]>
It says if its within the last 167 nightlies it will automatically bisect on the PRs.
<adamgreig[m]>
could you see what's in memory at that 0x20005044 address?
<PeterHansen[m]>
adamgreig: It's just 4 bytes into my HEAP, presumably the first thing allocated.
<PeterHansen[m]>
I assume as soon as I format!() it's beginning to build a string in allocated space.
<adamgreig[m]>
wonder what instruction it disassembles into
<PeterHansen[m]>
ah
<adamgreig[m]>
but it does sorta depend what else is going wrong and how pc was loaded
<adamgreig[m]>
the other thing maybe worth doing is putting a breakpoint just before things go bad and single-stepping instruction by instruction until the fault
<PeterHansen[m]>
would it be that location, or one word before or after perhaps?
<adamgreig[m]>
it should be that location
<adamgreig[m]>
the 16 or 32 bits starting there, anyway
<adamgreig[m]>
but yea, if you can get a gdb session going, i'd be trying to single step into the failure, then you'll see exactly what code loaded a ram address into pc and can hopefully work backwards a bit
<PeterHansen[m]>
Those are different locations from before, but 52bc is equivalent to the old one... HEAP is at 52b8.
explodingwaffle1 has joined #rust-embedded
<explodingwaffle1>
<PeterHansen[m]> "I seem to be missing something..." <- > <@peter9477:matrix.org> I seem to be missing something about how rustc-bisect works. If I just run it with the two known bounds `cargo bisect-rustc --start=2023-08-08 --end=2023-08-09` then it just outputs this and bails:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/BoUefXvZfekhkhDSSpluxhkD>)
<PeterHansen[m]>
So that first word is "None"... as expected I guess.
<PeterHansen[m]>
So just after the memcpy as before.
<PeterHansen[m]>
I suppose dumping regs and analyzing the memcpy code could give a hint what happened, but at that point I suppose single-stepping to it may make more sense. I'd need to learn some gdb then...
<diondokter[m]>
Hmmm, probably best to get the debugger, set a breakpoint on that bl instruction and then step into it and see what it does
<diondokter[m]>
Works in vscode with the cortex-debug plugin as well
<diondokter[m]>
Don't have to use GDB cli
<PeterHansen[m]>
Anyway, very unfortunately I really have to bail for today and tomorrow for a family matter. Much thanks for the input.
<dirbaio[m]>
do you have a self-contained repro?
<PeterHansen[m]>
Not yet. As mentioned I can so far only get it to fail by including a fair chunk of code, even though I've carefully neutered all of it. I have to spawn() two different tasks at the moment, and even though each has a "sleep forever" at the start to prevent anything from running, I still need to include their actual code, and much of what they would call, in order to trigger the failure.
<PeterHansen[m]>
So taking out the spawns, or removing the code following the sleep-forever, makes it go away. That's why I assume it's related to link order etc rather than my actual code for the most part.
<dirbaio[m]>
no unsafe?
<PeterHansen[m]>
I tried starting fresh with a cortex-m-rt-quickstart yesterday but that didn't fail. Will need to continue trying to strip down my own stuff apparently.
<dirbaio[m]>
have you checked whether your stack is overflowing?
<PeterHansen[m]>
No unsafe. Literally almost nothing left except (a) initialize HEAP and RTT and embassy, (b) spawn two tasks that just sleep, and (c) format! a None.
<PeterHansen[m]>
Stack usage is probably about 200 bytes or something... no chance I'm dealing with stack or RAM issues like that.
<PeterHansen[m]>
MSP : 0x2003f840
<dirbaio[m]>
oh wel
<dirbaio[m]>
* oh well
<PeterHansen[m]>
My top of stack is 0x2003FC00
<dirbaio[m]>
if you post a repro I'll take a look
Orange_Murker[m] has quit [Quit: Idle timeout reached: 172800s]
<PeterHansen[m]>
Thanks. Okay, gotta bail. Not back at this until tomorrow night at earlier. :(
<PeterHansen[m]>
s/earlier/earliest/
Tyalie7098[m] has quit [Quit: Idle timeout reached: 172800s]
firefrommoonligh has quit [Quit: Idle timeout reached: 172800s]
crabbedhaloablut has quit []
Guest7282 has left #rust-embedded [Error from remote client]