GenTooMan has quit [Ping timeout: 256 seconds]
GenTooMan has joined #rust-embedded
Amanieu has joined #rust-embedded
starblue has joined #rust-embedded
emerent has joined #rust-embedded
<re_irc> <@j​ohn_socha:m​> henrik_alser: Thanks. I'll work on making it more idiomatic, which of course that means I have to learn what that looks like.
fabic has joined #rust-embedded
tokomak has joined #rust-embedded
<re_irc> <@j​ohn_socha:m​> eldruin: Thanks. That's something I wanted to do, so having the link you provided will help me get there.
GenTooMan has quit [Ping timeout: 240 seconds]
GenTooMan has joined #rust-embedded
dcz has joined #rust-embedded
neceve has joined #rust-embedded
fabic has quit [Ping timeout: 268 seconds]
fabic has joined #rust-embedded
fabic has quit [Ping timeout: 258 seconds]
<re_irc> <@j​duchniewicz:m​> How welcome would be having `Backtrace` in core compared to current implementation in std? I am working on a RFC( which tackles this and has a proposed implementation where you have to provide your own backtrace hook (akin to panic one) or you will be provided with...
<re_irc> ... a compiler generated one.
<re_irc> <@j​duchniewicz:m​> The most important question is: where and how would be backtraces used in embedded contexts? So far we have discussed that they would be probably used for automated testing/bug reporting on platforms that can afford to allocate some memory for a backtrace and debug symbols. The discussion happens in this...
<re_irc> ... zulip stream:
fabic has joined #rust-embedded
<re_irc> <@e​ldruin:m​> jduchniewicz: I think that discussion would benefit from having its own issue in the [WG repo]( and probably also from discussion in our weekly meetings (Tuesdays 20:00h CEST)
<re_irc> <@e​ldruin:m​> PSA: `embedded-hal` `0.2.6` is out:
<re_irc> <@d​irbaio:m​> I imagine backtraces in core would add quite a bit of bloat if you need the whole unwinding code and symbol table with full strings
<re_irc> <@j​duchniewicz:m​> they don't need to be symbolized at the time of capturing
<re_irc> <@j​duchniewicz:m​> unwinding is a valid argument though
<re_irc> <@j​duchniewicz:m​> also symbols could be stored in external memory and pulled in when needed
<re_irc> <@j​duchniewicz:m​> citing nagisa from zulip:
<re_irc> <@j​duchniewicz:m​> >With frame pointers enabled (which I believe is typically true on thumb) the unwinding is just chasing a pointer in a linked list. Along with storing the chain somewhere else that'd be a couple hundred bytes if written with care.
<re_irc> <@j​duchniewicz:m​> so it seems like there is no big bloat entailed
<re_irc> <@d​irbaio:m​> Ahh, just collect an array of PCs and ship it to the server
<re_irc> <@d​irbaio:m​> That's quite Interesting
<re_irc> <@d​irbaio:m​> In my project I'm shipping the top 8kb of stack 🤣
<re_irc> <@r​yan-summers:m​> Don't know if already mentioned, but is quite a nice read
<re_irc> <@d​irbaio:m​> is there a way to get rustfmt to format all .rs files in a repo?
<re_irc> <@d​irbaio:m​> `cargo fmt` starts in the crates's and discovers all other files from `mod` declarations
<re_irc> <@d​irbaio:m​> but embassy is full of cfg's, and it doesn't have a single workspace for all crates
<re_irc> <@d​irbaio:m​> so it's missing many files :|
<re_irc> <@d​irbaio:m​> `find -name '*.rs' | grep -v stm32-data | xargs rustfmt --check --skip-children --unstable-features --edition 2018`
<re_irc> <@d​irbaio:m​> this is horrible lol
<re_irc> <@j​beaurivage:m​> Oof
<re_irc> <@j​beaurivage:m​> If there isn't a cargo native way to do it I would just use an Invoke task
<re_irc> <@r​icharddodd:m​> also file an issue, I think this is a common use-case
tokomak has quit [Ping timeout: 258 seconds]
dcz has quit [Ping timeout: 245 seconds]
fabic has quit [Ping timeout: 258 seconds]
<re_irc> <@d​irbaio:m​>
<re_irc> <@d​irbaio:m​> "Rustfmt formats programs rather than files" 🤷‍♂️
<re_irc> <@r​yan-summers:m​> I would comment on that issue with your usecase. It seems to me like the original person that closed the issue didn't really give it a lot of thought. The other alternative is to run rustfmt with all configurations
<re_irc> <@r​yan-summers:m​> Which would likely be very un-fun
<re_irc> <@r​yan-summers:m​> But I think rustfmt may actually not work if your code doesn't compile - it may very well _require_ that the rs files be part of the build to format them properly
<re_irc> <@d​khayes117:m​> I use IntelliJ Idea Community with the rust plug-in to handle my reformatting. Several configurations possible and works well.
fabic has joined #rust-embedded
<re_irc> <@n​ewam:m​> ryan-summers: Oooo that is so exciting.
<re_irc> <@n​ewam:m​> I have been dabbling with async, but the big incomplete warning on GATs turned me off of async traits.
<re_irc> <@n​ewam:m​> I'll have to try it out again 😀
<re_irc> <@n​ewam:m​> Are there any plans for async traits in `embedded-hal` when it can be done without nightly?
<re_irc> <@l​achlansneff:m​> Tada!
<re_irc> <@n​ewam:m​> That's excellent!
<re_irc> <@n​ewam:m​> it would be nice to have an `async` RNG trait, IIRC `rand_core` has no plans for `async`.
<re_irc> <@l​achlansneff:m​> Really, they don't?
<re_irc> <@l​achlansneff:m​> Huh
<re_irc> <@n​ewam:m​> Hmmm, that might be me misremembering though, I can't find any recorded conversation of that, no mention of `async` on github.
<re_irc> <@e​ldruin:m​> haha nice turn of events. We are removing the rng traits in `e-h` 1.0 in favor of `rand_core`
<re_irc> <@n​ewam:m​> I'll open up an issue asking what the plans are for `rand_core` with `async`.
<re_irc> <@e​ldruin:m​> awesome, I was going to suggest that
fabic has quit [Ping timeout: 258 seconds]
neceve has quit [Ping timeout: 258 seconds]
<re_irc> <@d​irbaio:m​> What's the use case for async rng?
<re_irc> <@d​irbaio:m​> HW rng is not that slow
<re_irc> <@n​ewam:m​> fair point.
<re_irc> <@n​ewam:m​> Let me get some numbers on the STM32WL RNG.
<re_irc> <@d​irbaio:m​> And you can also seed a csprng from the hwrng and then use that, so you wait for cpu instead of for hw
<re_irc> <@d​irbaio:m​> Not sure which would be faster
<re_irc> <@n​ewam:m​> is that secure enough for cryptographic use? Not an expert in that area.
<re_irc> <@d​irbaio:m​> Yeah it's secure as long as you seed it properly
<re_irc> <@n​ewam:m​> huh, good to know!
<re_irc> <@d​irbaio:m​> Cs in csprng stands for Cryptograpically Secure after all 😜
<re_irc> <@n​ewam:m​> Yeah the STM32WL RNG is pretty slow, 2662-2692 CPU cycles to generate one block of 4x u32, CPU at 48MHz, RNG at 48MHz (both max)
<re_irc> <@n​ewam:m​> wait... not release mode, let me re-run
<re_irc> <@n​ewam:m​> mmm same results
<re_irc> <@l​achlansneff:m​> Is that instruction blocking?
<re_irc> <@l​achlansneff:m​> Or rather, does it stall the cpu
<re_irc> <@n​ewam:m​> Yup.
<re_irc> <@n​ewam:m​> Though that is also the cold-boot numbers, it is a lot faster on the second block.
<re_irc> <@n​ewam:m​> that's more reasonable, at steady state it goes at the advertised 412 cycles per block.
<re_irc> <@n​ewam:m​> Still HW limited in that case though
<re_irc> <@l​achlansneff:m​> How could it be made async in that case?
<re_irc> <@n​ewam:m​> There's a hardware interrupt that fires when a new block of entropy is available.
<re_irc> <@n​ewam:m​>
<re_irc> <@n​ewam:m​> Opened an issue there, hopefully I explained it well.
<re_irc> <@d​irbaio:m​> heh, for non-embedded users it's a tough sell, RNGs are usually cpu-bound
<re_irc> <@d​irbaio:m​> CSPRNGs are just cpu calculations, reading from /dev/urandom (or the new getrandom()) never blocks..
<re_irc> <@d​irbaio:m​> embedded is quite unique in having a "coprocessor" that can do RNG while the core does other things
<re_irc> <@n​ewam:m​> Speaking of that do you have any suggestions for a `#![no_std]` CSPRNG crate?
<re_irc> <@n​ewam:m​> I am curious how many cycles it takes vs HW
<re_irc> <@n​ewam:m​> Oh, huh, `rand` is actually `no_std` compatible.
<re_irc> <@n​ewam:m​> I always thought it was `std`, and `rand_core` was the only `no_std` crate.
<re_irc> <@d​irbaio:m​> for pure SW I guess
<re_irc> <@d​irbaio:m​> that's the one I'm using
fabic has joined #rust-embedded
<re_irc> <@d​irbaio:m​> There's also ChaCha8/ChaCha12, there's a [paper]( claiming 20 rounds are overkill and 8 should be enough but I think it's somewhat debated (?)
<re_irc> <@d​irbaio:m​> not sure if even chacha8 will beat 412cycles/block
<re_irc> <@d​irbaio:m​> and it certainly won't win in code size :P
fabic has quit [Ping timeout: 252 seconds]
<re_irc> <@n​ewam:m​> CPU cycles to generate 1 block (`[u32; 4]`)
<re_irc> <@n​ewam:m​> Cha12: 22,646
<re_irc> <@n​ewam:m​> Cha20: 35,329
<re_irc> <@n​ewam:m​> Cha8: 16,304
<re_irc> <@d​irbaio:m​> oh wow, RIP
<re_irc> <@d​irbaio:m​> HW is sooo much faster haha
<re_irc> <@n​ewam:m​> Yeah, that's quite a bit more than I was expecting
<re_irc> <@d​irbaio:m​> built with release, lto, flash cache/accelerators enabled?
<re_irc> <@j​orgeig:m​> dirbaio: bare metal ftw!
<re_irc> <@n​ewam:m​> OH, good point, my dev build doesn't have all the acceleration enabled and this is entirely CPU, one sec.
<re_irc> <@n​ewam:m​> New numbers with all the optimizations (whoops):
<re_irc> <@n​ewam:m​> Cha8: 1,093
<re_irc> <@n​ewam:m​> Cha20: 2,568
<re_irc> <@n​ewam:m​> Cha12: 1,585
<re_irc> <@d​irbaio:m​> ahh :)
<re_irc> <@d​irbaio:m​> when you want RNG for crypto networky shit you usually want only 32-64 bytes (so 2-4 blocks)
<re_irc> <@d​irbaio:m​> and an async context switch probably takes more than 1000-2000 cycles
<re_irc> <@d​irbaio:m​> so blocking is probably faster than async
<re_irc> <@n​ewam:m​> dirbaio: I actually have not measured this yet; does async take longer than a normal RTOS?
<re_irc> <@n​ewam:m​> I was guessing that it would be a lot faster since there is usually less to save/restore without preemption.
<re_irc> <@d​irbaio:m​> I haven't measured anything, no
<re_irc> <@n​ewam:m​> I guess this also depends on the executor and how feature-rich it is though. Adding task priority can eat up quite a few cycles.
<re_irc> <@d​irbaio:m​> when awaiting the entire "call stack" returns, and has to be "called" again when polling the future again
<re_irc> <@d​irbaio:m​> so for very deep call stacks it might be slower than rtos
<re_irc> <@d​irbaio:m​> lke
<re_irc> <@d​irbaio:m​> if you have a deep future stack
<re_irc> <@d​irbaio:m​> f1, f2, ... f99
<re_irc> <@d​irbaio:m​> when polling, f1.poll() calls f2.poll() calls f3.poll() ... calls f99.poll()
<re_irc> <@d​irbaio:m​> and if f99 awaits something then the entire stack returns Poll::Pending and has to be called again on next poll
<re_irc> <@d​irbaio:m​> while a stackful RTOS would "jump" directly into f99 code when resuming a thread
<re_irc> <@d​irbaio:m​> OTOH for shallow future stacks async might be faster
<re_irc> <@d​irbaio:m​> it'd be cool to measure
<re_irc> <@d​irbaio:m​> and also if futures in the stack are "dumb" the compiler will probably inline them, so dunno
<re_irc> <@n​ewam:m​> What is a good way to measure this on a Cortex-M?
<re_irc> <@n​ewam:m​> Hmmm, now I am curious.
<re_irc> <@n​ewam:m​> When I have done this in the past it has been with a high speed trace.
<re_irc> <@n​ewam:m​> probably adding some code to the executor and sampling the cycle counter at a few key places?
<re_irc> <@d​irbaio:m​> maybe
<re_irc> <@d​irbaio:m​> or queue 2 futures, sample cycle counter at one, then yield, then at the other
<re_irc> <@d​irbaio:m​> that'd measure the entire "end-to-end" cycles of a switch
neceve has joined #rust-embedded
<re_irc> <@n​ewam:m​> Wow, that is a lot more cycles than I expected to switch.
<re_irc> <@n​ewam:m​> ```rs
<re_irc> <@n​ewam:m​> 2075 cycles for two empty tasks.
<re_irc> <@n​ewam:m​> static mut ONE: u32 = 0;
<re_irc> <@d​irbaio:m​> huh
<re_irc> <@d​irbaio:m​> ```rust
<re_irc> <@d​irbaio:m​> tasks: BTreeMap<TaskId, Task>,
<re_irc> <@d​irbaio:m​> task_queue: Arc<ArrayQueue<TaskId>>,
<re_irc> <@d​irbaio:m​> pub struct Executor {
<re_irc> <@d​irbaio:m​> no surprises, it uses BTreeMap and Arc
<re_irc> <@n​ewam:m​> I did say less than optimal 😀
<re_irc> <@d​irbaio:m​> what mcu are you testing on?
<re_irc> <@n​ewam:m​> STM32WL5x, using the Cortex-M4 (it has a CM0+ as well) at 48MHz
<re_irc> <@e​ldruin:m​> newam: Very interesting numbers! have you had a look at [wyrand](
<re_irc> <@d​irbaio:m​> that's not cryptographically secure though
<re_irc> <@n​ewam:m​> Yeah unfortunately this is for generating a nonce, so I need it to be secure
<re_irc> <@n​ewam:m​> That looks neat though, I'll save it for later 😀
<re_irc> <@n​ewam:m​> async context switch performance round 2
<re_irc> <@n​ewam:m​> Please correct me if I am using this wrong, have not used embassy much.
<re_irc> <@n​ewam:m​> ```rs
<re_irc> <@n​ewam:m​> This time with embassy.
<re_irc> <@n​ewam:m​> Also for good measure the non-async version (running both functions after each other) is 4 cycles.
<re_irc> <@d​irbaio:m​> 62 only? yay :D
<re_irc> <@d​irbaio:m​> you're using the raw task API, the highlevel one is `#[embassy::task] async fn sample1() {..` then you can spawn them with `spawner.spawn(sample1_task())`
<re_irc> <@d​irbaio:m​> but it should be equally fast
<re_irc> <@n​ewam:m​> dirbaio: Ran it again with the changes, 62 cycles again.
<re_irc> <@n​ewam:m​> That's rather impressive.
<re_irc> <@d​irbaio:m​> :D
<re_irc> <@d​irbaio:m​> it's the best case though, cycle count will increase as you nest futures
<re_irc> <@n​ewam:m​> Yeah, it's a good benchmark for minimum overhead though.
<re_irc> <@n​ewam:m​> I'm glad I measured, going to stay far, far away from that BTree executor.
<re_irc> <@n​ewam:m​> Huh, 62 cycles actually really good on the do-nothing benchmark scale.
<re_irc> <@n​ewam:m​> FreeRTOS quotes 84 for a minimum context switch on an M3. [source](
<re_irc> <@n​ewam:m​> Anecdotally Zephyr was low hundreds last time I used it (though they have been working on improving performance)
<re_irc> <@r​iskable:m​> Is there a way to `cargo embed` without flashing first?
<re_irc> <@j​amesmunns:m​> You mean view the rtt logs?
<re_irc> <@r​iskable:m​> Yeah
<re_irc> <@j​amesmunns:m​> there's a CLI tool for that, I think in the rtt-println repo
<re_irc> <@j​amesmunns:m​> looking for it now...
<re_irc> <@j​amesmunns:m​> `rtthost`
<re_irc> <@j​amesmunns:m​> I can't remember where it lives...
<re_irc> <@j​amesmunns:m​>
<re_irc> <@j​amesmunns:m​> `rtthost` folder
<re_irc> <@j​amesmunns:m​> example usage:
<re_irc> <@j​amesmunns:m​> ```bash
<re_irc> <@j​amesmunns:m​> rtthost --chip nRF52832_xxAA --scan-region 0x20000000..0x2000FC00
<re_irc> <@j​amesmunns:m​> though, nowadays you might be able to just make cargo embed do this without another tool :D
<re_irc> <@j​amesmunns:m​> yatekii would know better :)
<agg> With embed you can disable flashing in embed.toml
<agg> (or make a second profile that just does rtt etc)
<re_irc> <@j​amesmunns:m​> 🤦‍♂️
<re_irc> <@r​icharddodd:m​> Right I'm going on holiday next week. My holiday project is to write a blog post about why Rust embedded is so awesome/how it will be even more awesome in the future/how accessible it is. Posting this here in the vain hope that it will make me feel accountable and therefore more likely to actually complete...
<re_irc> ... it.
<re_irc> <@a​lmindor:m​> what's the process for fixing something in a PAC when the SVD is missing ? e.g. in this case the reset value is not defined in the SVD, should I add it in code, expand the svd itself?
<re_irc> <@a​lmindor:m​> s/SVD is missing/SVD is missing the part/
<re_irc> <@n​ewam:m​> For the STM32 SVD the `stm32-rs` repo contains a TON of patches to fix bugs in the vendor SVD, you add in in a YAML file and it gets applied when the SVD is generated.
<re_irc> <@n​ewam:m​> Find your device in that directory and go from there. There is some shared patches for things that impact multiple devices.
<re_irc> <@f​irefrommoonlight:m​> You need to edit the YAMLs using a donain-specific language. I'm new to it, but may be able to help if you have questions
<re_irc> <@f​irefrommoonlight:m​> As you've found out, the SVDs are full of errors
<re_irc> <@n​ewam:m​> firefrommoonlight: datasheets too ;)
<re_irc> <@n​ewam:m​> for the STM32WL there is a completely undocumented block-encryption feature; but they have code for it in their HAL which sets some registers to "reserved" values.
<re_irc> <@a​lmindor:m​> no such luxury here just the svd:
<re_irc> <@n​ewam:m​> I would recommend starting something similar; even the good vendors are not perfect.
<re_irc> <@n​ewam:m​> Oh, hm, that repo just commits the XML directly. Shouldn't be too bad to edit that directly then.
<re_irc> <@f​irefrommoonlight:m​> newam: Yikes
<re_irc> <@f​irefrommoonlight:m​> Often the reserved values are to keep parity with different MCUs, eg skipping features a given one doesn't have
neceve has quit [Ping timeout: 272 seconds]
<re_irc> <@a​lmindor:m​> hmm is it expected that svd2rust will generate uncompilable code?
<re_irc> <@a​lmindor:m​> I removed all the custom stuff from the in e310x so it just does the svd2rust, using latest version and it generated a reader with pub(crate) new that's unused
<re_irc> <@a​lmindor:m​> oh wait, i had some ancient svd2rust version from pacman installed, nvm
tokomak has joined #rust-embedded