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
<re_irc> <aja23> Hi team, I'm still picking away at trying to get binary size down to fit into my device (4kB limit). Currently I have one big function taking 1.6 kB (the main), then some compiler_builtins.
<re_irc> File .text Size Crate Name
<re_irc> 0.4% 30.2% 1.6KiB lvl2serial_bootloader lvl2serial_bootloader::__cortex_m_rt_main0.2% 14.3% 770B compiler_builtins compiler_builtins::mem::memmove
<re_irc> 0.1% 6.0% 324B compiler_builtins compiler_builtins::mem::memcpy
<re_irc> <aja23> The other confounding issue is I have my project arranged as a workspace with a couple of different binary crates and a lib crate. This arrangment seems to make tools like objdump fall over :(, usually with an error about not having the package field filled
<re_irc> < (@9names:matrix.org)> use nm to determine initialiser sizes for your data
<re_irc> split your main up into smaller functions, check the size of those instead.
<re_irc> use objdump to disassemble to see how much code is generated from your code.
<re_irc> < (@9names:matrix.org)> at some level, if you want less code size you _must_ do less work
<re_irc> < (@adamgreig:matrix.org)> check you have lto=true and codegen-units=1 and incremental=false in your [profile.release] in Cargo.toml too
<re_irc> < (@adamgreig:matrix.org)> and try opt-level=z and s as well as 3
<re_irc> < (@9names:matrix.org)> i think we've already been over optimisations with aja23
<re_irc> < (@adamgreig:matrix.org)> ah, ok
<re_irc> < (@9names:matrix.org)> lto=fat is sometimes better too
<re_irc> < (@adamgreig:matrix.org)> at this point you might be down to looking at the disassembly and checking nothing looks silly and working out what each chunk of instructions is doing
<re_irc> < (@adamgreig:matrix.org)> true is the same as fat
<re_irc> < (@9names:matrix.org)> oh. right.
<re_irc> < (@adamgreig:matrix.org)> you can have off, false (thin local only), thin, and fat or true
<re_irc> < (@adamgreig:matrix.org)> false isn't the same as off but fat is the same as true :/
<re_irc> < (@9names:matrix.org)> > false isn't the same as off
<re_irc> wat 👀
<re_irc> < (@adamgreig:matrix.org)> yea lol https://doc.rust-lang.org/cargo/reference/profiles.html#lto
<re_irc> < (@adamgreig:matrix.org)> with codegen-units=1 then false and off are functionally the same
<re_irc> < (@9names:matrix.org)> okay. that's terrible, why on earth did they choose that for false :S
<re_irc> < (@adamgreig:matrix.org)> it seems ok? it's only inside the current crate, and fully off at opt-level 0 or codegen-units 1, so
<re_irc> < (@adamgreig:matrix.org)> it probably just results in "the normal optimisations you'd expect to happen"
<re_irc> aja23: if you could share your project you might be able to nerd-snipe someone into helping more directly
<re_irc> < (@9names:matrix.org)> oh, we only (briefly) covered the basics of optimisation options last time.
<re_irc> there's a few other tricks you can do, like using "panic_immediate_abort".
<re_irc> < (@adamgreig:matrix.org)> surprised there's no formatting bloat in there, which is usually what you get from panics
<re_irc> < (@9names:matrix.org)> yeah, agreed!
<re_irc> <aja23> There was formatting bloat at one point, then I did a cargo clean and it disappeared, still confused about that to this day, thanks guys. unfortunately I can't post the repo as it's a port of some C code from my work.
<re_irc> The thing with the huge main function is also a bit confusing to me, as main actually consists of a series of call outs to different functions initializing various peripherals. I assumed that the compiler had somehow inlined all of that and that's why I only see one function
<re_irc> <aja23> * core::fmt
<re_irc> < (@adamgreig:matrix.org)> yea, that's probably what's happened
<re_irc> < (@adamgreig:matrix.org)> you could stick "#[inline(never)]" on those functions to stop it
<re_irc> < (@adamgreig:matrix.org)> (but this will increase total code size a bit I expect, because of the extra overhead of the function call/return, unless you have a function getting inlined twice or something)
<re_irc> < (@adamgreig:matrix.org)> but at least you could get a feel for which functions are bigger or smaller
<cr1901> I have personally never seen lto=fat do worse for size than lto=thin, off, or false
<re_irc> <aja23> Anyway to dodge compiler_builtins for things like memmove? Seems like a pretty hefty function. I'm wondering if maybe trying to do away with any functions that consume rather than take by reference might help?
<cr1901> aja23: Copy these and see if it helps: https://github.com/cr1901/AT2XT/blob/master/Cargo.toml#L53-L56
<re_irc> <aja23> Yep, I've got all of those, currently have opt-level = 'z' which is giving me the best results size-wise
<cr1901> I wonder if libcore for cortex-m isn't built w/ lto=fat
<cr1901> I cannot promise this'll work, but... use the nightly compiler and pass "-Zbuild-std=core" to cargo
<re_irc> < (@9names:matrix.org)> > I'm wondering if maybe trying to do away with any functions that consume rather than take by reference might help?
<re_irc> > maybe? but you should check the disassembly first to see if that's what's happening.
<re_irc> < (@9names:matrix.org)> ->
<cr1901> This will build a shiny-new custom libcore for you with LTO enabled. IIRC, compiler builtins comes w/ it. It's been a while since I looked into this
<re_irc> <aja23> would love to, but haven't figured out to get objdump to work properly as it spits the error out about not having a package field, will see if I can get this going as it seems pretty key to me making further progress on understanding
<re_irc> < (@9names:matrix.org)> are you following the instructions from cargo-binutils?
<cr1901> (Just to correct myself, compiler_builtins isn't a dep of libcore; it's just injected into the dependency list of no_std apps: https://github.com/rust-lang/wg-cargo-std-aware/issues/77#issuecomment-980526914)
<re_irc> <aja23> yes, as far as I can tell
<re_irc> C:\WorkingFolderTemp\lvl2serial-rustport> cargo objdump --release -- --disassemble --no-show-raw-insn
<re_irc> error: missing field `package`
<re_irc> < (@9names:matrix.org)> that's strange... is there any error if you run "cargo objdump --release" or is it only when you try to disassemble?
<re_irc> <aja23> This issue I think might be relevant: https://github.com/japaric/cargo-call-stack/issues/29
<re_irc> <aja23> Specifically Hydra's last update in that thread
<re_irc> < (@9names:matrix.org)> ah, good to know. i don't use workspaces so i would not have hit this
<re_irc> < (@firefrommoonlight:matrix.org)> Wasn't expecting to see that name pop up on element!
<re_irc> < (@nihal.pasham:matrix.org)> *just an update*: so, I just learnt that "device-trees" do not contain register-level definitions (like svd files) but do contain "memory mapped" address info for *all* SoC peripherals . The best we can do is write a parser to quickly retrieve all "mmio peripheral addresses" (along with interrupt numbers and pincrtl names). guess that's better than digging through the data-sheets.
<re_irc> <aja23> turns out my cargo-binutils was years out of date
<re_irc> <aja23> the package in workspace thing was fixed in late 2019 lol
<re_irc> <aja23> hmm, lots of interesting stuff from objdump already, there are 3 implementations of unwrap in there
<cr1901> jamesmunns: The crate is working: https://github.com/cr1901/postcard-infomem
<cr1901> I'll write docs when I'm less tired. For a quickstart, these are the only changes I had to make: https://github.com/cr1901/AT2XT/compare/infomem
<re_irc> < (@luojia65:matrix.org)> I'm working with bouffalo again to provide official peripheral access crate
<re_irc> < (@luojia65:matrix.org)> RAL looks better, would use on next project
<re_irc> <aja23> question to check my understanding of the stm32 HAL, if I use the write function on a register, does it default to writing the reset value + whatever bits I chose to write?
<re_irc> <aja23> is the correct way to "update" a register with new flags to call modify and OR the bits from read part of the call?
<re_irc> <aja23> I ask because I'm poking through disassembly and the modify calls are noticeably heavier than the write calls
<re_irc> <aja23> question to check my understanding of the stm32 peripheral access API, if I use the write function on a register, does it default to writing the reset value + whatever bits I chose to write?
<re_irc> <aja23> And an extension question, is the following exactly the same as a write call?
<re_irc> rcc.cr.modify(|_, w| w.hsi16on().enabled());
<re_irc> < (@burrbull:matrix.org)> "modify" first read register value, then write modified value
<re_irc> < (@burrbull:matrix.org)> "write" writes precalculated constant
<re_irc> < (@burrbull:matrix.org)> "modify" first read register value, then writes modified value
<re_irc> < (@burrbull:matrix.org)> "write" writes precalculated value (usually constant)
<re_irc> <aja23> yep, but does "modify" remember the old bit values for bits you aren't explicitly updating if you don't call read.bits() | thenewvalue?
<re_irc> <aja23> Or in other words, in the snippet in my previous comment, will the value written to the register be the rest value + the hsi16on bit, or will it be the prior value of the register + the hsi16on bit?
<re_irc> <aja23> * reset
<re_irc> <aja23> given the closure only does anything with a writer, and by default the writers seem to just do reset value + new bit, I'd guess it will be the prior, i.e. there's no different between a write call and a modify call with an ignored reader (|_,w| ...)
<re_irc> < (@jannic:matrix.org)> IIRC they are different and your code is correct. Modify starts from the read value and only modifies the fields you actively write to.
<re_irc> < (@jannic:matrix.org)> No need to call read.bits() unless you actually need the value (eg. to increment some field)
<re_irc> <aja23> Just noticed more curiosity with compiler_builtins. I have two versions of memcpy (I think):
<re_irc> File .text Size Crate Name
<re_irc> 0.2% 14.3% 770B compiler_builtins compiler_builtins::mem::memmove
<re_irc> 0.2% 19.5% 1.0KiB lvl2serial_bootloader lvl2serial_bootloader::__cortex_m_rt_main
<re_irc> <aja23> hand rolled "dumb_memcpy" comes in at 28 bytes, absolute footgun I'm sure, I dropped it into my main and figured out that core::ptr::copy is what drags in mem::memmove, without I'm 700 B lighter
<re_irc> <aja23> +it
<Darius> memcopy and memmove have different semantics BTW
<re_irc> < (@diondokter:matrix.org)> Has anybody here written crates that use defmt, but also have unit tests that run on your PC?
<re_irc> I have, but it's not great. Can I get defmt to log to the console? Or is there at least a log implementation that at least makes it compile?
<re_irc> How do you guys do it?
<re_irc> <aja23> Darius: I understand, I'm pretty sure it's safe, I guess I could have changed that ptr:copy to ptr::copy_non_overlapping and got the same effect of getting rid of the memmove?
<Darius> aja23: not sure TBH I am a Rust noob, but basically just picking only one or the other where you can so it doesn't link in both
<re_irc> <aja23> Hah, just double checked the original linker file for the C code and realized I have 8K to to work with for the bootloader, not 4K
<re_irc> <aja23> almost got there too, got down to 4.5 K
<re_irc> <aja23> confirmed copy_nonoverlapping has the same effect of removing memmove from my binary, makes sense
<re_irc> < (@adamgreig:matrix.org)> Nice, seems neater than having to DIY your own memmove
<re_irc> < (@adamgreig:matrix.org)> Do you have a full vector table at the start of your code?
<re_irc> < (@adamgreig:matrix.org)> If you never use higher interrupts you can put code there instead to save space
<re_irc> < (@adamgreig:matrix.org)> It's a bit ⚠️⚠️⚠️ because if they interrupt did fire for some reason it would just jump to the whatever address your code happened to look like but especially on bigger chips with a hundred interrupts and each is 4 bytes...
<re_irc> <aja23> I'm not sure actually, I don't think so but the vector table is something I'm not sure I've ported correctly yet (thanks for reminding me!)
<re_irc> <aja23> it's an stm32l0x1 so pretty small chip as well
<re_irc> < (@adamgreig:matrix.org)> If you're using a pac crate it generally gets added automatically, but ah, an L0 probably has like 32 interrupts so only a hundred bytes or so
<re_irc> < (@adamgreig:matrix.org)> And you are more likely to be using them
IlPalazzo-ojiisa has joined #rust-embedded
Foxyloxy_ has joined #rust-embedded
Foxyloxy has quit [Ping timeout: 260 seconds]
<re_irc> < (@jamesmunns:beeper.com)> just to confirm, memcpy == ptr::copy, and memmove == ptr::copy_nonoverlapping, and that you can sub memmove for memcpy, but not the other way around
<re_irc> < (@jamesmunns:beeper.com)> (technically not ==, c's memcpy and memmove are based on byte sizes, while the ptr:: methods are based on elements of the pointer, but yeah)
<re_irc> I have a firmware .bin file, which is having "defmt::println!()" for debugging.
<re_irc> < (@anand21:matrix.org)> Hi All,
<re_irc> But it seems .bin file cannot be flashed using probe-run by which I can get my debug statements.
<re_irc> Is there any other way to get these debug statements? because I have the signed .bin file which needs to be debugged.
<re_irc> < (@ryan-summers:matrix.org)> defmt stores the actual strings in the ELF debug data headers, so you can't use a bin, as you can't match the defmt symbols to statements, right?
<re_irc> < (@jamesmunns:beeper.com)> .bin files don't typically contain debuginfo, while .elf files do
<re_irc> < (@jamesmunns:beeper.com)> (so yes, agree with ryan)
<re_irc> < (@ryan-summers:matrix.org)> Technically you could run it and collect the enums and such it's sending and replay it against some lookup table if you managed to collect debug info from the original ELF
<re_irc> < (@ryan-summers:matrix.org)> But if you could do that, you probably have the ELF, and would just flash that
<re_irc> < (@jamesmunns:beeper.com)> Yeah, I think there is some way to do post-parsing by piping into a cli tool that does have the elf file.
<re_irc> < (@diondokter:matrix.org)> Yep, that one is called defmt-print
<re_irc> < (@ryan-summers:matrix.org)> So the answer is yes, you can do this, as long as you also have the original ELF. If you don't have that, sounds like you're out of luck
<re_irc> < (@anand21:matrix.org)> : I have the original elf file, is there any reference on usage of defmt-print?
<re_irc> < (@jamesmunns:beeper.com)> so if you need to load a signed bin, you would:
<re_irc> - use something to get the rtt feed, there's an rtt-host binary in the probe-rs tools somewhere, this will output to stdout
<re_irc> - turn it into a signed bin, flash it
<re_irc> - build and make the elf, keep it
<re_irc> - pipe that into something like "defmt-print THE-FILE.elf"
<re_irc> < (@jamesmunns:beeper.com)> cargo embed might just work, if you configure it to use defmt transport, and tell it not to actually flash the elf file, but I haven't tried that
<re_irc> < (@ryan-summers:matrix.org)> I would assume probe-rs-cli has an RTT reader? Not sure
<re_irc> < (@ryan-summers:matrix.org)> If not... It probably should
<re_irc> < (@jamesmunns:beeper.com)> I've used https://github.com/probe-rs/probe-rs/tree/master/rtthost, it might be supersetted by probe-rs-cli (I haven't used the latter tool before)
<re_irc> < (@dirbaio:matrix.org)> there's "probe-rs-cli run"
<re_irc> < (@dirbaio:matrix.org)> does "flash, then run showing rtt/defmt output", similar to "probe-run"
<re_irc> < (@jamesmunns:beeper.com)> can you make it skip the flash step, like cargo-embed can?
<re_irc> < (@ryan-summers:matrix.org)> It sounds like they want to flash the bin anyways, so that might be a fine step
<re_irc> < (@jamesmunns:beeper.com)> actually, I thought probe-run had a no flash option?
<re_irc> < (@dirbaio:matrix.org)> : no :(
<re_irc> < (@jamesmunns:beeper.com)> --no-flash Skip writing the application binary to flash
<re_irc> < (@jamesmunns:beeper.com)> yes, actually?
<re_irc> < (@dirbaio:matrix.org)> : yes, but it refuses to --no-flash if you're using defmt
<re_irc> < (@jamesmunns:beeper.com)> oh
<re_irc> < (@jamesmunns:beeper.com)> that's silly
<re_irc> < (@ryan-summers:matrix.org)> But we don't want defmt here
<re_irc> < (@ryan-summers:matrix.org)> We want to just get raw RTT and pipe it to a file
<re_irc> < (@jamesmunns:beeper.com)> well, sort of
<re_irc> < (@jamesmunns:beeper.com)> if probe-run COULD skip flashing, and handles "getting rtt" and "decoding defmt" for you, that would be ideal
<re_irc> < (@anand21:matrix.org)> : I was hopeful with this. But it seems
<re_irc> anand@anand-VirtualBox:~/Desktop/dev_space/Prod/nrf_bootloader_example/rustBoot_forked/boards/sign_images/signed_images$ probe-rs-cli --help
<re_irc> probe-rs-cli have only following SUBCOMMANDS
<re_irc> Probe-rs CLI 0.12.0
<re_irc> < (@dirbaio:matrix.org)> you have to update it
<re_irc> < (@ryan-summers:matrix.org)> Yeah, latest definitely has run, I just downloaded and ran the help
<re_irc> < (@jamesmunns:beeper.com)> but it seems it doesn't, so we do need to do "get rtt" and "decode defmt" in two steps with two tools.
<re_irc> < (@dirbaio:matrix.org)> if the issue is you have to go through a ".bin" because you have to sign it
<re_irc> < (@dirbaio:matrix.org)> it seems easier to add a flag to the bootloader to not check signatures during development imo
<re_irc> < (@jamesmunns:beeper.com)> I think Anand was working on cursed bootloader/trustzone stuff, so I dunno how possible it is? But that would make dev easier
<re_irc> < (@dirbaio:matrix.org)> if you have the source to the bootloader you can do anything
<re_irc> < (@anand21:matrix.org)> Yes, I have tried that
<re_irc> --> Disabling the signature check in Bootloader.
<re_irc> But there is unexpected problem that needs to be debug.
<re_irc> --> when i dump the signed firmware (Checks are passed)
<re_irc> In that case the problem is not hitting. (Works as expected)
<re_irc> < (@anand21:matrix.org)> I will try with the "probe-rs-cli run "
<re_irc> < (@jamesmunns:beeper.com)> Another option (if you aren't drowning in them, or if using rtt is troublesome), you could also try using https://github.com/jamesmunns/defmt-bbq/, and writing defmt messages via UART or USB-Serial, and piping that into "defmt-print" instead.
<re_irc> < (@ryan-summers:matrix.org)> Alternatively you could just drop defmt and use normal logging to RTT
<re_irc> < (@jamesmunns:beeper.com)> so many options :D
<re_irc> < (@ryan-summers:matrix.org)> There's a cost overhead you pay, but that's probably the simplest
<re_irc> < (@anand21:matrix.org)> : Yeah I will have a look at this.
<re_irc> perhaps currently I don't care for the over heads. 🙂
<re_irc> < (@ryan-summers:matrix.org)> Logging overhead isn't awful tbh. In most cases it's not an actual problem. It will make your bin larger and have slight performance impact, but eh
<re_irc> < (@ryan-summers:matrix.org)> At least just to figure out what's going on here
<re_irc> < (@jamesmunns:beeper.com)> I think you are on an nrf91? which has a lot of flash and cpu iirc?
<re_irc> < (@anand21:matrix.org)> Yes
<re_irc> < (@jamesmunns:beeper.com)> but yeah, if you can swallow the 10-50k formatting cost (in flash), and a little more cpu and data transfer than defmt, logging is "just fine"
<re_irc> < (@jamesmunns:beeper.com)> tbh, 90% of the time I use defmt, it's just because it's easier to set up, rather than any perf or efficiency reasons :D
<re_irc> < (@ryan-summers:matrix.org)> Somewhat unfortunate that the tooling we have doesn't support this easily
<re_irc> < (@ryan-summers:matrix.org)> FWIW I don't think this would be hard to just add to the probe-rs-cli tool on your own
<re_irc> < (@jamesmunns:beeper.com)> Yeah, I'd consider reporting "probe-run --no-flash" not doing what we want here as a bug. do you know if there was a reasoning why somewhere?
<re_irc> < (@dirbaio:matrix.org)> because defmt will decode garbage if the flashed elf doesn't match the one provided to probe-run
<re_irc> < (@ryan-summers:matrix.org)> Maybe an extra --just-trust-me-i-know-what-im-doing flag
<re_irc> < (@dirbaio:matrix.org)> yeah.. footguns are useful for advanced use cases
<re_irc> < (@jamesmunns:beeper.com)> "--no-flash-unchecked" :p
<re_irc> < (@dirbaio:matrix.org)> probe-run seems very opinionated towards "no footguns"
<re_irc> < (@jamesmunns:beeper.com)> what _does_ it do in "no-flash" then?
<re_irc> < (@ryan-summers:matrix.org)> Alternatively, I imagine a power user could just modify probe-run to remove that check without too much effort
<re_irc> < (@jamesmunns:beeper.com)> here I go with my nop sled!
<re_irc> < (@dirbaio:matrix.org)> : non-defmt rtt
<re_irc> < (@jamesmunns:beeper.com)> ohhh
<re_irc> < (@jamesmunns:beeper.com)> so "probe-run --no-flash | defmt-print elf-file.elf" should work?
<re_irc> < (@dirbaio:matrix.org)> I think it still wants the .elf, and will error out because it'll see it has defmt
<re_irc> < (@jamesmunns:beeper.com)> ¯\_(ツ)_/¯
<re_irc> < (@dirbaio:matrix.org)> lol
<re_irc> < (@jamesmunns:beeper.com)> yeah, I get the reasoning, but yeah.
<re_irc> < (@dirbaio:matrix.org)> (╯°□°)╯︵ ┻━┻
<re_irc> < (@jamesmunns:beeper.com)> ┬─┬ノ(ಠ_ಠノ)
<re_irc> < (@jamesmunns:beeper.com)> (put that back for you, let's keep it orderly in here)
<re_irc> < (@alexmoon:matrix.org)> I use probe-run —no-flash all the time with defmt
<re_irc> < (@jamesmunns:beeper.com)> here I go with my nop sled!
<re_irc> edit: nop sled wasn't what I was looking for. I was joking about replacing the checks with nops instead
<re_irc> < (@alexmoon:matrix.org)> It used to error out but now it just warns you
<re_irc> < (@dirbaio:matrix.org)> ┬──┬ ¯_(ツ)
<re_irc> < (@dirbaio:matrix.org)> * ¯\_(ツ)
<re_irc> < (@dirbaio:matrix.org)> oh
<re_irc> < (@jamesmunns:beeper.com)> so uh, maybe try adding "--no-flash" to your ".cargo/config.toml" "runner" then?
<re_irc> < (@jamesmunns:beeper.com)> maybe it'll just work lol
<re_irc> < (@dirbaio:matrix.org)> if it just warns now, that was an unwarranted table flip :D
<re_irc> < (@yatekii:matrix.org)> heyhey, let's not go overboard here, table flips are always appropriate :P
<re_irc> < (@dirbaio:matrix.org)> I have 130 compiler errors like
<re_irc> help: consider `await`ing on the `Future`
<re_irc> |
<re_irc> --> |src/record.rs:630:49
<re_irc> < (@dirbaio:matrix.org)> yet "cargo fix" won't auto-apply these 130 fixes
<re_irc> < (@dirbaio:matrix.org)> even with "--broken-code"
<re_irc> < (@dirbaio:matrix.org)> is there any way to get it to do that?
<re_irc> < (@dirbaio:matrix.org)> I don't want to fix them all manually 😂
<re_irc> < (@jamesmunns:beeper.com)> Rust analyzer has some magical find/replace syntax, but I don't know it
<re_irc> < (@jamesmunns:beeper.com)> It might be faster to do it manually, find a nice YouTube video or podcast lol
<re_irc> < (@anand21:matrix.org)> : This is throwing following error
<re_irc> Running `probe-run --chip nRF9160_xxAA --no-flash /home/anand/Desktop/dev_space/Prod/nrf_bootloader_example/rustBoot_forked/boards/target/thumbv8m.main-none-eabihf/release/nrf9160_bootfw`
<re_irc> (HOST) WARN insufficient DWARF info; compile your program with `debug = 2` to enable location info
<re_irc> (HOST) INFO skipped flashing
<re_irc> < (@jamesmunns:beeper.com)> Turn on debug info, don't strip, maybe disable LTO?
<re_irc> < (@anand21:matrix.org)> Is it required to update the tool-chain?
<re_irc> < (@dirbaio:matrix.org)> this error usually means the firmware is not booting
<re_irc> < (@dirbaio:matrix.org)> some problem in the bootloader maybe
<re_irc> < (@dirbaio:matrix.org)> it doesn't get to boot, so it doesn't initialize the rtt control block
<re_irc> < (@dirbaio:matrix.org)> (or that it boots but crashes very very early before initializing it, but that's less likely in your case I guess)
<re_irc> < (@anand21:matrix.org)> But My FW leds are blinking.
<re_irc> < (@jamesmunns:beeper.com)> : I'm not sure what you mean by this
<re_irc> < (@anand21:matrix.org)> steps is followed.
<re_irc> - Compiled the FW
<re_irc> - flashed the .bin file using "probe-rs-cli download"
<re_irc> - now running the "probe-run --chip nRF9160_xxAA --no-flash" from my firmware
<re_irc> - Signed the FW --> got the signed.bin file
<re_irc> < (@jamesmunns:beeper.com)> That should be fine? As long as your signing tool doesn't modify the original elf
<re_irc> < (@jamesmunns:beeper.com)> And your original elf had debug info in it
<re_irc> < (@anand21:matrix.org)> Yes.
<re_irc> < (@jamesmunns:beeper.com)> do you know if Trustzone messes with debugger interactions?
<re_irc> < (@anand21:matrix.org)> : my probe-run version is
<re_irc> 0.3.0
<re_irc> supported defmt version: 3
<re_irc> probe-run --version
<re_irc> < (@jamesmunns:beeper.com)> Oh, I think there are newer versions which might help, but should work if your defmt dep in your app is also 0.3.0
<re_irc> < (@jamesmunns:beeper.com)> (toolchain usually refers to the set of tools you use for building your program, specifically in this case which versions of rustc/cargo you used)
<re_irc> < (@jamesmunns:beeper.com)> It's a vague word though, often misused :D
<re_irc> < (@yatekii:matrix.org)> : i would for sure expect it, but depends on what exactly is happening, but what's the context exactly?
<re_irc> < (@yatekii:matrix.org)> I have no experience with trustzone tho appart from the various talks I have heard about hacking it :D
<re_irc> < (@yatekii:matrix.org)> maybe the oxide folks have input here? :)
<re_irc> < (@dirbaio:matrix.org)> I think probe-rs hardcodes HNONSEC=0
<re_irc> < (@dirbaio:matrix.org)> so it does all accesses as S mode
<re_irc> < (@dirbaio:matrix.org)> but S mode can still read NS memory, so RTT to a NS binary should still work
<re_irc> < (@dirbaio:matrix.org)> I haven't _personally_ used it though :S
<re_irc> < (@dirbaio:matrix.org)> I've only used RTT to a S binary, so I can confirm that works, at least
<re_irc> < (@yatekii:matrix.org)> : yes :)
emerent has quit [Ping timeout: 246 seconds]
emerent has joined #rust-embedded
<re_irc> < (@chris_pwnorbitals:matrix.org)> Help us build the future of space exploration with solar sailing ! Embedded Systems Engineer position is open GAMA. Our flight software, as well as all ground support equipment and mission control software, is in Rust ! 😉 Feel free to apply ! https://gamaproject.notion.site/Embedded-Software-Engineer-M-F-eaf7a7c61f2b407185be9da85b826fa4
<re_irc> (mods : hope job postings aren't considered spam here, otherwise please direct me to a more relevant place 🙂 )
<re_irc> < (@dirbaio:matrix.org)> well that was painful https://github.com/Dirbaio/ekv/commit/b494ceaebe0b727aa39cc2faea39c1d94065fbab
<re_irc> <henrik_alser> 🍺
<re_irc> < (@dirbaio:matrix.org)> it's close to being done 🤩.. at least to the point I can ship it in my products (the "TODO soon" readme section)
<re_irc> <henrik_alser> Looking forward to trying it out
<re_irc> < (@dirbaio:matrix.org)> I wonder if there's interest in maintaining a blocking version as well?
<re_irc> < (@dirbaio:matrix.org)> should be just removing "async" and ".await" (and perhaps changes to how mutexes work at the top level struct?)
<re_irc> < (@jamesmunns:beeper.com)> the current "norm" is: posting it here is okay, as long as:
<re_irc> - don't do it too often (once/week is probably fine)
<re_irc> - it is actually an embedded rust position (you're good - you mention both in the offering)
<re_irc> < (@jamesmunns:beeper.com)> if we end up getting a LOT, we might do something about it, like asking folks to wait for the weekly meeting to "batch" them, or make a separate channel, but we're not close to there, IMO (we get a few a month, currently, if that)
<re_irc> < (@dirbaio:matrix.org)> not many rust embedded positions yet
<re_irc> < (@jamesmunns:beeper.com)> ehhhhh. I have feelings on this. It's not HUGE, relative to the number of all sw or even embedded or rust positions
<re_irc> < (@jamesmunns:beeper.com)> but it's not trivially small. Most companies are more quietly open than you would think
<re_irc> <Félix the Newbie> I've been a Rust dev at job for 2 years, and the only positions I've seen are in the Blockchain field.
<re_irc> <Félix the Newbie> No, once, I saw a web dev position
<re_irc> <Félix the Newbie> Never heard about an embedded one
<re_irc> < (@jessebraham:matrix.org)> Microsoft, Intel, Amazon, and Cloudflare are all using Rust. We use Rust at Espressif too (which is embedded). There are jobs out there.
<re_irc> < (@jessebraham:matrix.org)> It's still early, I think things will look much better in 5 years
<re_irc> < (@jamesmunns:beeper.com)> In general, my suggestions are:
<re_irc> - If you are open to a position, be as loud as you can (linkedin, etc.), I know this isn't always possible when already employed
<re_irc> - If you are an employer, be as loud as you can, and I (personally) or we (the embedded wg) will help signal boost as much as possible.
<re_irc> <Félix the Newbie> I don't really mind, I work in a blockchain company to up my Rust years count, but I'd like to work with embedded Rust in the future :)
<re_irc> <Félix the Newbie> I'm just afraid that the salaries are not the same.
<re_irc> < (@jamesmunns:beeper.com)> That being said: Ferrous grew a tremendous amount while I was there in "just" three years, and I've also been working solo for about a year now, and never had a shortage of work (that being said, I'm loud as hell, so people likely have heard/seen me around)
<re_irc> <Félix the Newbie> That's really great, Ferrous is an inspiring company.
<re_irc> < (@jamesmunns:beeper.com)> I haven't been involved with them for a year, but I certainly liked the folks that were there when I left, and they seem to keep doing cool things, which is nice to see :)
<re_irc> < (@dirbaio:matrix.org)> how high are embedded dev salaries nowadays?
<re_irc> < (@dirbaio:matrix.org)> and does embedded rust make for a higher salary?
<re_irc> < (@jamesmunns:beeper.com)> I can't comment much, as always, salaries are higher when working (or contracting for) folks in the US
<re_irc> < (@dirbaio:matrix.org)> yeah 😅
<re_irc> <Félix the Newbie> : What about the US, then? I work for an US company, so that I can compare
<re_irc> < (@jamesmunns:beeper.com)> In general, "ask for more than you think you could get away with", and "talk to other devs about your salary all of the time" are best practices.
<re_irc> < (@dirbaio:matrix.org)> I might open a position at Akiles soon
<re_irc> < (@dirbaio:matrix.org)> but i've never hired or worked as a firmware engineer
<re_irc> < (@dirbaio:matrix.org)> so I have no idea lol
<re_irc> <Félix the Newbie> : Yeah, that's why I'm asking you :P
<re_irc> < (@yatekii:matrix.org)> Hmm is there a way to say "static X goes to address Y" other than telling the linker which section the symbol goes in?
<re_irc> < (@jamesmunns:beeper.com)> I'm happy to privately share my rates, haven't commited to publishing them entirely, but not super against the idea.
<re_irc> THAT BEING SAID: I'm not sure if "the rate james charges for 2-12 week engagements for 'get started quick', 'expand rust to more folks in a team', 'review first project' or 'emergency diagnose some issue asap' rates transfer to general full time salaries :D
<re_irc> < (@dirbaio:matrix.org)> yeah, consulting/contracting is always quite higher than fulltime :D
<re_irc> < (@jamesmunns:beeper.com)> (usually 3x+, because you also cover your own taxes, insurance (health and business), operating costs, etc.)
<re_irc> < (@dirbaio:matrix.org)> plus you're senior-er
<re_irc> < (@yatekii:matrix.org)> james is more than senior imo :)
<re_irc> < (@dirbaio:matrix.org)> : no 💩
<re_irc> you can not make a static though, just cast int to pointer and use it
<re_irc> < (@dirbaio:matrix.org)> +just
<re_irc> < (@yatekii:matrix.org)> : hmm I want this nicely in a config lib tho, so I do not want the user to deal with pointers :)
<re_irc> < (@yatekii:matrix.org)> I will find a way :)
<re_irc> < (@yatekii:matrix.org)> maybe working with linker sections is the way anyways
<re_irc> < (@dirbaio:matrix.org)> then sections in linker script is the way yeah
<re_irc> < (@yatekii:matrix.org)> I want my tool to be able to load config fields from the ELF. that is what I am doing :)
<re_irc> < (@dirbaio:matrix.org)> O_o
<re_irc> < (@yatekii:matrix.org)> automatic provisioning baby :D
<re_irc> < (@yatekii:matrix.org)> no throwing around invalid memory locations to end up in a graveyard :D
<re_irc> < (@jamesmunns:beeper.com)> so, the COMPILER doesn't actually know/care where anything ends up in the binary
<re_irc> < (@jamesmunns:beeper.com)> only the linker does
<re_irc> < (@jamesmunns:beeper.com)> so the only way to "transfer" that knowledge is to have the compiler place that in a specific linker section, and have the linker place that somewhere specific
<re_irc> < (@yatekii:matrix.org)> yeah I know but since there is a way to tell the linker "go to section X" I thought maybe the same existed for a memory location.
<re_irc> < (@jamesmunns:beeper.com)> there's more or less one guaranteed level of "indirection" there
<re_irc> < (@yatekii:matrix.org)> yeah that's how I expected it. thanks :)
<re_irc> < (@jamesmunns:beeper.com)> nah, compiler doesn't deal with address placement at all. just linker section buckets.
<re_irc> < (@jamesmunns:beeper.com)> : y'all are crazy. there's no linear "seniority" scale. I'm just good at/familiar with a bizarrely wide set of things, including being very loud, which turns out to be useful in the specific kind of consulting I do :D
<re_irc> < (@yatekii:matrix.org)> : aka more than senior :) senior does not mean crazy math phd with insane domain specific knowledge ;)
<re_irc> < (@dirbaio:matrix.org)> so senior he's off the linear seniority scale
<re_irc> < (@dirbaio:matrix.org)> 😂
<re_irc> < (@chris_pwnorbitals:matrix.org)> : : well we're open to getting help with boosting the signal then, we're struggling to get good candidates :p
<re_irc> < (@jamesmunns:beeper.com)> Tag @rustembedded on twitter, use #rustembedded on cohost, do... something? on mastodon, add it to the wg newsletter, there are some monthly job postings on reddit, there are some other newsletters that handle general rust gigs, mention this at the end of the meeting or ask to add it to the announcement section of the meeting
<re_irc> < (@chris_pwnorbitals:matrix.org)> thanks for the tips, will do
<re_irc> < (@yatekii:matrix.org)> hmm is there even a way to have an uninitialized static in Rust, aka it maps directly to flash? I do not think so? Maybe this is even a bad idea for other reasons (e.g. cacheing)?
<re_irc> < (@jamesmunns:beeper.com)> make it "MaybeUninit"?
<re_irc> < (@jamesmunns:beeper.com)> you'll probably initialize it with "uninit" or "zeroed", in both cases it'll probably end up in ".bss".
<re_irc> < (@jamesmunns:beeper.com)> for "true" uninitialized memory, no, I think there's no sound way to do it in rust. panic-persist uses linker sections and does volatile reads/writes.
<re_irc> < (@yatekii:matrix.org)> hmm yeah, volatile reads/writes is what I was thinking of too. that makes the "read factory config schema from ELF" part trickier though
<re_irc> < (@jamesmunns:beeper.com)> cr1901 just did that yesterday
<re_irc> < (@jamesmunns:beeper.com)> he built the "config data" in a "build rs" with postcard, put it at a fixed location, so he could load it later with a tool
<re_irc> < (@jamesmunns:beeper.com)> He was loading build metadata (git sha, rust version, etc.), but you could do the same with any arbitrary data.
<re_irc> < (@jamesmunns:beeper.com)> If you want it to persist across many flashes, I'd probably say you'd want to either:
<re_irc> - Make a linker section, but don't have the app inhabit that section, and flash that section as a separate step at the factory
<re_irc> - Make two builds, one that does have some default value for that section, which you use for the factory, and a different build that doesn't, that you use for firmware updates or whatever
<re_irc> < (@jamesmunns:beeper.com)> sorta depends on what the "lifecycle" of that data is tho
<cr1901> https://github.com/cr1901/postcard-infomem I'll write docs soon
<cr1901> https://github.com/cr1901/AT2XT/compare/infomem Quickstart for those who can't wait
<cr1901> Arbitrary data would be interesting, but not currently in my plans.
<re_irc> < (@yatekii:matrix.org)> cr1901: how do you mean arbitrary data? :)
<cr1901> "Make the InfoMem struct generic over T, where T is your userdata"
<cr1901> right now it's not generic over anything
<re_irc> < (@jamesmunns:beeper.com)> That being said, the pattern right now is "build rs makes a binfile that happens to be postcard, that gets blindly included in the binary, which you can optionally put in a defined linker section, which you can also tie to a fixed location"
<re_irc> < (@jamesmunns:beeper.com)> if that's a suitable tl;dr
<cr1901> the linker section is optional, but defaults to ".info"
<re_irc> < (@yatekii:matrix.org)> I think I am stupid ...
<re_irc> < (@yatekii:matrix.org)> I was holding it wrong the entire time lol
<cr1901> you need to look at your microcontroller's documentation for the memory regions that are reserved for vendor info (if they exist)
<re_irc> < (@yatekii:matrix.org)> cr1901: yeah, but you can also just use regular flash :)
<cr1901> True, but you don't get around adding stuff to memory.x
<re_irc> < (@yatekii:matrix.org)> my issue is basically how I say "static X" points to memory "0xabcdef" in Rust where I fill that memory factory side :)
<re_irc> < (@yatekii:matrix.org)> cr1901: ah yes, that's true :) But I think that's perfectly fine :)
<cr1901> ".info : { KEEP(*(.info .info.*)) } > ROM" (not tested)
<re_irc> < (@yatekii:matrix.org)> I think embedded just requires linkerscript fiddling if you wanna do the fun stuff :)
<cr1901> static X: &[u8; INFOMEM_LEN] = &INFOMEM;
<re_irc> < (@yatekii:matrix.org)> yep :)
<cr1901> where INFOMEM gets defined in include_postcard_infomem!
<cr1901> yatekii: Honestly, if you have a branch you can make, I would appreciate you testing out my crate
<re_irc> < (@jamesmunns:beeper.com)> but yeah, there's no getting around using "link_section" and specifying the region in the linker script.
<cr1901> I'll answer q's as they come up in exchange for "no docs" right now
<cr1901> Also, having someone besides me test it can help shape the docs
<cr1901> jamesmunns: Willing to try testing the crate w/ some toy app you have on hand?
<re_irc> < (@jamesmunns:beeper.com)> cr1901: not today! But maybe in the future
<re_irc> <dngrs (spookyvision@{github,cohost})> : 5D senior
<cr1901> jamesmunns: Is it possible for a postcard data structure to have a header/magic constant (context- autofind the infomem if you only have a binary blob)?
<cr1901> If not that's fine
<re_irc> < (@yatekii:matrix.org)> cr1901: oh, are you in via IRC? :)
<cr1901> yes
<re_irc> < (@jamesmunns:beeper.com)> not as-is. You could do any of:
<re_irc> - Have a dummy field, like a fixed size u32, with a magic word in it
<re_irc> - Define your own serialization flavor, that includes the header magic automatically
<cr1901> flavors are unstable?
<re_irc> < (@jamesmunns:beeper.com)> flavors are stable
<cr1901> ahh okay
<re_irc> < (@jamesmunns:beeper.com)> (anything not in the "experimental" module is stable, that's only the schema stuff and MAX_SIZE stuff)
<re_irc> < (@yatekii:matrix.org)> hmm using postcard for this is interesting
<re_irc> < (@yatekii:matrix.org)> will give an architecture independent format
<re_irc> < (@jamesmunns:beeper.com)> yup! Just need to hold the "schema" stable.
<re_irc> < (@jamesmunns:beeper.com)> not a bad idea to have a fixed version string as the first field or similar, to at least detect mismatches.
<re_irc> < (@jamesmunns:beeper.com)> Serializing "(&str, ActualInfo)" as your "type" is also reasonable, since deser'ing just "&str" from that same data is guaranteed to be sound.
<re_irc> < (@yatekii:matrix.org)> ah, I have a tool to track the schema already :) just the definition part is a shitty UI atm and I would rather have the FW define it directly
<re_irc> < (@yatekii:matrix.org)> I need to figure how to read the schema from postcard tho :)
<re_irc> < (@jamesmunns:beeper.com)> (so you can read a schema "str" first, if it matches, then re-deser the whole tuple, or just deser the remainder bytes)
<re_irc> < (@jamesmunns:beeper.com)> ah, postcard is not a "self describing" format, so something like cbor or json might be better if you have a "true wild west" of values that might occur there.
<re_irc> < (@jamesmunns:beeper.com)> otherwise if you could use any other rust type, like "HashMap" or "enum"s or whatever, you could theoretically do it with postcard.
<re_irc> < (@yatekii:matrix.org)> : yes, that's fine :) but I somehow need to read the schema :) ahead of time :) I do not need a description during runtime tho as (JSON or similar do)
<re_irc> < (@jamesmunns:beeper.com)> in THEORY
<cr1901> I plan on making a reader app, but back compat aside from the reader app is not high-priority
<re_irc> < (@jamesmunns:beeper.com)> you could use https://docs.rs/postcard/latest/postcard/experimental/schema/index.html
<re_irc> < (@jamesmunns:beeper.com)> I don't know if those types impl "Serialize" yet, but they could.
<re_irc> < (@jamesmunns:beeper.com)> but it's not very ergonomic, you get a static recursive struct that describes the schema of a message format
<re_irc> < (@jamesmunns:beeper.com)> which you could then unbake into a dynamic gui or whatever
<re_irc> < (@jamesmunns:beeper.com)> but if you're uploading the whole schema to the device, it's gunna take a fair amount of space, but schema+message in postcard might be less than json
<re_irc> < (@jamesmunns:beeper.com)> if you wanna try it, happy to help hack on postcard enough to make it happen. Not out of the box supported today tho.
<re_irc> < (@jamesmunns:beeper.com)> Or, you could just "blindly" include the postcard message, and a SHA or ID that defines the schema used, and have your GUI support all known schemas. This is probably a better choice if the set of all schemas is fairly low
<cr1901> This silly little crate didn't take long, but... it took a surprising amount of energy to churn out
<cr1901> Having to impl Deserialize didn't help
<re_irc> < (@jamesmunns:beeper.com)> like:
<re_irc> let (schema, leftovers): &str, &[u8] = postcard::take_from_bytes::<&str>(buf).unwrap();
<re_irc> let buf: &[u8] = ...;
<re_irc> let data = match schema {
<cr1901> >then re-deser the whole tuple <-- what do you mean by this?
<cr1901> You can "back up" a deserializer?
<re_irc> < (@jamesmunns:beeper.com)> well
<cr1901> i.e. "put back" read chars
<re_irc> < (@jamesmunns:beeper.com)> in my example, doing the second deser with "buf", starts over. if you use "take_from_bytes" and then use "leftovers", you "pick up where you left off"
<re_irc> < (@jamesmunns:beeper.com)> it's two separate steps though. I'm abusing the fact that "(T, U)" in postcard is always specified as "the serialized value of T, then the serialized value of U, back to back".
<re_irc> < (@jamesmunns:beeper.com)> so "take_from_bytes<T>(buf)", "from_bytes::<U>(leftovers)" is well formed.
<cr1901> FWIW, my Deserialize impl is only for postcard (it only understands seqs)
<cr1901> it may impl Deserialize, but deserializing InfoMem from e.g. JSON is likely to fail
<re_irc> < (@jamesmunns:beeper.com)> citation: https://postcard.jamesmunns.com/serde-data-model.html#24---tuple
<cr1901> jamesmunns: In my example, InfoMem is a struct. But, #28 applies
<re_irc> < (@jamesmunns:beeper.com)> Actually, https://postcard.jamesmunns.com/wire-format.html#24---tuple is a better citation
<re_irc> < (@jamesmunns:beeper.com)> yeah, struct fields and tuple members are essentially serialized "the same".
<re_irc> < (@jamesmunns:beeper.com)> (structs are serialized "lexical definition order, top to bottom", while tuples are serialized "lexical definition order, left to right")
<re_irc> < (@jamesmunns:beeper.com)> though left/right top/bottom is mostly contextual. basically: postcard doesn't reorder fields like rust might for a repr(Rust) type.
<re_irc> < (@jamesmunns:beeper.com)> anyway I think I am just infodumping about the internals of postcard, so I'll stop :)
<re_irc> < (@jamesmunns:beeper.com)> cr1901: I have a thing for you, I hope you like it: https://github.com/cr1901/postcard-infomem/pull/1
loki_val has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
IlPalazzo-ojiisa has quit [Quit: Leaving.]