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
_whitelogger has joined #rust-embedded
<JamesMunns[m]> It's pretty common for speed optimized memcpy/moves to be largeish. It might be a good place to use Dion's optimize for size setting to provide a less optimized and smaller impl
<JamesMunns[m]> Speed ones usually do a lot of work to handle alignment and striding to make large copies as fast as they can, or do unrolling at the start and end for unaligned copies
<JamesMunns[m]> vs a naiive byte copy that might end up with 1/4 the throughput on large copies
<M9names[m]> the intrinsics in compiler_builtins are linked in such a way that if you define these in your project (or in a crate that your project uses) you can override the default impls.
<M9names[m]> rp2040-hal uses this to use the hand-optimised library functions that live in the RP2040 mask ROM (which also saves hitting the QSPI interface).
<M9names[m]> embassy-rp does this too ^
okhsunrog[m] has joined #rust-embedded
<okhsunrog[m]> <M9names[m]> "the intrinsics in compiler_built..." <- > <@9names:matrix.org> the intrinsics in compiler_builtins are linked in such a way that if you define these in your project (or in a crate that your project uses) you can... (full message at
<M9names[m]> It's not very exciting tbh.
<M9names[m]> One caveat of this approach is that you will want the memcpy/memmove replacements to be written in assembly to avoid the compiler replacing your implementations with calls to the built-in memcpy/memmove
jfsimon1981a has joined #rust-embedded
jfsimon has quit [Ping timeout: 276 seconds]
_whitelogger has joined #rust-embedded
dcz[m] has joined #rust-embedded
<dcz[m]> why is there no core::rc?
<M9names[m]> because it's in alloc, just like box
<dcz[m]> oh, right
pcs38 has joined #rust-embedded
Yann[m] has quit [Quit: Idle timeout reached: 172800s]
jsolano has quit [Quit: leaving]
jsolano has joined #rust-embedded
<KevinPFleming[m]> <JamesMunns[m]> "It's pretty common for speed..." <- thanks! as it turns out setting opt-level to `z` instead of `s` causes `memmove` to disappear completely, but `memcpy` is still there at the same size.
hrmny[m] has quit [Quit: Idle timeout reached: 172800s]
jason-kairos[m] has joined #rust-embedded
<jason-kairos[m]> After recently updating to the latest rustc I was amazed to see what 'seemed like' 3-4kb shaved off of a 15kb binary running inside of a MCU with 16kb of flash. (even though I knew to expect it, I didn't think it would be so much)
<KevinPFleming[m]> yes, it's impressive
<KevinPFleming[m]> is it possible to construct a StaticCell holding a [u8; 128] (raw array)?
<KevinPFleming[m]> i'm currently putting a `heapless::Vec::<u8, 128>` in the`StaticCell` so that it can be used as a DMA buffer, but it doesn't need to be a `Vec`, just a bare array
<KevinPFleming[m]> * in the `StaticCell` so
<KevinPFleming[m]> ahh... sure, that would make sense. i'll leave this alone for now, the few additional bytes used by Vec are not important at the moment :-)
<JamesMunns[m]> <KevinPFleming[m]> "is it possible to construct a ..." <- Yes, you can also use a const static cell to avoid the init cost
<JamesMunns[m]> <JamesMunns[m]> "Yes, you can also use a const..." <- One important thing to remember is that if you take a slice of an empty vec, it's empty.
<JamesMunns[m]> This seems "duh", but a lot of people forget and pass an &mut borrow of a vec and their code crashes in a fun way because it receives an empty slice instead of a 128 byte one like they expect :D
<JamesMunns[m]> JamesMunns[m]: So if you want to fill it with dma, you'd need to use unsafe ptr methods and set len, or pre-fill it before you use dma and then overwrite those values
FreeKill[m] has joined #rust-embedded
<FreeKill[m]> Is there a library that can generate a parser from an input grammar that's suitable for embedded?
<FreeKill[m]> I've seen pest and lalrpop, but it seems they still use alloc even if you switch off std
<dcz[m]> I used nom, although if you do debug printing, there's a lot of that
<FreeKill[m]> nom can't generate it's parser from a grammar can it?
<dcz[m]> I don't remember how I provided the grammar
<therealprof[m]> <KevinPFleming[m]> "thanks! as it turns out setting..." <- You may want to avoid `z`, it tends to randomly break stuff and sometimes results in larger binaries, too, due to non-ideal inlining parameters.
<dcz[m]> you need to import a crate that provides this symbol
<dcz[m]> I solved it by checking which crate pulls in critical-section (cargo tree) and then by figuring out what the purpose of that was
<JamesMunns[m]> <FreeKill[m]> "nom can't generate it's parser..." <- Correct, nom is a parser combinator, instead of a grammar based generator
<JamesMunns[m]> dcz[m]: Cortex m can do this if you have a single core processor
<therealprof[m]> dcz[m]: Huh? Well, I know it's called by `defmt`, I just don't know why I need to muck with it, I never had to do that before.
<KevinPFleming[m]> <JamesMunns[m]> "So if you want to fill it with..." <- Yes exactly, and I just opened a PR for embassy-stm32 to add some assertions which would have told me I was doing that!
<JamesMunns[m]> therealprof[m]: Defmt takes a cs because you could log from interrupts
<therealprof[m]> Somehow all the defmt documentation seems to be out-of-date.
<therealprof[m]> JamesMunns[m]: That is perfectly fine but how do I get rid of the linker error?
<JamesMunns[m]> It uses an extern symbol instead of a dep because the user chooses which impl to use
<therealprof[m]> Oh, it's a cortex-m feature now.
<JamesMunns[m]> For example, rp2040 needs a dual core version that uses the API lock peripheral, while single core CPUs can just disable interrupts
<therealprof[m]> Thanks, I completely forgot about that.
<JamesMunns[m]> s/API/spin/
<JamesMunns[m]> therealprof[m]: Definitely send a PR for where you looked for that info and didn't find it, if you stumbled there, others will too
<therealprof[m]> First I need to get it to work. Somehow it doesn't like me.
<JamesMunns[m]> We always should add more breadcrumbs for docs wherever we can, not everyone knows the right place to look.
<M9names[m]> <therealprof[m]> "Huh? Well, I know it's called by..." <- You used to not have to do this because most of the ecosystem used to use cortex-m:: critical-section.
<M9names[m]> Was great if you were using one of those cores, pretty terrible for anyone else
<therealprof[m]> I added use defmt_rtt as _; (which is missing from the docs) but still can't get any output.
<therealprof[m]> M9names[m]: Yes, I know. I just forgot that this turned into a `cortex-m` feature. I'm reviving a really old HAL crate and that of course didn't bother with the feature.
<M9names[m]> You need to set DEFMT_LOG envvar
<therealprof[m]> M9names[m]: I'm doing that.
<JamesMunns[m]> M9names[m]: And also do a clean if you set it in `.cargo/config.toml`, unless the fix for that landed in cargo, since deps won't "notice" the env var Change there and recompile
<therealprof[m]> I'm setting it on the CLI and it doesn't work. Also clean didn't help.
<JamesMunns[m]> Can you push your current project somewhere? I can take a peek
<JamesMunns[m]> Other thing you could miss: adding the defmt linker section
<therealprof[m]> Okay, checking.
<therealprof[m]> <JamesMunns[m]> "Other thing you could miss..." <- That was the issue 🤦
<dngrs[m]> on an abstract level it's really a bummer operations like "add defmt to this project" require multiple steps and error diagnosis can get stuck at "go through all of them"
<dngrs[m]> * on an abstract level it's really a bummer operations like "add defmt to this project" require multiple steps and error diagnosis tends to be "go through all of them" because no diagnostics
<JamesMunns[m]> yep. but libraries can't provide linker fragments or set env vars, and unused deps get linked out, and defmt requires all of thise to work, so not sure what else could be done.
<dngrs[m]> yeah, not saying I have a solution
<JamesMunns[m]> agreed it's Not Great, for sure
<dngrs[m]> it just sometimes feels to me we (Rust at large) are stuck in local maxima
<JamesMunns[m]> takes energy to push past a band gap, unfortunately, and we don't have very many cargo and rustc devs to help push us down and up the next hill.
<dngrs[m]> yip yip
<M9names[m]> also still a lot of problems to solve that don't require such heroics
<dngrs[m]> * on an abstract level it's really a bummer operations like "add defmt to this project" require multiple steps and error hunting tends to be "go through all of them" because no diagnostics
<JamesMunns[m]> honestly the ability for deps to change linker settings has somewhat frightening implications for safety lmao
<JamesMunns[m]> despite it being very compelling and convenient for embedded
<dngrs[m]> petition to add unsafe to Cargo.toml
<JamesMunns[m]> honestly, they've started adding unsafe to linker attributes in general, which is a good step
<dngrs[m]> SGTM!
<JamesMunns[m]> you probably wouldn't get too much argument if you had a good way of declaring unsafe cargo features too
<dngrs[m]> yeah, I wasn't entirely kidding 😬
<JamesMunns[m]> you could do fun things like force a segfault by putting things like atomic statics in a read only section then writing to it on desktop
<JamesMunns[m]> and probably subtler ones like overriding symbols and such
<JamesMunns[m]> (requires unsafe in 2024)
<dngrs[m]> on a less moonshot brain level I could envision a tool that everything that makes "a Rust project" (env, .cargo/config.toml, etc) and checks/sets all that's required. Not 100% watertight when it comes to env vars but might still be worth it? dunno. In general (zooming out from defmt) it feels to me that having several disconnected places to "configure" a "project" is tedious and error prone
<jason-kairos[m]> JamesMunns[m]: That's actually really cool. I'd bet with some creativity that would allow one do to a bunch of neat things on embedded (I suppose defmt does it, and so does HubrisOS)
<JamesMunns[m]> > I'd bet with some creativity that would allow one do to a bunch of neat things on embedded
<JamesMunns[m]> in general writing to mapped flash regions cause some kind of access violation/hard fault on embedded too
<JamesMunns[m]> instead of a SIGSEGV
<JamesMunns[m]> (assuming `.text` is mapped to flash, defmt is mapped to non-flashed regions, idk what the linker or code at runtime would make of you writing to defmt "addrs")
<JamesMunns[m]> fwiw, this is mostly a fun party trick, before 2024 all linker stuff was "well if you decide to shoot yourself in the foot, have fun", in 2024 all linker-oriented attrs now require unsafe, because they are
ouilemur has quit [Quit: WeeChat 4.6.2]
<JamesMunns[m]> (the syntax for 2024 is `#[unsafe(link_section = ".text")]`)
<JamesMunns[m]> but yeah, "morally" we're putting r/w data in a r/o section, so it definitely is breaking the rules.
<dngrs[m]> lol I missed the (...) button where you set the edition to 2021. I kept scratching my head re "where IS the unsafe???"
<dngrs[m]> (yeah it's also in the URL parameters but who reads those)
<JamesMunns[m]> but if your `.text` was in RAM and you didn't set up an MPU/MMU, it would *work*, but still be *wrong*, and could cause UB elsewhere I suppose.
<JamesMunns[m]> btw maybe interesting for folks if you have an embedded target not supported by LLVM but is supported by gcc: https://old.reddit.com/r/rust/comments/1ktph3c/media_the_gcc_compiler_backend_can_now_fully/
<JamesMunns[m]> I'm sure "works" is still a work in progress, but it's progress nonetheless!
<JamesMunns[m]> Folks in the comments said they were able to get a minimal m68k hello world going, which is a good sign
lethalbit[m] has joined #rust-embedded
<lethalbit[m]> Finally, I can run Rust on my VAX/11 :v
Lumpio[m] has quit [Quit: Idle timeout reached: 172800s]
<JamesMunns[m]> ooh, if it is a real 32-bit target, that's interesting :D
<JamesMunns[m]> I think some of the vaxen have weird memory widths and stuff?
<lethalbit[m]> The PDP yeah, but I think most VAX were a log2 width
<JamesMunns[m]> https://faultlore.com/blah/rust-layouts-and-abis/ goes over some assumptions that *probably* need to be true for most of Rust to actually work
<lethalbit[m]> so no UNIVAC 418 then, RIP, lol
<JamesMunns[m]> yeah, and probably no goofy dsp targets that have 16-bit bytes
<lethalbit[m]> womp womp
<JamesMunns[m]> RIP TI
<dngrs[m]> recently read about rust2c to solve the issue of "Rust on platforms you probably won't ever be able to natively target, given the lack of LLVM"
<JamesMunns[m]> people on the internet sure do be having opinions
<dngrs[m]> it's mad science I can get behind, like if you wanna target the original game boy but still use Rust, you now can
<dngrs[m]> practical usefulness: limited
BradleyNelson[m] has quit [Quit: Idle timeout reached: 172800s]
dirbaio[m] has quit [Quit: Idle timeout reached: 172800s]
i509vcb[m] has joined #rust-embedded
<i509vcb[m]> <dngrs[m]> "this was the post: https://..." <- I've considered whether it would be practical to hit an 8086 target but the memory addressing there is very weird
<i509vcb[m]> The only real safe way to do it is to limit yourself to a fixed segment
<i509vcb[m]> Which means no more than 64k of memory
<therealprof[m]> Meh... stm32f0xx-hal is very broken. Clock rate calculation is all over the place, I2C read/write is wonky.
<therealprof[m]> Probably time to retire it.
<JamesMunns[m]> embassy-stm32 supports f0, is actively maintained, and has blocking support even if you aren't interested in async, so yeah, I'm not sure if there are any compelling reasons to continue maintenance on the project, if the maintainers of the f0xx-hal aren't active/interested.
<therealprof[m]> Well, I'm the maintainer and was looking into getting it up-to-date.
<therealprof[m]> Problem is: I thought I could fix it in order to fix embassy... because that is also broken.
<therealprof[m]> Didn't want to start debugging stuff in unknown code with hardware in uncertain condition.
<JamesMunns[m]> yeah, fair. what bit is broken btw?
<therealprof[m]> I don't know, it doesn't transmit anything. Also the transaction() method has a big honking todo()! in the implementation.
<therealprof[m]> So drivers using that will happily panic.
Max[m] has joined #rust-embedded
<Max[m]> <Noah[m]> "should work :)" <- allright, thanks
<therealprof[m]> (this is how the rabbit hole chase started in the first place, I was reviewing a PR to add e-h-1 support to stm32f0xx-hal, which was flagged by another reviewer as not being sufficient due to having a todo!() in the same place)
<therealprof[m]> <therealprof[m]> "I don't know, it doesn't..." <- The non-transmission thing might also be a bug in ariel-os, not sure. There's some basic I2C support, but it's only tested by a test case, there's no example code.
<therealprof[m]> Does anyone have a good solution for passing build flags/features into neovim for rust-analyzer etc.?
<thejpster[m]> I was watching Rusty Bit's latest YouTube video about building a CO2 sensor. It's absurdly excellent, as always.
<thejpster[m]> But I was sure that he took a PAC singleton from embassy-st and then passed it to the I2C driver. I thought embassy PACs and HALs didn't do that?
<thejpster[m]> Yeah, he's passing a value of type TWISPI0 into the I2c driver
dirbaio[m] has joined #rust-embedded
<dirbaio[m]> The pac doesn't have singletons, the Hal does
<thejpster[m]> oh, he's using embassy-nrf.
<JamesMunns[m]> <therealprof[m]> "Does anyone have a good solution..." <- I *think* there is some kind of JSON project config file you can set for r-a, I never use it tho (I usually hackily edit the `defaults` of cargo toml instead), but should
<therealprof[m]> Yeah, that's rather limited though. Also I'd like to be able to switch quickly between different configurations.
<thejpster[m]> who do we need to poke in the project to merge https://github.com/rust-lang/team/pull/1838? I noticed the github teams and the rust-lang/team repo were out of sync with the rust-embedded/wg repo.
<JamesMunns[m]> there's a specific `team` reviewers group IIRC
<therealprof[m]> Good question, usually people just pick it up. If I need to get things moving quicker I usually ping someone who knows me, like Pietro... I've had some weird "and who are you?" discussions in the past.
<JamesMunns[m]> I think there was some discussion to allow team leads to approve prs for changes to their teams/subteams, but I might be confusing that with something else because I can't find it
<therealprof[m]> In this case I'd probably have repinged Kobzol but I think it would be polite to not be too pushy over a weekend. 😉
<JamesMunns[m]> in-impl now it seems: https://github.com/rust-lang/team/issues/1759
<KevinPFleming[m]> lazy Matrix here... is anyone aware of a proposal to allow default features to be defined in profiles in Cargo.toml?
Emkanea[m] has quit [Quit: Idle timeout reached: 172800s]
Noah[m] has quit [Quit: Idle timeout reached: 172800s]
<dngrs[m]> like, have different defaults for debug vs release?
<KevinPFleming[m]> yes, exactly
<dngrs[m]> this sounds dangerous
<therealprof[m]> PSA: I found this for the neovim users out there: https://github.com/folke/neoconf.nvim. Seems to work great... Doesn't make a difference for my particular usage though, seems rust-analyzer fails to follow too many levels of cfg-based indirection...
Emkanea[m] has joined #rust-embedded
<Emkanea[m]> I got a very weird behavior and I cant explain it ... maybe somebody has an idea. I made a device driver way back using SPI communication with EH 0.2.7 and stm32l4xx-hal 0.7.1 and it worked fine on my hardware (lets call it HW_1). I update the driver in the last few days to EH 1.0.0 and embassy-stm32 drivers. This updated device driver worked good on another hardware (letc call it HW_2). When I used the updated driver on HW_1 it
<Emkanea[m]> suprisingly did not work. The old version of the device driver still worked on HW_1 same as before. Logic analyzer trace looked good for old version on HW_1 but not quite right for HW_2. After checking everything for an hour I started to fiddle random on the configuration... and changed SPI Mode from MODE_3 (CPOL = 1 , CPHA = 1) to MODE_= (CPOL =0, CPHA = 0). Now the new device driver version worked on HW_1. But now the mystery
<Emkanea[m]> part: The old device driver used MODE_3 and the new driver on HW_2 used also MODE_3. Only new device driver on HW_1 works only with MODE_0. I mean now it works but I cant make any sense out of this behavior.
<Emkanea[m]> * I got a very weird behavior and I cant explain it ... maybe somebody has an idea. I made a device driver way back using SPI communication with EH 0.2.7 and stm32l4xx-hal 0.7.1 and it worked fine on my hardware (lets call it HW_1). I update the driver in the last few days to EH 1.0.0 and embassy-stm32 drivers. This updated device driver worked good on another hardware (letc call it HW_2). When I used the updated driver on HW_1 it
<Emkanea[m]> suprisingly did not work. The old version of the device driver still worked on HW_1 same as before. Logic analyzer trace looked good for old version on HW_1 but not quite right for the updated driver. After checking everything for an hour I started to fiddle random on the configuration... and changed SPI Mode from MODE_3 (CPOL = 1 , CPHA = 1) to MODE_= (CPOL =0, CPHA = 0). Now the new device driver version worked on HW_1. But now
<Emkanea[m]> the mystery part: The old device driver used MODE_3 and the new driver on HW_2 used also MODE_3. Only new device driver on HW_1 works only with MODE_0. I mean now it works but I cant make any sense out of this behavior.
<Emkanea[m]> * I got a very weird behavior and I cant explain it ... maybe somebody has an idea. I made a device driver way back using SPI communication with EH 0.2.7 and stm32l4xx-hal 0.7.1 and it worked fine on my hardware (lets call it HW_1). I update the driver in the last few days to EH 1.0.0 and embassy-stm32 drivers. This updated device driver worked good on another hardware (letc call it HW_2). When I used the updated driver on HW_1 it
<Emkanea[m]> suprisingly did not work. The old version of the device driver still worked on HW_1 same as before. Logic analyzer trace looked good for old version on HW_1 but not quite right for the updated driver. After checking everything for an hour I started to fiddle random on the configuration... and changed SPI Mode from MODE_3 (CPOL = 1 , CPHA = 1) to MODE_0= (CPOL =0, CPHA = 0). Now the new device driver version worked on HW_1. But now
<Emkanea[m]> the mystery part: The old device driver used MODE_3 and the new driver on HW_2 used also MODE_3. Only new device driver on HW_1 works only with MODE_0. I mean now it works but I cant make any sense out of this behavior.
vollbrecht[m] has quit [Quit: Idle timeout reached: 172800s]
<therealprof[m]> <Emkanea[m]> "I got a very weird behavior..." <- Anything relevant in the errata? Could also be slight timing variations, are MODE_0 and or MODE_3 actually correct? Maybe it's just coincidence that they work on some hardware but in reality you're supposed to use a different mode.
<Emkanea[m]> Datasheet of the IC states CPOL = 1 and CPOL = 1:
ouilemur has joined #rust-embedded
<Max[m]> <Max[m]> "allright, thanks" <- let me know if you want me to run some code
Mihael[m] has quit [Quit: Idle timeout reached: 172800s]
pcs38 has quit [Quit: leaving]
dreamcat4 has quit [Quit: Connection closed for inactivity]