<RobinMueller[m]>
hmm, the is_input_high usually should work independently of events/interrupts, but I am not familiar with microbit
<RobinMueller[m]>
dumb question, you are keeping the buttons pressed right? You said every time you press a button, but if you just click it shortly once, your logic probably becomes unreliable
<RobinMueller[m]>
* dumb question, are you keeping the button pressed? You said every time you press a button, but if you just click it shortly once, your logic probably becomes unreliable
<astennumero[m]>
<RobinMueller[m]> "dumb question, you are keeping..." <- No, I'm not keeping the button pressed. I do a short click.
<astennumero[m]>
I'm sorry why does the logic become unreliable if it's short click?
<astennumero[m]>
I'm new to embedded programming. And I might be missing something here.
<RobinMueller[m]>
I don´t know your setup and hardware, so I might make wrong asssumptions here.. Are you checking in the TIMER IRQ whether the button is pressed or not pressed? If the delay is too long, the pins will be measure when the button is already unpressed
<M9names[m]>
putting a delay in the interrupt isn't a good solution. starting a new timer inside the delay is also problematic.
<M9names[m]>
and then not trigger a new "press" until the signal has been low for a set number of samples.
<M9names[m]>
if you're going for a timer sampled solution, you want to count the number of samples that had the signal asserted and make a decision based on that.
<astennumero[m]>
<RobinMueller[m]> "I don´t know your setup and..." <- Yes, I think you're referring to these variables? buttonapressed, buttonbpressed
<astennumero[m]>
<RobinMueller[m]> "I don´t know your setup and..." <- I think I understand you now. What if I created another mutex refcell variable and store the value of the buttons in it one the buttons are pressed, reset the channels in the first interrupt and then use the mutex variable to check if the button has been pressed in the second interrupt?
<RobinMueller[m]>
for detecting double presses, maybe detect them based on proximity of two state flips when using that method? (e.g. one flip detected on b0, and 0-3 samples later, flip on b1)
<RobinMueller[m]>
* on b1, could of course also happen in different order)
<M9names[m]>
i would put double-press detection at a higher level than this
<M9names[m]>
oh, you're talking different buttons still?
<M9names[m]>
i thought you mean pressing the same button multiple times in a short interval, apologies
<astennumero[m]>
Yup there are two buttons A and B
<astennumero[m]>
And I want to record A+B when both the buttons are pressed together. The initial issue I had was there was a very small time difference between the buttons pressed - I just couldn't press them together. Humanely impossible?
<astennumero[m]>
So I put in a nop there to ensure that the interrupt doesn't start running immediately. I want to replace this with a timer to ensure the code is robust and idiomatic.
<astennumero[m]>
Apologies if I missed mentioning that in the beginning
<dirbaio[m]>
(with embassy-nrf. nrf-hal doesn't support async)
<astennumero[m]>
Right. Embassy is in my bucket list of things in the rust embedded ecosystem I want to learn. Haven't learnt it yet.
<astennumero[m]>
<M9names[m]> "oh, you're talking different..." <- Yup there are two buttons A and B
<astennumero[m]>
And I want to record A+B when both the buttons are pressed together. The initial issue I had was there was a very small time difference between the buttons pressed - I just couldn't press them together. Humanely impossible?
<astennumero[m]>
So I put in a nop there to ensure that the interrupt doesn't start running immediately. I want to replace this with a timer to ensure the code is robust and idiomatic.
<M9names[m]>
yes, you build the state machine i was describing by hand instead of asking rust to build it for you
<M9names[m]>
(which is what the async solution does)
<astennumero[m]>
Hmm. Right. Okay, let me see what I can do. Thanks everyone for your suggestions.
t-moe[m] has quit [Quit: Idle timeout reached: 172800s]
t-moe[m] has joined #rust-embedded
<t-moe[m]>
I know that the type layout can change anytime as long as we dont use repr(..), but I can always use the schema hash to verify, so I guess why not 🫣
<t-moe[m]>
I experimented a bit with postcard_schema James Munns and wrote some code that can recover a postcard schema on the host from the ELF file 😅.
<JamesMunns[m]>
I've considered doing this for all postcard schemas for postcard-rpc, BUT postcard-rpc does some compile time checks for collisions, and that's not possible to do if you just shove everything into a linker section, since you can only really observe that at link time or run time
<JamesMunns[m]>
oh you do it from the ELF file, not via RTT
<JamesMunns[m]>
hmmm
<JamesMunns[m]>
If you do want to do something like this, one thing you could do is serialize the schema at compile time, it's not easy to do generally because there are no const traits, but for a specific type (schemas), it's maybe possible.
<t-moe[m]>
JamesMunns[m]: yeah, i though about doing this at compile time, but I figured it would be hard.. Maybe I'll try...we'll see.
<t-moe[m]>
I'll focus on the rest of the tooling first...
<t-moe[m]>
* yeah, i though about doing this at compile time, but I figured it would be hard.. Maybe I'll try to adapt to that...we'll see.
<t-moe[m]>
I'll focus on the rest of the tooling first... (As the schema recovery from the elf already works)
<zeenix[m]>
sorry, just changed the subject without any context :)
AshconMohseninia has joined #rust-embedded
<AshconMohseninia>
Hey, question, does anyone know whats happened to the usb-device crate? There is PR https://github.com/rust-embedded-community/usb-device/pull/153, which is required to get USB running on ATSAMD chips, but it appears the PR has completely stalled without being merged, even though there is no conflicts at all
<JamesMunns[m]>
I think it's just that there aren't any maintainers that have time to do a release.
<ejpcmac[m]>
I understand that async fn is desugared in a function with an async block inside, which creates a new Future for f1 that is different from the one for f2, but I’d expect that with optimisation level set to z the compiler would kind of “inline” this useless future.
<JamesMunns[m]>
yes, async optimization (particularly wrt size) is a known issue
pcs38 has quit [Quit: leaving]
<JamesMunns[m]>
Someone might know the tracking issues offhand, and there's some work on it, but I don't have them handy
<ejpcmac[m]>
Then, I think we should promote the usage of impl Future instead of async / await.
<ejpcmac[m]>
JamesMunns[m]: I agree for local code, but for libs it impacts all users.
<JamesMunns[m]>
(and PRs for core libraries like this to switch over seems reasonable to me, with docs like "we did this to work around GITHUB ISSUE, this can be reverted when that is addressed"
<JamesMunns[m]>
* is addressed")
<ejpcmac[m]>
Yes, I was thinking opening PRs for those
<JamesMunns[m]>
I'd say open an issue, PR, or add it to the meeting agenda if you want to discuss?
<ejpcmac[m]>
Just wanted to check before
<JamesMunns[m]>
I'd CC dirbaio, but it seems like a reasonable win to me, especially if we document WHY we are doing it - some people go to lib source to learn, and I don't necessarily think it's a good idea for everyone to ALWAYS try and write impl Future code vs async code
<ejpcmac[m]>
The thing is to which extent should we rollback to using impl Future?
<ejpcmac[m]>
Yes, indeed comments should be added, but I don’t think it makes sense on every function. Maybe on the Future type definition?
<JamesMunns[m]>
module level is reasonable to me, but I'm also not the owner of any of that code :D
<JamesMunns[m]>
but I think copy/pasting two top level docs lines in any file you touch seems reasonable.
<JamesMunns[m]>
or just open a tracking issue like "revert to using normal async funcs" and link that, so folks can discuss
<ejpcmac[m]>
Seems reasonable to me as well. A good explanation of the why + link to the tracking issue in rustc.
<ejpcmac[m]>
I’m generally more in favour of keeping the comments in context, so that people reading the code understand why it’s done like this.
<ejpcmac[m]>
I won’t start anything before later tonight anyway, and perhaps even tomorrow. So this lets some time to discuss it here.
<dirbaio[m]>
I sort of think we should not "dirtify" the code with manual "impl Future", we should inestad wait for rustc to get better async optimization
<JamesMunns[m]>
I sort of agree, but I don't think that's likely in the near future? Agreed we shouldn't do any complicated reworks, but for little passthroughs like this it feels reasonable to me?
<JamesMunns[m]>
dunno the magnitude of the overhead, honestly.
<ejpcmac[m]>
Yeah, it’s mostly for passthroughs.
<ejpcmac[m]>
For context, I am using the hexagonal architecture a lot, with many traits and implementations which are normally completely inlined in sync code.
<ejpcmac[m]>
In a tiny blinky firmware of ~8k, switching from having the blink task directly using Embassy + Timer to using an abstract app using traits for the LED + Delay did a +400 bytes or something.
<ejpcmac[m]>
I would need to check again, but I was a bit shocked so I investigated.
<ejpcmac[m]>
But this raises a lot of questions. For instance, what about:
<ejpcmac[m]>
```
<ejpcmac[m]>
async fn caller(n: u8) {
posborne[m] has joined #rust-embedded
<posborne[m]>
👋 For the time being I'm still on hibernation from the WG but have started up a new job working on the wasmtime wasm compiler/interpreter. Recently, some [changes have been made](https://bytecodealliance.org/articles/wasmtime-portability) to increase the suitability of the project for additional use cases, including embedded (no_std, no virtual memory support).
<posborne[m]>
I'm looking to potentially increase our coverage for these code paths in-tree and am wondering if there is a good example showing compilation to an embedded target (e.g. thumbv7-none-eabihf) and a CI setup to run code on that target to assert it is working correctly (presumably qemu with an assert on expected uart output).
<ejpcmac[m]>
Completely unrelated question: has anyone already managed to link a library produced by rustc with code produced by armclang using armlink, with LTO enabled?
<JamesMunns[m]>
You might need xlto for that
<JamesMunns[m]>
not sure if anyone has tried armclang/armlink specifically, but I think some folks did a while back with C and clang in general?
<JamesMunns[m]>
or do you mean "all rust, just using armlink as the linker binutil"?
<zeenix[m]>
<JamesMunns[m]> "I think it's just that there..." <- I wish I had enough familiarity with the project to help but if it's only about preparing release notes, I can volunteer
<ejpcmac[m]>
However, I struggle doing the way arond, that is building the C code with armclang + -flto, Rust code with Cargo and LTO enabled, and linking with armclang.
<ejpcmac[m]>
I wonder if there could be some optimisation already at the library level, like optimising as if the public interface of the lib is completely used, but still do internal optimisation between Rust crates that are included in such library.
<ejpcmac[m]>
And anyway, currently I have either armlink complaning that some symbols are not present, or even that the bitcode is incompatible.
<JamesMunns[m]>
does arm publish the source of armclang?
<ejpcmac[m]>
I don’t think so unfortunately.
<ejpcmac[m]>
They just say it’s based on LLVM.
<ejpcmac[m]>
* on LLVM and clang.
<JamesMunns[m]>
if you want to get really fancy you could build rust on top of armclang, but yeah, would require source I think
<ejpcmac[m]>
Yes indeed.
<ejpcmac[m]>
Let’s open a ticket and ask them a custom build of rustc 🤣
<whitequark[cis]>
JamesMunns[m]: I believe that the current Arm policy is to stay as close to upstream as feasible, though I do not have a public source for that
<JamesMunns[m]>
(if someone disagrees with me, listen to them, I'm not super familiar with how the toolchain works :D)
<ejpcmac[m]>
whitequark[cis]: Yep, they likely have some additional tweaks in optimisations + license management.
<whitequark[cis]>
I wonder if you just need to match LLVM versions?
<ejpcmac[m]>
I have tried, but that’s not sufficient.
<JamesMunns[m]>
I think it needs to be close enough that the bitcode matches, since I think the bitcode isn't really well versioned
<ejpcmac[m]>
They themselves require the exact same version of the toolchain I think to enable LTOs.
<whitequark[cis]>
the bitcode does actually have fairly robust backwards compat for the format
<JamesMunns[m]>
Oh? that's much cooler than I thought.
<whitequark[cis]>
but there is additional semantics above bitcode format that does not
<whitequark[cis]>
the text IR is often broken though
<whitequark[cis]>
JamesMunns[m]: it's kind of by necessity I think
<ejpcmac[m]>
> L6123E: LTO bitcode in <objname> was generated by an incompatible version of armclang
<ejpcmac[m]>
>
<ejpcmac[m]>
> You have attempted to link objects containing bitcode for Link-Time Optimization (LTO) that were created by different versions of the compiler. Any objects or libraries created for LTO must all be compiled and linked with the same Arm® Compiler for Embedded version.
<JamesMunns[m]>
tbh not an unreasonable integrity check for the kind of customers that pay for compiler toolchains
<whitequark[cis]>
ask Arm to build a rustc for you against their LLVM?
<ejpcmac[m]>
whitequark[cis]: I’m seriously going to try that ^^
<JamesMunns[m]>
whitequark[cis]: I bet thejpster would be aware if they were doing that already :D
kenny has joined #rust-embedded
<JamesMunns[m]>
it would not surprise me if they already have a build, even if it is not public.
<ejpcmac[m]>
Yes, especially in the automotive world, I’d assume customers wanting to link code produced by armclang with Rust code produced by Ferrocene.
<thejpster[m]>
I can say there is a general problem of customers wanting to join C code and Rust code together. We haven’t made any announcements in this area.
<thejpster[m]>
If you’re at Embedded World feel free go to the Arm booth and ask them if and when they are going to ship Rust frontend as part of Arm Compiler. They won’t do it if no one asks.
<thejpster[m]>
Feel free to come to our booth and ask us about C compilers too.
<thejpster[m]>
<posborne[m]> "👋 For the time being I'm still..." <- > <@posborne:matrix.org> 👋 For the time being I'm still on hibernation from the WG but have started up a new job working on the wasmtime wasm compiler/... (full message at
<ejpcmac[m]>
I wont be at Embedded World unfortunately, but I’ll start by opening a ticket on their support. The more customer ask for this, the more it is likely they do something.
<ejpcmac[m]>
s/customer/customers/
<thejpster[m]>
QEMU supports semi hosting so use that rather than a UART.
<thejpster[m]>
thejpster[m]: I will add that for certification purposes you can only use opt level 2 and you can’t turn LTO on, so it’s not an issue for some people.
<ejpcmac[m]>
Oh, really? I’m working on the mobile side of things, so die size (and then code space) is the main driver. And we don’t need any certification.
jiande2020 has quit [Quit: Ping timeout (120 seconds)]
<jason-kairos[m]>
s/How do you print the length of a slice in gdb when debugging a rust program? (I messed up the formatting the first time)/How do you print the length of a slice in gdb when debugging a rust program? (edit: deleted and reposted, I messed up the formatting the first time)/
<ejpcmac[m]>
It is not present when using impl Future but pops from nowhere when using async
<ejpcmac[m]>
(On the nRF build)
<dirbaio[m]>
hmhm probably due to not enough inlining
<dirbaio[m]>
i'd recommend using `Instant` everywhere to avoid ms<->ticks conversions, though
<ejpcmac[m]>
Exact same results for lto=fat
<dirbaio[m]>
welp
<dirbaio[m]>
this "u64_div_rem only present when using async fn" is "just" the compiler making different inlining decisions, I wouldn't read too much into it
<dirbaio[m]>
these decisions can be a bit random
<dirbaio[m]>
like, it's possible in a different project it's the complete opposite
<dirbaio[m]>
it's not inherent bloat in the "extra useless" state machine
<dirbaio[m]>
* it's not inherent bloat due to the "extra useless" state machine
<ejpcmac[m]>
Yep, but I’d assume it’s a cascade of optimisation misses
<dirbaio[m]>
yea
<ejpcmac[m]>
Like, due to the extra useless state machine, it’s not possible to inline, so the compiler builtin gets bundled.
<ejpcmac[m]>
But less likely to have an impact in a bigger project
<dirbaio[m]>
yea
<dirbaio[m]>
you can try messing with the inline-threshold codegen option
<dirbaio[m]>
maybe bringing it higher will cause it to get inlined
<dirbaio[m]>
but IME it's not worth spending time wrestling the compiler into optimizing something right in a "toy" project
<dirbaio[m]>
because you then apply the same thing to a real bigger project and the compiler will do something completely different 🫠
<dirbaio[m]>
it's very random :(
<ejpcmac[m]>
This specific issue is on a personal project, but this won’t help me send Rust to my management 😢
<ejpcmac[m]>
Like, I know Rust’s value is somewhere else.
<dirbaio[m]>
also these things tend to amortize better in bigger proejcts. for example it's likely you'll have something else pull in u64_div_rem anyway
<ejpcmac[m]>
But they ask about 1 thing: code size. (No, actually they are asking many more metrics, but code size is a really important one).
<ejpcmac[m]>
dirbaio[m]: Indeed.
<dirbaio[m]>
panic-immediate-abort also helps debloating a lot
<dirbaio[m]>
and defmt
<ejpcmac[m]>
But the useless future thing can add a little overhead, but in many places of the code.
<ejpcmac[m]>
And I’m more worried about that to be frank.
<dirbaio[m]>
yeah that's the problem, it's 100's of places, all over the hals and crates and such
<dirbaio[m]>
maybe we should try to get some "could we have async inlining" conversation started in rustc :D
<dirbaio[m]>
but from what I know of the compiler internals, it's haaaaaard :(
<dirbaio[m]>
async is desugared very early, when lowering from HIR to MIR
<ejpcmac[m]>
dirbaio[m]: Actually for embedded this can be a huge problem depending on the kind of chip you work on.
<dirbaio[m]>
and inlining can be done either in MIR, or by LLVM...
<dirbaio[m]>
I don't think the issue is that big though. especially with panic-immediate-abort
<dirbaio[m]>
* and inlining can be done either in MIR, or by LLVM...
<dirbaio[m]>
so I think it'd need some kind of "async MIR". I'm a rustc dev noob thuogh so maybe i'm wrong
<ejpcmac[m]>
dirbaio[m]: For next project goals ? 😛
<dirbaio[m]>
project goals aren't "hey Rust project pls do this"
<dirbaio[m]>
they're more like "hey Rust project, I want to work on this, pls ACK that it's something wanted and allocate reviewer time etc to the PRs I'll send"
<dirbaio[m]>
so unless someone goes and spends the time implementing it, it's not happening
<ejpcmac[m]>
Oh, I see
<dirbaio[m]>
I think you can propose a goal without actually voluteeiring yourself to impl it, but then it'll just sit there
danielb[m] has joined #rust-embedded
<danielb[m]>
<ejpcmac[m]> "Actually for embedded this can..." <- buy our chips 🙈