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
emerent has quit [Ping timeout: 264 seconds]
emerent_ has joined #rust-embedded
emerent_ is now known as emerent
IlPalazzo-ojiisa has quit [Quit: Leaving.]
firefrommoonligh has joined #rust-embedded
<firefrommoonligh> <ChristianHeussy[> "Does anyone have a good referenc..." <- HALs are wide, as their purpose is providing a high-level API over a breadth of MCU peripherals. With this in mind, I would pick the peripherals you need for a given project, and implement those with the functionality you need first, using the official documentation of the MCU as your guide.
<firefrommoonligh> Take API inspiration from HALs for other chips.
<firefrommoonligh> While they can have lots of code, much of it is independent, so it's not as intimidating as it seems; a given project will likely only need a small subset. If you approach that subset, then it can be straightforward
Shell has quit [Ping timeout: 255 seconds]
Shell has joined #rust-embedded
Guest7282 has left #rust-embedded [Error from remote client]
notgull has joined #rust-embedded
Guest7282 has joined #rust-embedded
notgull has quit [Ping timeout: 252 seconds]
<Alex[m]123456> Hey folks, I'm a long time rust user, but fairly new to embedded. Was wondering if I could get some advice. I need to sample and smooth at least 4 analog inputs (but preferably 8). This is a bluepill stm32f103. I started using DMA for this so my main loop can spin faster but I was wondering, what's the best way to sample continuously like this? I noticed the inputs can be quite noisy, probably my breadboard circuitry, so I'm
<Alex[m]123456> using some caps to filter, but is there a way to convince the adc to sample over a longer period so that noise is naturally smoothed out, then I just grab a sample when it's ready?
marmrt[m] has joined #rust-embedded
<marmrt[m]> What frequency are you measuring at?
<Alex[m]123456> Noise is only one small issue I can deal with in circuit and software. I'm more interested in the best practice for repeated sampling.
<Alex[m]123456> By frequency, I assume you mean the adc clock? it's currently set to 2MHz, but since this is a midi controller it really doesn't need to be that high. `rcc.cfgr.adcclk(2.MHz())`
<Alex[m]123456> Sorry, my first sentence in my most recent reply was maybe not accurate. I am wondering if there's a way to smooth noise using the chip too
<marmrt[m]> No, what are your requirements for samples per second.
<marmrt[m]> There might be some parameters in the ADC peripheral that you can adjust to reduce noise. You can also acquire multiple ADC samples and average them
<Alex[m]123456> Ahh
<Alex[m]123456> Should be very low requirement. Since it's a midi controller, the slowest would be in the region of 500 samples/s
<Alex[m]123456> That should comfortably support all sensible BPMs
<Alex[m]123456> > You can also acquire multiple ADC samples and average them
<Alex[m]123456> Yeah, this is what I'm doing currently. Just wanted to check if there's an on chip method.
<Alex[m]123456> I'm assuming a high speed adc clock is fine, because we want the adc to actually do some sampling whilst the main loop is doing other work
<Alex[m]123456> This is in my main loop to handle the adc dma. Does this seem reasonable for continual sampling?... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/JRWKRTRgThNcpyHzGsJdETqh>)
<Alex[m]123456> This is stm32f1xx-hal.
<Alex[m]123456> I feel like I'm asking dumb questions
crabbedhaloablut has quit [Read error: Connection reset by peer]
crabbedhaloablut has joined #rust-embedded
mameluc[m] has joined #rust-embedded
<mameluc[m]> I am debugging with vscode + openocd gdb server. Is there a way to dump all peripheral memory to a file so I could compare two different states?
<mameluc[m]> preferrably as JSON or some other format with a bit of text, raw binary might be hard to read
<JamesMunns[m]> x/... is usually the command you want for that, but that prints it to a console
<JamesMunns[m]> like
<JamesMunns[m]> `x/1024b *0x40000000` will print 1024 bytes starting at that address to the console
<JamesMunns[m]> beware of reads with side effects, like clearing flags tho :p
<JamesMunns[m]> or like x/256w *0x40000000 will print the same size, but as 32-bit words instead of 8-bit bytes, which might be more readable
<JamesMunns[m]> I don't know any automatic tools to take that data, and mix it with say, the svd file, to turn that into meaningful data
<JamesMunns[m]> (you might want x/256wx to print as hex too? can't remember off the top of my head)
<mameluc[m]> okay thanks. First I have to figure out what is actually happening when I press F5 in vscode 😅
<JamesMunns[m]> ah, gotcha. My suggestions are from the GDB console :D
<JamesMunns[m]> never used the vscode integration
<JamesMunns[m]> https://stackoverflow.com/questions/16095948/gdb-dump-memory-in-specific-region-save-formatted-output-into-a-file seems to suggest two ways of logging or dumping that, if you have a console
IlPalazzo-ojiisa has joined #rust-embedded
<mameluc[m]> okay I have to figure that stuff out. maybe something exists in some ST IDE that would make it easy
<mameluc[m]> vscode has a "memory" view but I think it only supports LLDB c++ debugger, whatever that is
crabbedhaloablut has quit [Read error: Connection reset by peer]
crabbedhaloablut has joined #rust-embedded
<firefrommoonligh> <thejpster[m]> "https://imgs.xkcd.com/comics/bug..."; <- @Mozilla
<firefrommoonligh> <Alex[m]123456> "Hey folks, I'm a long time..." <- #1: You can do what you're explicitly asking by setting the sample time; this may help!
<firefrommoonligh> #2: I think you should apply a lowpass filter to your results, using the IDSP crate or a CMSIS-DSP wrapper. Sample the ADC at a high rate, and pass each channel to an IIR filter.
<firefrommoonligh> * sample time, and related ADC clock settings; this
<firefrommoonligh> * sample time in hardware, and related ADC clock settings; this
<firefrommoonligh> * #1: You can do what you're explicitly asking by setting the sample time in hardware, and related ADC clock settings; this may help! This comes at the cost of sample rate.
<firefrommoonligh> #2: I think you should apply a lowpass filter to your results, using the IDSP crate or a CMSIS-DSP wrapper. Sample the ADC at a high rate, and pass each channel to an IIR filter.
<firefrommoonligh> * #1: You can do what you're explicitly asking by setting the sample time in hardware, and related ADC clock settings; this may help and/or solve your problem! This comes at the cost of sample rate.
<firefrommoonligh> #2: I think you should apply a lowpass filter to your results, using the IDSP crate or a CMSIS-DSP wrapper. Sample the ADC at a high rate, and pass each channel to an IIR filter.
<firefrommoonligh> * #1: You can do what you're explicitly asking by setting the sample time in hardware, and related ADC clock settings; this may help and/or solve your problem! This comes at the cost of sample rate.
<firefrommoonligh> #2: If it doesn't, or even if so, consider a digital lowpass filter, using the IDSP crate or a CMSIS-DSP wrapper. Sample the ADC at a high rate, and pass each channel to an IIR filter.
Dr_Who has quit [Quit: ZZZzzz…]
adamgreig[m] has joined #rust-embedded
<adamgreig[m]> hi @room, meeting time again! agenda is https://hackmd.io/RkEjPOSHSOO5Lyq9AGepyQ, please add anything you'd like to announce or discuss! we'll start in a few mins
<adamgreig[m]> ok, let's start!
<adamgreig[m]> first up, as you may have heard, embedded-hal 1.0.0 is now out!
<adamgreig[m]> many congratulations to the hal team and everyone here for years of hard work on that!
<adamgreig[m]> hopefully now it's payoff time :P
<adamgreig[m]> there's a blog post about it with details here: https://blog.rust-embedded.org/embedded-hal-v1/
<adamgreig[m]> so if you haven't already, now's the time to try porting your drivers/hals/etc over and see how it goes
<adamgreig[m]> in other release news, the risc-v team released the new 0.11 of risc-v, 0.12 of riscv-rt, and the first releases of riscv-pac and riscv-semihosting crates
<thejpster[m]> I did some work (others did more) porting over the RP2040 stuff to eh-1.0 and the missing traits kind of bit us a bit as we tended to expose functionality through traits rather than through inherent methods.
<adamgreig[m]> including therefore the first crate with the new concept for a "pac interface" between the architecture crates and the PACs, riscv-pac, https://docs.rs/riscv-pac/latest/riscv_pac/
<thejpster[m]> So if we want to let people use rp-hal without importing embedded-hal 0.2 we have to move a bunch fo methods over.
eldruin[m] has joined #rust-embedded
<eldruin[m]> linux-embedded-hal 0.4 was released with embedded-hal updated to 1.0
jannic[m] has joined #rust-embedded
<jannic[m]> thejpster: Not a big issue, though, or is it? Whether we replace them by new inherent methods, or by eh 1.0 impls, should be a similar amount of work.
<thejpster[m]> no, maybe not a big deal - and we only have to do it once.
<adamgreig[m]> you can't replace them with eh1.0 impls for traits that eh1.0 doesn't have, so it does leave you having to design your own inherent methods, but I think that's intentional from embedded-hal
<jannic[m]> Yes, I meant it wouldn't change the effort if e-h had those traits.
<adamgreig[m]> the idea is now more focussed on driver/hal interop, with end users generally directly using hal-provided methods (since it saves having to import the trait and it allows for hardware-specific functionality)
<adamgreig[m]> ah, yea, indeed
<thejpster[m]> but this also touches on the point I put on the agenda - harmonising things. I don't think there's a clear steer from the Edwg on how a HAL should be constructed.
<adamgreig[m]> eldruin: how did spibus/spidevice work for it in the end?
<adamgreig[m]> indeed, I think at present that's deliberate
<thejpster[m]> Like, should it have an inherent `fn is_high(&self) -> bool` on a `Pin` type? Or should it only have the impl for the embedded-hal trait, which gives you `fn is_high(&mut self) -> Result<bool, Self::Error>` (or something .. I forget).
<firefrommoonligh> thejpster[m]: Both
<thejpster[m]> I have been bouncing between chips and HALs recently and the differences started to jar a little bit.
<adamgreig[m]> do you think the wg should say what a hal should look like?
<firefrommoonligh> So, you can wrap one approach with the other:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/mYGQVRtMEETbeBnlpBvedSNE>)
<firefrommoonligh> where Pin::is_high() is native, and the code I posted wraps it in EH traits
<adamgreig[m]> we haven't ever really officially, but when in the past there's been a sort of "blessed" hal, it tends to lead to lots of very similar hals for other chips, but perhaps less innovation in different/better APIs
<eldruin[m]> adamgreig[m]: both bus and spidevice are implemented for an inner spidev and the whole deal is documented
<firefrommoonligh> adamgreig[m]: I don't think you'd find a consensus.
<thejpster[m]> > perhaps less innovation in different/better APIs
<thejpster[m]> How much valuable innovation do we think remains?
<adamgreig[m]> so while it's nice that in theory you could swap between chips with less effort, in practice it felt like it was holding the general ecosystem back, and letting different hals come up with their own apis suitable for their hardware (and for whether they're async or not and so forth) was better
<firefrommoonligh> I'm with Adam: Sounds great in theory, but I'm skeptical it'd work out.
<adamgreig[m]> good question!
<adamgreig[m]> I would always hesitate to say we're done inventing HAL APIs
<jannic[m]> thejpster[m]: When you are in this situation, can you take notes which alternative felt better?
<jannic[m]> I like it that the HALs still have room for experimentation, but we should learn from it, and the best way to see which alternative works best is by actually using both.
<adamgreig[m]> but I guess at some point you could make a compelling argument that we've found some good APIs and so there'd be more net benefit to suggesting most hals have something in that style
<adamgreig[m]> I sort of expect that to happen naturally as HALs develop rather than necessarily requiring the wg to take a position though
<thejpster[m]> I think most of the people who are Big Fans of Chip Company A, to the point they want to work on a Rust HAL for their chips, don't also tend to be Big Fans of Chip Company B.
<firefrommoonligh> Over time, I find my APIs get simpler and more streamlined. I'm regularly looking at my code and thinking "Wow this is repetative / a DRY violation". I end up adding an abstraction in the unerlying lib.
<thejpster[m]> So you won't get much cross pollination?
<adamgreig[m]> but if HAL authors for new chips look to us first, perhaps we should have somewhere to point them at?
<adamgreig[m]> yea, perhaps not
<firefrommoonligh> * at my firmware code and
<adamgreig[m]> what did you want to say about riscv/cortex-m?
vollbrecht[m] has joined #rust-embedded
<vollbrecht[m]> most of the times the HAL starres in a bottom up development from there respective PAC's so you would need first to determine high level top down api's that "feel good" i suppose
<vollbrecht[m]> s/starres/start/
<thejpster[m]> I also had to bounce between an Arm chip and a RISC-V chip
<thejpster[m]> and interrupt handlers don't use the same kind of macro
<vollbrecht[m]> thejpster[m]: there is no stable ISR abi right?
<thejpster[m]> Which just seemed weird, given they basically have to do the same job (stuff a function pointer into a struct that is otherwise populated with pointers to a default function)
<thejpster[m]> No but cortex-m defines #[interrupt] fn TIMER0_IRQ() { } and risc-v defines interrupt!(UART0_IRQ, uart_handler); fn uart_handler() { ... }
<thejpster[m]> It just seemed unnecessarily differnet
<thejpster[m]> s/differnet/different/
<thejpster[m]> The Cortex-M ISR ABI is the C ABI, and the RISC-V one is handled by an assembly language routine which bounces you into a Rust ABI function call
<thejpster[m]> but ultimately both just want an extern "Rust" function with a magic name, maybe with some re-writing of static mut to be &mut.
<adamgreig[m]> it sounds like riscv-rt has the same macro as cortex-m-rt used to use, before the proc macros were written?
<adamgreig[m]> is that still the case, actually?
<adamgreig[m]> where did the interrupt macro come from?
<thejpster[m]> I'm looking at the /riscv repo but I can't see a tag for the latest release so I can't see what changed
<adamgreig[m]> the changelog has a list of the changes
<firefrommoonligh> I am not a fan of the cortex-m function-name-is-interrupt-periph syntax. Minor concern, but IMO you should specify it in a diff way like with RTIC
<thejpster[m]> uh, I can't immediately put my finger on where I saw interrupt! now.
<firefrommoonligh> And name the fn what you want
<firefrommoonligh> It would be v nice if this was standardized among architectures as you point out
<adamgreig[m]> it used to be the case that you named the function whatever and used a separate macro to tell rt what name to export it under, but we changed it to the current way
<vollbrecht[m]> i think that this is a hard problem, because some architectures handle ISR's fundamentally different than others, for example PowerPC has its own special quirks with no vector tables.
<adamgreig[m]> you can see the PR and discussion for it https://github.com/rust-embedded/cortex-m-rt/pull/122
<firefrommoonligh> Essentially, the (minor) issue I face, and I think is the concern Adam and TheJpster are pointing out, is I currently have 3 formats on active firmware projects:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/jRGNkoAxadgrmVcWfIchpreK>)
<firefrommoonligh> Not a big deal, but I would prefer to make a breaking change to fix it over leaving it. My 2c
<firefrommoonligh> * have slightly-different interrupt syntaxes
<vollbrecht[m]> wasn't there a rust wg around a unified isr abi? i think they are currently not that active though
<vollbrecht[m]> * wasn't there a rust wg working on a unified isr abi? i think they are currently not that active though
<adamgreig[m]> RTIC needs to have a more sophisticated syntax to mark its tasks, including what resources are accessed, so I don't think you'll get the same syntax for cortex-m-rt's generic "this function is an interrupt handler" macro
<adamgreig[m]> you could envision that macro taking an optional interrupt name which it uses in place of the function name, though?
bartmassey[m] has joined #rust-embedded
<bartmassey[m]> For those architectures with "weird" IVs the HAL could build a trampoline table of some kind I guess.
<firefrommoonligh> So, similar to RTIC, and as `Adam` hinted, I propose:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/fxEfQjDMokSjmuMOEMJGxigk>)
<firefrommoonligh> I don't know how to do the proc macro thing, but I bet one of you or ChatGPT does!
<jannic[m]> IIRC the argument against that was that then there's a meaningless identifier my_timer_isr?
<thejpster[m]> We've been around this loop before - the name of your function does not become a symbol because it's very important to ensure nothing else in the program can call it (otherwise the function can be pre-empted and the escalation of static mut to &mut becomes unsound)
<thejpster[m]> and if it doesn't become a symbol it might as well do something useful, like name the interrupt
<bartmassey[m]> This is all very similar to the situation with #[test] I think
<firefrommoonligh> jannic[m]: Not meaningless. The meaning is a semantic description, like with any function
<firefrommoonligh> My example name was bad. Something like this highlights it better:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/PXEdIgrrRRLKSZUyPSNYdtcV>)
<bartmassey[m]> Anyway maybe get the Hal ISR WG going again? I personally would love to have the same ISR interface across parts for teachability purposes.
<vollbrecht[m]> using a hardware Interrupt to represent a "software" interrupt still needs a logical link to the hardware interrupt on platforms where it is "wired" that way.
<firefrommoonligh> I do have a spear along these lines at RTIC's ISR syntax:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/JRsPQBCADIIpsiVHhrAuPzye>)
<Ralph[m]> firefrommoonligh: i agree, it'd be good to be able to name it. it's much nicer to have a method named `button_click` instead of `EXTI9_5` (STM32 interrupt names are... weird?)
<thejpster[m]> I use it...
GrantM11235[m] has joined #rust-embedded
<GrantM11235[m]> <thejpster[m]> "We've been around this loop..." <- How many people actually use the static mut thing? I only ever hear about it in the context of people being surprised that it exists
<adamgreig[m]> I guess the people using it probably don't talk about it much, but it's a very surprising feature that we've also discussed removing in the future
<jannic[m]> I think the interrupt syntax is just one example, but a good one, because it shows the underlying problem: While the difference between the HALs is just some detail, and for sure not difficult to learn, it's a completely unnecessary obstacle when learning things or switching between architectures. So I do think the overall ecosystem would be easier if we could have less of those differences.
<adamgreig[m]> in preference to using the normal rust tools for statically allocated mutable things, though usually with some performance penalty compared to the known-uniqueness the interrupt macro can take advantage of...
<adamgreig[m]> for the cortex-m-rt interrupt macro, personally i'd be on board with a change to allow an optional interrupt to be specified, and if not specified it uses the function name; that way it's not a breaking change and you can choose how you want the name picked, and besides the "now we have two ways to declare an interrupt" I don't see other downsides
<adamgreig[m]> but it does mean you have two ways to declare an interrupt
<adamgreig[m]> #[interrupt] fn TIM9() { ... } vs #[interrupt(TIM9)] fn slow_tick() { ... }
<firefrommoonligh> jannic[m]: Yea - I think we can unify interrupts, even if I'm doubtful about unifying HALs
<firefrommoonligh> s/interrupts/interrupt syntax/
<adamgreig[m]> but I don't know if you could do such a thing on riscv, let alone any other architecture
<thejpster[m]> adamgreig: I'd like to see a PR that changes riscv-rt to work in the same way, at the same time.
<firefrommoonligh> adamgreig[m]: Valid
<Ralph[m]> adamgreig[m]: i think that's a good approach for seamless migrations. and you can always declare the current approach as obsolete and remove it in the next major
<jannic[m]> I don't think we should unify HALs. Just try to avoid completely arbitrary differences. If there's a reason (and be it a strong personal preference of the respective maintainers), fine.
<adamgreig[m]> afaict riscv-rt currently takes a simpler approach: the linker script still expects certain-named synbols, and it's up to the user to create them
<thejpster[m]> You can, but only for the ISA defined interrupts, like MachineExternal. How MachineExternal reads your soc-specific interrupt controller and decides to bounce into either the Timer IRQ handler or the UART IRQ handler is unfortunately SoC specific. Although riscv-rt could provide some scaffolding to help.
<adamgreig[m]> which also works as-is on cortex-m, we just don't document it as a way to do things
<adamgreig[m]> #[export_name="TIM9"] fn whatever() { .. } or #[no_mangle] fn TIM9() { ... } on riscv-rt
<thejpster[m]> > completely arbitrary differences.
<thejpster[m]> > strong personal preferences
<thejpster[m]> These are not mutually exclusive 🤣
<adamgreig[m]> so I suppose you could write the same #[interrupt] macro as we have in c-m-rt, in principle
<adamgreig[m]> or we could delete it from c-m-rt, and just tell people to write interrupts the same as the risc-v crate
<adamgreig[m]> (or leave the macro around for back-compat, but update the documentation)
<thejpster[m]> I like the macro, because I like the static mut transmogrification.
<adamgreig[m]> the only reason to have the macro in c-m-rt is to do the `&static mut` transform, I believe, and it's pretty weird non-rust magic syntax
<thejpster[m]> also it ensures the ISR cannot be re-entered from anywhere else
<adamgreig[m]> perhaps the macro could be "how you declare an interrupt if you want the rt crate to give you a static mut transform" but otherwise you just make a function with the right name
<thejpster[m]> (which makes it safe to use static mut, even if you don't want the macro to do it for you)
<adamgreig[m]> yea, but unless you're doing the static mut transform, you don't need to ensure that
<adamgreig[m]> (or otherwise yourself relying on that non-reentrancy for some unsafe precondition, but in that case it remains on you to not call it?)
<vollbrecht[m]> If you for example compare a simple architecture like avr 8bit vs something like xtensa. On esp xtensa for example you get 32 hardware Interrupts but up to 99 hardware Interrupts source signals through an interrupt allocater with different priority levels. Nothing like that on a small avr. The syntax needs to be powerful enough to accommodate both options
<vollbrecht[m]> * If you for example compare a simple architecture like avr 8bit vs something like xtensa. On esp xtensa for example you get 32 hardware Interrupts but up to 99 hardware Interrupts source signals through an interrupt allocater with different priority levels. Nothing like that on a small avr. A unified syntax needs to be powerful enough to accommodate both options
<GrantM11235[m]> Another difference is that avr interrupt handlers get a free CriticalSection token in the function signature, since the hardware automatically disables concurrent interrupts
<adamgreig[m]> in which avr crate? I was just looking at https://docs.rs/avr-device/latest/avr_device/attr.interrupt.html which doesn't seem to
<adamgreig[m]> (though note the syntax requires being given the chip name, so wouldn't be immediately compatible with the suggested version I had above anyway)
<thejpster[m]> Another note in favour of tagging interrupt and exception handlers with attribute macros is that some handlers take function arguments. Like a Cortex-M HardFault gets the &ExceptionFrame. We currently also use `#[entry]` to indicate the entry function.
<Ralph[m]> adamgreig[m]: from the docs you linked:
<Ralph[m]> > This is an unfortunate requirement of the current crate architecture and might change in the future.
<Ralph[m]> so this isn't a hard technical requirement of AVR chips; meaning if/when `interrupt` would get aligned this would "just" have to be cleaned up (easy to say if you're not the one to do it 😅)
<adamgreig[m]> ideally hardfault would not get the exceptionframe, if we could delete that retrospectively we would
<adamgreig[m]> instead there's been work to make it optional with an argument to the macro
<Ralph[m]> > <@adamgreig:matrix.org> (though note the syntax requires being given the chip name, so wouldn't be immediately compatible with the suggested version I had above anyway)... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/fxPkFyPLodBAVlQrRENrLAGO>)
<thejpster[m]> uh, how else would you get the exception frame? Isn't it pushed onto the other CPU stack?
<thejpster[m]> I forget how it works. But I definitely have HardFault handlers that print it out.
<adamgreig[m]> besides that I don't think any of the macros take arguments. I suppose the entry macro is also only required to do the static mut transform. it's a shame we can't (afaik?) hook into rust to allow users to just have a rust "main" fn
<GrantM11235[m]> adamgreig[m]: uhhh, I have no idea. I am pretty sure I saw it somewhere though
<adamgreig[m]> GrantM11235[m]: I can see how it could be allowed, which is neat
<thejpster[m]> adamgreig: so you're saying have `fn Reset()` call some `extern "C" { fn main(); }` and have the user declare a no-mangle main function?
<adamgreig[m]> the user could already do that today if they wanted, yea
<adamgreig[m]> but I'd rather have Reset call some extern rust main() that's just the normal main, and then the user doesn't need #[no_main] either, but I don't think that's possible today
<thejpster[m]> but if they do that the function signature isn't type-checked
<thejpster[m]> yeah, I don't think you can have extern Rust functions?
<adamgreig[m]> I don't think the extern rust part is relevant, it's just that you can't have main in no-std binaries?
<adamgreig[m]> anyway, we're out of time for today, we could continue chatting about this later or someone could open an issue to track it?
<thejpster[m]> ok, in general it sounds like there's no real agreement on "use macros to ensure the user did the right thing, and also let us re-write static muts" and "let the user make objects with magic symbol names and the linker will probably sort it out"
<adamgreig[m]> you can't have the former without the latter anyway, so it's mostly a question of how we suggest users do things I Guess
<adamgreig[m]> s/Guess/guess/
<Ralph[m]> so i presume this would need an issue with rust-lang to see if there'd be an option to get a `no_std` `main`
<Ralph[m]> > At the time of writing, Rust's main interface makes some assumptions about the environment the program executes in: For example, it assumes the existence of command line arguments, so in general, it's not appropriate for #![no_std] programs.
therealprof[m] has joined #rust-embedded
<therealprof[m]> thejpster[m]: I can probably agree to anything that works universally but I don't think that method has been discovered already...
<adamgreig[m]> nothing stopping you making your own interrupt and exception macro on riscv (in fact the cortex-m-rt-macros one probably works as-is!), or using no_mangle/export_name in cortex-m
<GrantM11235[m]> I would be interested to see if there is a way get the benefits of the static-mut-rewriting in a less magical way
<thejpster[m]> I'm not minded to port the cortex-m-rt macros to the riscv-rt crate if the cortex-m people want to deprecate them anyway
<adamgreig[m]> I don't think there's any serious call to deprecate them from c-m-rt, but there is talk of removing static-mut (not necessarily going to happen) and exceptionframe
<adamgreig[m]> the "ensures only called from interrupt" and "checks type signature" properties are helpful enough to probably warrant the macros continued existance and use
<adamgreig[m]> so maybe add the option to put the interrupt/exception name into the macro call, ideally take the macro out of the PAC and keep it just in the rt crate (for interrupt), give risc-v the same interface, avr is already very similar, it could work
<adamgreig[m]> anyway, I have to run, thanks everybody!
<jannic[m]> Could the static-mut rewriting a separate thing, to make it more explicit? Like... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/qOYOEbrTcfDqdzjBEnPqfkvp>)
<GrantM11235[m]> Something like `#[Interrupt(TIM1) fn my_timer_isr(token: InterruptToken<'_>)]`, where the token can be used to "lock" a zero cost "mutex"
<adamgreig[m]> maybe it's an argument to the interrupt macro
<jannic[m]> (Of course the rewrite_static_mut must make sure it can only be applied to functions with the interrupt attribute)
<adamgreig[m]> as it'd be scary to call it without the interrupt macro too :P
<jannic[m]> Yes, or an argument, exactly.
<adamgreig[m]> #[interrupt(TIM9, rewrite_static_mut: True)] or whatever
<adamgreig[m]> or yes, it could be an optional argument to the method, I think we actually used to have something a lot like that
<GrantM11235[m]> Could the attribute be applied directly to the static inside the function?
<jannic[m]> That would make the magic a lot less obscure, and that would help a lot to easily understand what's going on. If you don't know how it works, you can google rewrite_static_mut and get an explanation.
<GrantM11235[m]> That would make it more clear what is being rewritten
<adamgreig[m]> yes, I think the interrupt macro could detect calls to some new attribute inside the function body and rewrite those
<adamgreig[m]> and then the attribute woudln't be usable outside of that macro either
<jannic[m]> Because I think the big issue with the current version is that beginners that just learned how static mut works get completely confused by code that looks the same but works different.
<GrantM11235[m]> We also don't want beginners to think that static muts are a good idea in general
<thejpster[m]> I think lazy_static! uses the static ref syntax already when it re-writes your static variable for you
<adamgreig[m]> I think you'd still want "mut" in there syntactically somehow
<thejpster[m]> got to run
<GrantM11235[m]> Is the interrupt macro multicore safe? Is it possible to use it to register the same handler for two different cores?
<GrantM11235[m]> Or is it possible to make two cores use the same vector table?
<firefrommoonligh> I use per-ISR code like that for internal counters all the time, FYSA. Useful mechanic if it makes them safer.
<firefrommoonligh> Usually if I'm dividing a large main loop into tasks to even the load between runs, and for debug prints that I want to occur at a readable rate
M9names[m] has joined #rust-embedded
<M9names[m]> <GrantM11235[m]> "Or is it possible to make two..." <- Yep, totally possible. Still need to unmask the interrupt on both cores to have it enter concurrently (which is an unsafe op). I haven't thought of any task where calling an interrupt handler from multiple cores simultaneously was a good idea yet.
<jannic[m]> However I think the documentation of NVIC::unmask doesn't state that safety requirement. It only says: "This function is unsafe because it can break mask-based critical sections". https://docs.rs/rp2040-pac/0.5.0/rp2040_pac/struct.NVIC.html#method.unmask
<M9names[m]> You can also re-enable the interrupt and change priority from within the interrupt handler, so if you try hard enough this effects single core too.
<jannic[m]> * However I think the documentation of NVIC::unmask doesn't state that safety requirement. It only says: "This function is unsafe because it can break mask-based critical sections". https://docs.rs/rp2040-pac/0.5.0/rp2040_pac/struct.NVIC.html#method.unmask (or https://docs.rs/cortex-m/latest/cortex_m/peripheral/struct.NVIC.html#method.unmask, it's all the same)
<M9names[m]> Personally I put this stuff in the same category as writes to /dev/mem. Someone who is that keen to blow their feet off is probably going to manage it whether we put protections in or not
<jannic[m]> Sure, but enabling a superficially safe interrupt handler on both cores could be done without being a case of obvious mischief.
<jannic[m]> Probably not a wise design decision, but also not something that should be punished with undefined behavior.
<jannic[m]> Like, you use an interrupt as an async waker. It's allowed to have spurious polls, so a lazy approach could be to just have the same interrupt handler on both cores, and wake each CPUs executor in parallel. Totally fine, unless you have, for some reason, a static mut in that interrupt.
ello has quit [Read error: Connection reset by peer]
ello has joined #rust-embedded
ithinuel[m] has joined #rust-embedded
<ithinuel[m]> <jannic[m]> "Like, you use an interrupt as an..." <- If I may chime in, the main reason which "deterred" me from enabling an irq on both core while keeping the same handler is that the handler will need to clear the irq flag.... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/MbLJIzpFCdNJQKQywXUsapAw>)
<ithinuel[m]> * If I may chime in, the main reason which "deterred" me from enabling an irq on both core while keeping the same handler is that the handler will need to clear the irq flag.... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/JGxsQjaCmZtpyYIlQGWnCztU>)
<ithinuel[m]> (I hope I'm not too wildly off-topic, I only followed the last few messages)
<jannic[m]> I don't say it's a good idea to use the same handler on both cores. In fact I didn't think about it enough to have an opinion.
<jannic[m]> It's just that it looks like nothing in the docs strongly advises against doing it, and there may be good reasons to try it, and one could end up with undefined behavior (due to coexisting `&mut` references to the pseudo-`static mut`) without doing anything obviously wrong.
dne has quit [Remote host closed the connection]
dne has joined #rust-embedded
<thejpster[m]> <GrantM11235[m]> "Or is it possible to make two..." <- Possible and indeed the default on the RP2040.
<thejpster[m]> (Sorry, reading the scroll back. Others made the same point already)
danielb[m] has quit [Quit: Idle timeout reached: 172800s]
notgull has joined #rust-embedded