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: 240 seconds]
emerent has joined #rust-embedded
starblue1 has quit [Ping timeout: 240 seconds]
starblue1 has joined #rust-embedded
<re_irc> <9names (@9names:matrix.org)> Pico is master, device is slave. So your code should set up a master.
<re_irc> i2c0 or i2c1 are fine, choose the appropriate one for the pins you are using
<re_irc> <9names (@9names:matrix.org)> > maybe the OS does the handshaking
<re_irc> It does not
explore has quit [Quit: Connection closed for inactivity]
<re_irc> <bradleyharden> Am I misunderstanding something? Isn't this function unsound?
<re_irc> <bradleyharden> A minimal example triggers Miri
<re_irc> <James Munns> Can you have two instances at the same time?
<re_irc> <James Munns> (it looks like a private method?)
<re_irc> <bradleyharden> I guess it's not unsound if you never call it more than once? But that seems extraordinary dangerous
<re_irc> <James Munns> If you can have two "&mut"s live at the same time, then yes, it'd be ub
<re_irc> <bradleyharden> And against what is usually accepted as safe
<re_irc> <James Munns> I mean, a "// SAFETY" comment would be good
<re_irc> <James Munns> it likely could be more clear when it is/isn't safe, or tweak it to make it less foot-gunny
<re_irc> <Lumpio> Well that entire library isn't exactly very well written from a safety standpoint tbh
<re_irc> <Lumpio> Shameful display
<re_irc> <James Munns> no judgement!
<re_irc> <Lumpio> Shouldn't even try to use "&mut" for anything, just pointers, it's all weird memory manipulation anyways
<re_irc> <Lumpio> * and volatile memory manipulation anywayse
<re_irc> <James Munns> Yeah, that's what I found with linked-list-allocator
<re_irc> <James Munns> getting it to pass miri was mostly "remove all the references, actually".
causal has joined #rust-embedded
<re_irc> <Mehmet Ali> Hi! I am trying to implement an embedded-storage Trait for a mock NOR Flash.
<re_irc> <Mehmet Ali> I am a bit rusty on Error Types in Rust and embedded-storage seems to have some requirements for those.
<re_irc> error[E0437]: type `Error` is not a member of trait `NorFlash`
<re_irc> <Mehmet Ali> the main error that I keep coming to is this:
<re_irc> --> flash-manager\src\lib.rs:54:5
<re_irc> |
<re_irc> <Mehmet Ali> My relevant code is this:
<re_irc> <Mehmet Ali> use embedded_storage::nor_flash::{NorFlash,ReadNorFlash};
<re_irc> use embedded_storage::nor_flash::{ErrorType,NorFlashError,NorFlashErrorKind};
<re_irc> #[derive(Debug)]
<re_irc> pub enum MockError {
<re_irc> <Mehmet Ali> Mostly copy paste from places sorta.
<re_irc> <Mehmet Ali> I guess I don't understand how an error type can be "a member" of a trait.
<re_irc> <Mehmet Ali> Any pointers?
<re_irc> <Mehmet Ali> impl NorFlash for MockNorFlash{
<re_irc> const ERASE_SIZE: usize = 4096;
<re_irc> type Error = MockError;
<re_irc> const WRITE_SIZE: usize = 4;
<re_irc> <ryan-summers> Mehmet Ali: You're hitting this error because "type Error" is not defined in the trait - you can't add it into the trait implementation because it doesn't exist for the definition
<re_irc> <ryan-summers> There's no "type Error" associated with the "NorFlash" trait directly: https://docs.rs/embedded-storage/0.3.0/embedded_storage/nor_flash/trait.NorFlash.html
<re_irc> <ryan-summers> It looks like the "Error" is assocaited with https://docs.rs/embedded-storage/0.3.0/embedded_storage/nor_flash/trait.ErrorType.html, which you're two requirements away from. Try implementing "ReadNorFlash" and then "ErrorType" for the same structure - the "type Error" would belong in the "impl ErrorType for MockNorFlash" I believe
<re_irc> <ryan-summers> I think you're making some assumptions because you're used to inheritance based languages, which rust doesn't have. Because of that, you can't impl all of the Trait chain in a single impl block
<re_irc> <ryan-summers> * Are you used to using inheritance based languages? rust doesn't have those - because
cr1901 has quit [Ping timeout: 244 seconds]
<re_irc> <Mehmet Ali> Thank you so much! Well, I guess I am not fully used to both, but yes, I might be primed by that expectation slightly.
<re_irc> <Mehmet Ali> I find Traits to be a relief, but still sometimes I am not fully versed in them, especially when there are a few to satisfy.
<re_irc> <ryan-summers> Yeah, I'll admit that it trips me up to. But I think the move away from inheritance is a great one. It removes all the boilerplate empty template classes that you get in e.g. C++
<re_irc> <ryan-summers> But the way you do it with traits is definitely a change
<re_irc> <Mehmet Ali> Yep, I always imagine inheritance forces you to build an imaginary world of yours, where it is up to you whether you can end up with stuff that is actually needed.
<re_irc> Traits on the other hand, seem to start with the actual need and keeps the conversation of point.
<re_irc> But, since they are buildings levitating, there might be more surface area to deal with at first.
starblue1 has quit [Ping timeout: 268 seconds]
starblue1 has joined #rust-embedded
<re_irc> so I started work on getting Trustzone to work in Rust. There are a couple of nice posts about it online so that's a good start.
<re_irc> <diondokter> Hey all,
<re_irc> Now, in principle there are two ways that you seem to be able to work with trustzone.
<re_irc> What you see most often is a two binary approach where you have a secure bootloader and a non-secure application. The application can then call into the bootloader for things like key management and encryption.
<re_irc> <diondokter> Actually, that last idea is still two binaries, except that you have only one binary with an actual "main" entrypoint
<re_irc> <diondokter> Ooohhh, "staticlib" is interesting: https://doc.rust-lang.org/reference/linkage.html
<re_irc> <dirbaio> single binary won't work, it'll be an endless source of pain
<re_irc> <diondokter> Yeah, while typing I kinda came to that conclusion as well haha
<re_irc> <dirbaio> for example, what if both S and NS code call into the same function? where should it get placed?
<re_irc> and what if that function uses some static, where should it go?
<re_irc> <diondokter> Yeah, so they need to be separated. And shared data should go into the secure side, but in the "non-secure-callable" section. The secure side must then have a function that can return a pointer/reference so the non-secure code can access it
<re_irc> <diondokter> It's gonna be a pain regardless, because you will probably get a fault if you let non-secure code access a secure stack allocated variable. So you can't pass many references back and forth
<re_irc> <dirbaio> "staticlib" won't work either, you still have to link everything into a single bin in the end. If S and NS sides have duplicate fns/statics it'll fail to link with duplicate symbol errors (or it'll deduplicate them causing it to not work)
<re_irc> <diondokter> Really? Hmmm
<re_irc> <dirbaio> and also
<re_irc> <dirbaio> keep in mind lots of Rust types have invalid bit representations which cause UB
<re_irc> <dirbaio> if S side exposes a "func foo(x: bool)" to the NS side, the NS side can call it with "x=2", causing UB on the S side
<re_irc> <ryan-summers> Maybe have a post-processor or proc-macro that annotates the link section of functions and data in specific modules?
<re_irc> <dirbaio> which could allow NS to exploit S and escalate privilege
<re_irc> <diondokter> ryan-summers: Yeah, that's something I thought about as well, but then you'll still be stuck with shared dependencies that need to go somewhere too
<re_irc> <dirbaio> you can't pass "Box, Vec, Arc, Rc" etc either across NS/S
<re_irc> <diondokter> dirbaio: But that's an issue regardless of multi or single binary, right?
<re_irc> <dirbaio> yeah
<re_irc> <diondokter> Yeah ok
<re_irc> <dirbaio> But it's yet another reason why you can't simply "expose" rust fns from the S side
<re_irc> <dirbaio> even if you got the "#[link_section]" stuff sorted out (which I don't think it's possible)
<re_irc> <dirbaio> * possible either)
<re_irc> <ryan-summers> Maybe take the approach of Nordic with the softdevices? Essentially, use syscalls into a binary blob that controls the boot process
<re_irc> <ryan-summers> Also, why do you have a 1-bin requirement?
<re_irc> <ryan-summers> It's easy enough to combine two ELFs if their memory doesn't overlap
<re_irc> <diondokter> It's not a requirement
<re_irc> <ryan-summers> I do this for a BL+App constantly
<re_irc> <dirbaio> the softdevice is something totally different, it is not intended to be a security boundary
<re_irc> <diondokter> Is just want something that's super easy to set up
<re_irc> <ryan-summers> Yeah, I'll admit I have never used trustzone or secure apps etc.
<re_irc> <diondokter> Me neither :P
<re_irc> <dirbaio> I think the only sound way to do this is with two completely separate bins, plus something bindgen-like to generate stubs on the NS side to call into the S side
<re_irc> <dirbaio> and stick only to FFI-safe types
<re_irc> <diondokter> I think I agree yes
<re_irc> <dirbaio> and do lots and lots of pointer validation etc on the S side
<re_irc> <ryan-summers> That's just like C! :D
<re_irc> <ryan-summers> Fun times
<re_irc> <diondokter> Ok, but then the question becomes, how do I generate a binary without a main? Can you just do that?
<re_irc> <dirbaio> yeah.. its kinda the same as regular OS's syscall APIs
<re_irc> <ryan-summers> Is your secure side not a bootloader?
<re_irc> <ryan-summers> If you have two binaries, both will have a main
<re_irc> <ryan-summers> You set up the bootloader to just redirect the PC to the _start address of the app
<re_irc> <ryan-summers> When trying to boot
<re_irc> <ryan-summers> Alternatively, just make the bootloader main() a stub to jump to the expected app start addr (after doing sanity checks that such an app exists, CRC validation, etc.)
<re_irc> <diondokter> ryan-summers: In most applications I see online that is the case, but I was wondering if I could keep the main application in secure mode and then just delegate things like and ethernet stack to the non-secure side
<re_irc> <ryan-summers> If it doesn't have tod o anything
<re_irc> <ryan-summers> That seems... like an odd idea
<re_irc> <diondokter> Well, I got the idea when I saw the "BLXNS" instruction that allows you to jump to a non-secure function that can then return to the secure code
<re_irc> <diondokter> Why else would that function exist?
<re_irc> <diondokter> * instruction
<re_irc> <dkhayes117> Maybe look at TockOS? They have separate user app spaces loaded with Tockloader. Maybe some inspiration there?
<re_irc> <ryan-summers> Yeah, seems like the instruction may be directed towards an RTOS or something
<re_irc> <dirbaio> what's the usecase for trustzone in a Rust firmware anyway?
<re_irc> <dirbaio> in C firmwares it's used to try to keep secrets safe if your NS side gets exploited
<re_irc> <diondokter> The normal one is for a Trusted Execution Environment
<re_irc> <dirbaio> but if the NS side is rust, it's supposed to be not exploitable anyway
<re_irc> <ryan-summers> Key word is supposed to
<re_irc> <diondokter> Yup, logic bugs are not solved by Rust
<re_irc> <ryan-summers> Any moment you step into UB, Rust no longer helps. E.g. stack overflow, voltage rail manip to change PC, etc.
<re_irc> <ryan-summers> The real world is very different than what the compiler sees
<re_irc> <dirbaio> you can catch stack overflow with the MPU
<re_irc> <dirbaio> and trustzone doesn't protect against hardware attacks
<re_irc> <dirbaio> and trustzone doesn't protect against hardware attacks
<re_irc> <ryan-summers> But it can limit attack surface
<re_irc> <ryan-summers> That being said, I don't know - I haven't really used it, just spitballing here
<re_irc> <diondokter> dkhayes117: My guess is that they use privileged and unprivileged code like normal RTOSses do and while it sounds a lot alike, it's not the same
<re_irc> <diondokter> One usecase for us is that we must be in non-secure mode to use the nRF91 modem and in secure mode to use the cryptocell stuff. Also, in the future we're probably gonna literally run untrusted 3rd party code on our mcu and we want our keys to be as safe as possible
<re_irc> <dirbaio> and about logic bugs: trustzone can help prevent them by adding an additional "layer" of checks. BUT you can also have that same "layer" as regular rust fns in the same privilege level
<re_irc> <dirbaio> as long as you don't have memory safety exploits (which Rust prevents) you can't "skip" the extra layer even if it runs at the same privilege level
<re_irc> <dirbaio> I think you should be able to use the cryptocell from NS mode (?)
<re_irc> <diondokter> Only a secure mapping
<re_irc> <dirbaio> ohhhh wtf
<re_irc> <dirbaio> +why
<re_irc> <diondokter> Although the DMA is non-secure-accessible??
<re_irc> So maybe the cryptocell library does some magic there and is usable if the cryptocell is enabled?
<re_irc> <dirbaio> btw I've seen reports the cryptocell is slower and more power-hungry than a well-optimized software impl https://blog.ridil.fr/2019-12-04-ble3/#cc310
<re_irc> <dirbaio> you might want to skip it altogether, saving the trouble of trustzone and their C blob
<re_irc> <diondokter> Oh lol XD
cr1901 has joined #rust-embedded
<re_irc> <dirbaio> there was also an interesting devzone thread with benchs that arrived to the same conclusion, trying to find it..
<re_irc> <ub|k> what's the current status of LoRaWAN in Rust embedded development? I have an STM32W I played with some time ago, and it could do LoRa but there were no libraries which would make it easy to use LoRaWAN. any recent developments?
<re_irc> <firefrommoonlight> I think newam and one other person use yhat
<re_irc> <ub|k> they use what?
<re_irc> <ub|k> oh, there's also an embassy-lora, I see
<re_irc> <firefrommoonlight> I have a rust project that uses LoRa, but I can't help since it uses an offboard MCU that runs OSS firmware and passes the data as serial
<re_irc> <ub|k> ah, I see
<re_irc> <firefrommoonlight> The HAL I wrote supports Stm32WL, but has no RF support included
<re_irc> <firefrommoonlight> Or second core support
<re_irc> <firefrommoonlight> newam:
<re_irc> <firefrommoonlight> Lmk if you want tips on the hardware side though lol
<re_irc> <firefrommoonlight> I have a few designs with the sx1280
<re_irc> <firefrommoonlight> https://github.com/stm32-rs/stm32wlxx-hal maybe?
<cr1901> Finally implemented Iterator for my HAL. Unfortunately, it's probably only useful for code running an OS w/ threads right now (blocking each iteration of a for loop)
<cr1901> Has there been anything done in Rust for async for loops?
<cr1901> (Which can be emulated with loop {} of course, but still wondering)
<re_irc> <Marco Silva> an update on my I2C issue, I got it working 🥳
<re_irc> decided to check out any implementations of this in micropython, after digging a lot and getting that setup I was able to get an example working based on https://github.com/kfricke/micropython-sht31
<re_irc> With this I could try different configurations of the pins and 0 or 1 interface, and got some better understanding.
<re_irc> After that I changed my rust code to do the exact same thing in the exact same pins and interface, and it looks like what I had wrong were the pins.
<re_irc> <Marco Silva> on that code up there, I'm gettin an i1
<re_irc> <Marco Silva> * getting an i2c0. If I want both an i2c0 and an i2c1, I could in theory duplicate that, but not really because that first object borrows the clocks.peripheral_clock. what's the way around this?
<re_irc> <Marco Silva> I know I2c is a bus and everything can be on i2c0, but my shield has 2 so I was wondering if it's possible to setup both or if this is a big nono
<re_irc> <bradleyharden> Suppose I have a long documentation example. I would like to split it up to explain it line by line. But I also still want it to be checked as part of doc tests.
<re_irc> As far as I know, the only way is to add enough commented, invisible lines in each example for the visible line to be valid. But that means repeating the same commented lines over and over in every code block Is there some way to avoid that repetition?
<re_irc> <firefrommoonlight> Marco Silva: Sounds like an API limitation, or you're misunderstanding the API
<re_irc> <jannic> Marco Silva: I think you can call it with "clock.freq()" instead of "clock" so you keep ownership of the clock. (I'm on mobile ATM so I can't try myself)
<re_irc> <jannic> Implementing "From<SomeNotCopyType> for SomeCopyType" doesn't look like a very good choice - it's confusing that the clock object gets "lost" when converting it to "Hertz". I think we should change that, https://github.com/rp-rs/rp-hal/pull/394
crabbedhaloablut has joined #rust-embedded
<re_irc> <Marco Silva> I got it working using the direct value,
<re_irc> let sda_pin = pins.gpio8.into_mode::<hal::gpio::FunctionI2C>();
<re_irc> let i2c0 = I2C::i2c0(
<re_irc> let scl_pin = pins.gpio9.into_mode::<hal::gpio::FunctionI2C>();
<re_irc> <Marco Silva> but I feel like there should be a way to use the "clocks.peripheral_clock"
<re_irc> <jannic> Yes, that's another option, of course. BTW, it should be system_clock, not peripheral_clock, as far as I know. By default, they are the same, so it often doesn't matter.
<re_irc> <dirbaio> why not store the current clock in a global var? and have i2c/etc pick it up from there
<re_irc> <Marco Silva> jannic: "clocks.peripheral_clock.freq()" did work 👍️
<re_irc> <Marco Silva> should it really? I was using peripheral_clock from an example somewhere, and it is an attached peripheral so it made sense :/, will look it up
<re_irc> <jannic> Yes, I think the example is wrong. But https://github.com/rp-rs/rp-hal/blob/main/rp2040-hal/src/i2c/controller.rs#L27 calls the parameter system_clock, and if I understand the datasheet correctly, that's the right value.
<re_irc> <jannic> "4.3.1.2. Clocking
<re_irc> The I2C controller is connected to clk_sys. The I2C clock is generated by dividing down this clock, controlled by registers
<re_irc> inside the block."
<re_irc> <jannic> BTW, https://matrix.to/#/#rp-rs:matrix.org would be a better room for rp2040 specific questions, I guess.
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
<re_irc> <dkhayes117> Can build.rs completely replace a .cargo/config.toml? For example, can you set target and runner in build.rs?
<re_irc> <dirbaio> no :(
<re_irc> <adamgreig> Afaik just linker script, not default target :(
<re_irc> <dkhayes117> So unless you need some special linking or individual control over specific bins, it really isn't necessary.
<re_irc> <dirbaio> setting the target from build.rs would be a chicken-and-egg
<re_irc> <dirbaio> because build.rs can see the target in the "CARGO_TARGET" envvar :)
<re_irc> <dkhayes117> gotcha
<re_irc> <dkhayes117> So if a project has a lib.rs which is imported into a binary for linking, IE "use <package-name-here> as _:", would that be better to be placed in a build.rs?
<re_irc> <dirbaio> it wouldn't have the same effect, build.rs is its own binary (that's compiled for the host arch, not the target arch, and run in the host)
<re_irc> <dirbaio> so the lib wouldn't get linked in the true final binary
<re_irc> <dkhayes117> Okay, seems I need some more time to understand all the relationships of these
<re_irc> <adamgreig> hah, in the end it seems "wait it out" is going to work for svd2rust: bors is about to merge 'mark unsafecell as not dereferenceable' https://github.com/rust-lang/rust/pull/98017
emerent has quit [Ping timeout: 255 seconds]