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> <@peter9477:matrix.org> : I would say that from my perspective, the idea of a "tick interrupt" should now be considered archaic. While I know there are lots of systems still being built on the basis of a simple timed polling loop with a fast (e.g. 1kHz) tick interrupt on which timing facilities are based, it's been a long time since that sort of approach felt anything but crude to me. There are alternatives, such as the "tickless" option in...
<re_irc> ... FreeRTOS, and with Rust's async abilities there are much nicer ways to structure even very complex code. Code built on Embassy, for example, is inherently tickless, and timing is provided efficiently by an RTC, with an interrupt occurring only on overflow (which in the case of nRF52 should be only every 512s) yet with a timer resolution ("tick") of 1/32768 second, and a u64 to accumulate it (giving a little over 17 million years of continuous...
<re_irc> ... run time before it will wrap....).
<re_irc> As for why the systick approach is common, I'd say it's because it's simple and fairly universal (as it's part of the ARM architecture rather than specific to any one vendor's design). It's the lowest common denominator. And that's fine for simple stuff... quick and shipping is better than elegant and still in the lab.
<re_irc> <@firefrommoonlight:matrix.org> Thank you for the insight!
<re_irc> <@firefrommoonlight:matrix.org> With what you said in mind, I suppose an adv of systick is it works the same on any Cortex-M MCU (or maybe any ARM MCU)
<re_irc> <@firefrommoonlight:matrix.org> My use cases here are #1: timestamps for CAN nodes, and #2: Logging points for use in a flight control model. Neither are the cononical OS threading tick. I'm happy with the timer approach I posted. It sounds like we've covered all 3 cases here! Maybe the RTC would be better though that you hint at; Can give you actual seconds, minutes etc from hardware. I'm wrapping/interrupting twice a second with the current...
<re_irc> ... setup (Somewhat arbitrary choice). Big upgrade from systick, but that 512s is even longer!
<re_irc> <@ryukenx:matrix.org> Hi, I have C library bindings in Rust for WASM3 which runs on cortex m using cc and bindgen, however when I include the memory.x file included cortex-m-quickstart and use -Tlink.x as a flag, the memory layout makes it so the c library has undefined symbols. It compiles without the C library and with the C library but not using the link.x flag. Any ideas on how to fix this so the C library uses the proper memory layout for...
<re_irc> ... cortex m so that the Rust compiler is able to resolve the symbols?
<re_irc> <@ryukenx:matrix.org> Hi, I have C library bindings in Rust for WASM3 which runs on cortex m using cc and bindgen, however when I include the memory.x file included in the cortex-m-quickstart repo and use -Tlink.x as a flag, the memory layout makes it so the c library has undefined symbols during Rust compilation. The Rust project compiles without the C library and with the C library but not using the link.x flag. Any ideas on how to fix this so...
<re_irc> ... the C library uses the proper memory layout for cortex m so that the Rust compiler is able to resolve the symbols during linking?
cr1901_ has joined #rust-embedded
cr1901 has quit [Ping timeout: 248 seconds]
<re_irc> <@ryan-summers:matrix.org> DauntlessAdvent: Is rust properly wrapping extern symbols in an extern C tag?
<re_irc> <@ryan-summers:matrix.org> I.e. how are you binding to the c code from rust?
<re_irc> <@sourcebox:matrix.org> : You've already used my systick crate, so you can see that you get a lot for free without having to utilize any other peripheral. It simply works even on the smallest MCU. I would not worry too much about the interrupt in bothering the MCU as it's priority is typically the lowest. Yes, with low power, it's not that nice, that's a valid point. It would be nice to have more resolution so that we overflow occurs less often,...
<re_irc> ... but we have to live with it as it is.
rardiol has joined #rust-embedded
IlPalazzo-ojiisa has joined #rust-embedded
<re_irc> <@sourcebox:matrix.org> Btw, I had a look at several C HALs (STM32, ESP32, nrf, Arduino). All of them provide functions to get the time elapsed since boot with a certain granularity. I would expect that Rust HALs do the same, maybe feature-gated for alternatives like SysTick, RTC).
<re_irc> <@ryan-summers:matrix.org> : This implies using system resources (i.e. using a timer, setting up ISRs). Doing this without being explicitly asked for is a hard no from me, but I like the idea of allowing it to be instantiated. That being said, I'm unsure this belongs at the HAL layer personally
<re_irc> <@ryan-summers:matrix.org> (I don't know if arduino does this for you under the hood or if you have to explicitly set it up)
<re_irc> <@sourcebox:matrix.org> : Therefore I said, it can be feature gated and even disabled by default.
<re_irc> <@ryan-summers:matrix.org> I see no issue in just adding it as a function that the user optionally sets up :)
<re_irc> <@datdenkikniet:matrix.org> how would feature gating it be any different/better than instantiating it "manually"? I.e. through the "Monotonic" trait in RTIC?
<re_irc> <@datdenkikniet:matrix.org> * "manually" by adding some function/code?
<re_irc> <@ryan-summers:matrix.org> Also, anything that actually needs an ISR (like a timer overvlow) cannot be completely abstracted by the HAL from what I understand
<re_irc> <@datdenkikniet:matrix.org> +impls of
<re_irc> <@ryan-summers:matrix.org> Since the ISR always has to live in user end app
<re_irc> <@ryan-summers:matrix.org> * apps
<re_irc> <@datdenkikniet:matrix.org> * function/code in the user application?
<re_irc> <@datdenkikniet:matrix.org> * E.g.
<re_irc> <@sourcebox:matrix.org> Then the user has to setup the ISR and call a certain function from the HAL inside it.
<re_irc> <@ryan-summers:matrix.org> Yeah, it's just unfortunate because that's a massive footgun
<re_irc> <@ryan-summers:matrix.org> If you don't call it, everything _appears_ to work but your time is always wrong. Or you could handle the overflow flag when checking time, but you never know how many times it overflowed
<re_irc> <@ryan-summers:matrix.org> Time is a tricky business on embedded :P
<re_irc> <@sourcebox:matrix.org> Embedded is a tricky business in general, you will never be able to make it fully idiot-proof.
<re_irc> <@ryan-summers:matrix.org> No, but some of the HALs have done a pretty nice job in comparison to C. I just updated from 0l.8 to 0.15 of the F4 HAL and it does a lot of great things with AF pins
<re_irc> <@ryan-summers:matrix.org> Now I can purge any thought of which AF mode I need, I just say "into_alternate()" and the type system figures out what alternate mode I need
<re_irc> <@sourcebox:matrix.org> Yes, that's a neat thing and will prevent errors because messing up numbers is common and sometimes hard to find.
<re_irc> <@sourcebox:matrix.org> But for time, I don't get the point why C HALs can do it and it works for lor of applications whereas here with Rust it's discussed to death.
<re_irc> <@ryan-summers:matrix.org> Mainly because most people don't want it IMO
<re_irc> <@ryan-summers:matrix.org> C HALs take a different approach (and have different capabilities) than Rust HALs. In C, they generally do a lot of things for you out of the box and take over system resources
<re_irc> <@ryan-summers:matrix.org> Rust HALs do _not_ do that by design, so they cannot take ownership of things like ISR vectors
<re_irc> <@ryan-summers:matrix.org> Because the user has to opt-in.
<re_irc> <@ryan-summers:matrix.org> As a professional embedded guy, this is why I am willing to use Rust HALs but hold C HALs away with a 10 foot stick
<re_irc> <@ryan-summers:matrix.org> Esp. for timing critical systems, it's _very_ important to know what every interrupt in your app is, and C HALs have a tendency to try to hide that from you
<re_irc> <@sourcebox:matrix.org> But enabling a feature is basically an opt-in.
<re_irc> <@dalepsmith:matrix.org> : Couldn't agree with you more
<re_irc> <@sourcebox:matrix.org> It has to be clearly decumented what implication that has.
<re_irc> <@ryan-summers:matrix.org> I don't know if it's technically possible to actually have an ISR bound in the HAL crate because of the architecture of Rust crates
<re_irc> <@ryan-summers:matrix.org> But if you want to make a timing mechanism in a HAL with a callback function for the user to call from user space, by all means, make a PR
<re_irc> <@ryan-summers:matrix.org> It gets discussed to death because no one just does it ;)
<re_irc> <@ryan-summers:matrix.org> Try it out and see what you run into :) I'm always an advocate for getting your hands dirty
<re_irc> <@sourcebox:matrix.org> I'm already aware of that and my patience is not that endless.
<re_irc> <@ryan-summers:matrix.org> Well, if you want someone else to do it for you, that's generally paid for contract work :)
rardiol has quit [Quit: https://quassel-irc.org - Chat comfortably. Anywhere.]
<re_irc> <@sourcebox:matrix.org> I don't want to have someone do it for me, I have already working solutions. It's about getting a better ecosystem overall.
<re_irc> <@ryan-summers:matrix.org> I guess I'm confused as to why you're impatient then
<re_irc> <@ryan-summers:matrix.org> I think it's worth pointing out that a _lot_ of open sourced development is actually funded by contracts underneath things that allow engineers to publish the work openly as well. Not all of it is charity work
<re_irc> <@sourcebox:matrix.org> Yes, that's right.
<re_irc> <@sourcebox:matrix.org> But I don't get the point here.
<re_irc> <@ryan-summers:matrix.org> My point is, if you want this feature, you can either do it yourself, or pay someone to do it. Asking others to do it for free is often a tall order because people are busy
<re_irc> <@sourcebox:matrix.org> I always offer help if I'm able to do it, but there has to be a consensus about the goal. And I don't see it here.
<re_irc> <@ryan-summers:matrix.org> Honestly, I think this is one of the places where it's best to just try doing something and see how it turns out. Everyone's always willing to offer a million opinions (myself included!)
<re_irc> <@sourcebox:matrix.org> I have a crate on GH that does give the functionality with SysTick on Cortex-M. Anyone is invited to take the code or propose changes to it.
mrtazz has joined #rust-embedded
dc740 has joined #rust-embedded
dc740 has quit [Remote host closed the connection]
emerent has quit [Ping timeout: 248 seconds]
emerent has joined #rust-embedded
<re_irc> <@hugolgst:matrix.org> Hey guys, not sure what I am doing wrong but I am trying to follow this doc to initiate an I2C connection and literally nothing's happening I don't know why (LED blinking works perfectly when I do not do .enable())
<re_irc> let mut peripherals = Peripherals::take().unwrap();
<re_irc> let mut clocks = GenericClockController::with_internal_32kosc(
<re_irc> let core = CorePeripherals::take().unwrap();
<re_irc> &mut peripherals.PM,
<re_irc> peripherals.GCLK,
<re_irc> &mut peripherals.SYSCTRL,
<re_irc> &mut peripherals.NVMCTRL,
<re_irc> );
<re_irc> let pins = Pins::new(peripherals.PORT);
<re_irc> let mut pa02: Pin<PA02, PushPullOutput> = pins.pa02.into();
<re_irc> let mut delay = Delay::new(core.SYST, &mut clocks);
<re_irc> let pads = Pads::new(pins.pa08, pins.pa09);
<re_irc> // Configure GCLK for 10 MHz
<re_irc> let mut i2c = Config::new(&peripherals.PM, peripherals.SERCOM2, pads, 10.mhz()).baud(1.mhz()).enable();
<re_irc> <@hugolgst:matrix.org> Would you any of you have an idea?
<re_irc> <@firefrommoonlight:matrix.org> I think the systick count would be a good addition to the "cortex-m" crate, and HAL is a good spot for it for use with timers or the RTC
<re_irc> <@firefrommoonlight:matrix.org> The setup I posted above uses HAL to get the time since the timer's run, and user-code to get the time-from-overlaps
<re_irc> <@firefrommoonlight:matrix.org> So, a hybrid approach
<re_irc> <@firefrommoonlight:matrix.org> The setup I posted above uses HAL to get the time since the timer's start, and user-code to get the time-from-overlaps
dc740 has joined #rust-embedded
cr1901_ is now known as cr1901
<re_irc> <@sourcebox:matrix.org> It would have the advantage to be implemented only once, otherwise each HAL would need to do it on its own with basically similar code.
rardiol has joined #rust-embedded
<re_irc> <@djc:mozilla.org> I’m an embedded noob with a nRF52840 dongle
<re_irc> <@k900:0upti.me> Hi embedded noob with a nRF52840 dongle, I'm dad
<re_irc> <@djc:mozilla.org> Where do I go to find out how hardware on the dongle is connected to the nRF52840?
<re_irc> <@djc:mozilla.org> Like, which pin is the LED connected too?
<re_irc> <@k900:0upti.me> Probably wherever you got the dongle from
<re_irc> <@k900:0upti.me> They should have schematics
<re_irc> <@k900:0upti.me> Or at least a datasheet
<re_irc> <@djc:mozilla.org> I found schematics but not a datasheet
<re_irc> <@k900:0upti.me> Well if you have the schematics, you can just look at those
<re_irc> <@k900:0upti.me> It's probably a CAD file of some sort, so you might have to download the CAD tool the vendor used to actually open it
<re_irc> <@djc:mozilla.org> Ah but it turns out I have never looked at schematics before so this isn’t that easy for me
<re_irc> <@k900:0upti.me> LEDs generally look like, uh, "-->|"-"
<re_irc> <@k900:0upti.me> It might be easier to look for those and then trace the connections from them to the SoC
<re_irc> <@k900:0upti.me> Here, I googled a non-shitty picture
<re_irc> <@dirbaio:matrix.org> djc: Nordic infocenter -> nrf52840 -> nrf52840 dongle -> hardware description
<re_irc> <@ryan-summers:matrix.org> Nordic's docs take some getting used to even for the experienced, was fighting with the nrf9160 docs yesterday
<re_irc> <@dirbaio:matrix.org> it's certainly clunky, but i'll take HTML docs over PDF docs any day
<re_irc> <@djc:mozilla.org> : awesome, thanks!
<re_irc> <@dirbaio:matrix.org> wish more manufacturers did it...
<re_irc> <@ryan-summers:matrix.org> Yeah agreed :)
<re_irc> <@admin:orangemurker.com> : Same!
<re_irc> <@jamesmunns:beeper.com> Tbf I prefer pdfs, tho if someone made a single page html doc I'd prefer that
<re_irc> <@jamesmunns:beeper.com> Link behavior for Nordics pages are bizarre, and being able to do a plaintext doc full text search is so nice
<re_irc> <@jamesmunns:beeper.com> But honestly both the pdfs and website from Nordic are pretty good
brazuca has joined #rust-embedded
brazuca has quit [Quit: Client closed]
<re_irc> <@djc:mozilla.org> okay, I have more n00b questions: so I'm writing my first blinky leds thing for the nRF52840, and in https://github.com/ferrous-systems/embedded-trainings-2020/blob/main/boards/dk/src/lib.rs#L200 I see all this clock and RTC setup stuff
<re_irc> <@djc:mozilla.org> is that necessary, and if so why?
<re_irc> <@djc:mozilla.org> should I just cargo cult this along and don't worry about it? (I'd rather understand what this code is doing and why)
<re_irc> <@djc:mozilla.org> (I would like to use the "TIMER" peripheral but it's not clear to me if that somehow depends on the RTC/clocks stuff)
dc740 has quit [Remote host closed the connection]
<re_irc> <@thejpster:matrix.org> Looking at at the RTC interrupt shows that it increments OVERFLOWS. Further searching on that variable shows that is required by the uptime function.
<re_irc> <@thejpster:matrix.org> The clock setup will be run off the external crystal. These are usually higher accuracy than the default internal RC oscillators and very often required for USB Device mode to work. Which is part of the training course.
<re_irc> <@thejpster:matrix.org> A timer will usually work regardless of which clock source you are using, but on some systems you need to set up specific extra clock sources for specific timers, or do some routing of the clock signals. STM32 do this and it’s sufficiently complicated that CubeMX has a whole GUI for it. I can’t remember if the nRF also does anything similar - possibly not.
<re_irc> <@peter9477:matrix.org> Interesting that that code does a curr = load() then a store(curr + 1) rather than just using fetch_add(1)... is there something I'm missing that makes load-then-store better?
<re_irc> <@thejpster:matrix.org> The clock setup will be to run off the external crystal. These are usually higher accuracy than the default internal RC oscillators and very often required for USB Device mode to work. Which is part of the training course.
<re_irc> <@thejpster:matrix.org> atomic fetch-add isn’t available on Cortex-M0 so maybe the author was thinking of the nRF51. Or maybe they reasoned that no one else ever writes to that variable, so it’s fine.
<re_irc> <@peter9477:matrix.org> Assuming fetch-add manages to become a single cpu instruction, it's likely it's at least faster I would think, which is always worth striving for in an interrupt.
<re_irc> <@peter9477:matrix.org> but yeah, possibly the code was originally not for cortex-m4
<re_irc> <@thejpster:matrix.org> I think it’s a regular add wrapped in instructions which loop if an interrupt has occurred?
<re_irc> <@thejpster:matrix.org> I read this in Mara’s excellent book, but that was Aarch64 mode on an Armv8-A
<re_irc> <@peter9477:matrix.org> I guess I should check the assembly code generated for my own use of fetch_add() before I assume it's any good...
<re_irc> <@thejpster:matrix.org> Note that a RISC chip can’t add 1 to a value in memory. It’s always load, operation, store.
<re_irc> <@adamgreig:matrix.org> on armv7 with the exclusive operations, yea, it's like "ldrex mem into r1, add one to r1, strex r1 to mem, if failed: retry"
<re_irc> <@peter9477:matrix.org> I thought this was about the nrf52840...
<re_irc> <@adamgreig:matrix.org> certainly not one instruction
<re_irc> <@peter9477:matrix.org> : Yikes!
<re_irc> <@adamgreig:matrix.org> it's not that bad on balance I don't think
<re_irc> <@adamgreig:matrix.org> as says, no risc architecture will have an instruction to change memory directly, their whole deal is reading memory into register, modifying register, writing back to memory
<re_irc> <@peter9477:matrix.org> I guess practically speaking that would never need to retry in the simplest case, but the non-deterministic nature of it is bothersome.
<re_irc> <@peter9477:matrix.org> Are you guys saying Cortex-M4 is considered to be RISC?
<re_irc> <@adamgreig:matrix.org> i think that's a pretty widely agreed opinion yea
<re_irc> <@peter9477:matrix.org> heh... never even noticed that. go figure.
<re_irc> <@thejpster:matrix.org> It’s an Arm core.
<re_irc> <@peter9477:matrix.org> "ARM is a family of reduced instruction set computer (RISC) instruction set architectures for computer processors, configured for various environments."
<re_irc> <@thejpster:matrix.org> Like the one they literally put in a computer called the RiscPC
<re_irc> <@adamgreig:matrix.org> ARM used to stand for advanced risc machines, right?
<re_irc> <@thejpster:matrix.org> Acorn RISC Machines first ;)
<re_irc> <@peter9477:matrix.org> Probably. I certainly spent most of my career on non-ARM stuff... this slipped by me. Hilarious really.
<re_irc> <@adamgreig:matrix.org> not any more, but I think it's uncontroversial that the cortex-m4 is risc
<re_irc> <@adamgreig:matrix.org> if you liked that, you'll love that the three types of core arm design are cortex-a, cortex-r, and cortex-m
<re_irc> <@thejpster:matrix.org> Wait until you find out there’s a document called the “Arm ARM ARM”
<re_irc> <@thejpster:matrix.org> And the cut down version of Arm is called … Thumb.
<re_irc> <@adamgreig:matrix.org> https://rust.godbolt.org/z/6T9PoqoM6
<re_irc> <@peter9477:matrix.org> ; Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),
<re_irc> 3b2da: 3001 addsr0, #1
<re_irc> 3b2d6: e851 0f18 ldrexr0, [r1, #96]
<re_irc> 3b2dc: e841 0218 strexr2, r0, [r1, #96]
<re_irc> 3b2e0: 2a00 cmpr2, #0
<re_irc> 3b2e2: d1f8 bne0x3b2d6 <hwtest::hal::pdm::Pdm::on_interrupt::hd276207c9b86caec+0x6> @ imm = #-16
<re_irc> 3b2e4: 4814 ldrr0, [pc, #80] @ 0x3b338 <$d.735+0x4>
<re_irc> Yep, definitely nowhere near the one instruction I blithely assumed the atomics were mostly managing to achieve.
<re_irc> <@jannic:matrix.org> And this assumes that "Relaxed" is fine - otherwise you get additional "dmb" instructions.
<re_irc> <@peter9477:matrix.org> all that is basically a fetch_add(1, Relaxed)
<re_irc> <@peter9477:matrix.org> yep
<re_irc> <@adamgreig:matrix.org> it's still better than like, entering a critical section or something
<re_irc> <@adamgreig:matrix.org> and it does provide some good guarantees... just not that it will complete in constant time, heh
<re_irc> <@adamgreig:matrix.org> or ever.....
<re_irc> <@peter9477:matrix.org> Here's the load+store for comparison, minus the loop:
<re_irc> ; Relaxed => intrinsics::atomic_load_relaxed(dst),
<re_irc> ; INT_COUNT.store(count + 1, Ordering::Relaxed);
<re_irc> 3b2d6: 6e08 ldrr0, [r1, #96]
<re_irc> 3b2d4: 4915 ldrr1, [pc, #84] @ 0x3b32c <$d.735>
<re_irc> 3b2d8: 3001 addsr0, #1
<re_irc> ; Relaxed => intrinsics::atomic_store_relaxed(dst, val),
<re_irc> 3b2da: 6608 strr0, [r1, #96]
<re_irc> <@adamgreig:matrix.org> really only that second ldr should count, the first is loading the address into r1 which had to happen before your earlier snippet too
<re_irc> <@adamgreig:matrix.org> but yea, it's load, add, store
<re_irc> <@peter9477:matrix.org> Yeah, I didn't try pruning them to match exactly.
<re_irc> <@peter9477:matrix.org> I have opt='z' so I figured it didn't matter too much, just wanted the basic idea.
<re_irc> <@adamgreig:matrix.org> if it's not a contended lock, ldrex/add/strex/cmp/bne is only going to be a little longer than ldr/add/str, especially if the str has to wait at all for memory
<re_irc> <@adamgreig:matrix.org> so if it's supported on your hardware and it's the semantics you want, no reason not to use fetch_add where it's convenient really?
<re_irc> <@adamgreig:matrix.org> i guess you could benchmark if it was a very important hot loop
<re_irc> <@peter9477:matrix.org> I doubt any of my current uses are either hot or matter either way, but I like to understand the tools I'm working with, even if just to avoid wasting time debugging things like "why the heck does this interrupt take different amounts of time to run sometimes"?
<re_irc> <@adamgreig:matrix.org> yea, totally!
<re_irc> <@peter9477:matrix.org> thanks for the teaching guys. :)
IlPalazzo-ojiisa has quit [Quit: Leaving.]
radens has quit [Quit: Connection closed for inactivity]