<re_irc>
<michael.desilva> Depending on Content-Type, the rendered error is now handled accordingly - for now I'm only matching on JSON (for my particular use).
cr1901_ has joined #rust-embedded
cr1901 has quit [Ping timeout: 260 seconds]
IlPalazzo-ojiisa has joined #rust-embedded
<re_irc>
< (@dirbaio:matrix.org)> michael.desilva: these are very esp32-specific questions, maybe you'll have more luck asking in #esp-rs:matrix.org (https://matrix.to/#/#esp-rs:matrix.org)
starblue has quit [Ping timeout: 268 seconds]
starblue has joined #rust-embedded
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has quit [Remote host closed the connection]
loki_val has joined #rust-embedded
andvari[m] has joined #rust-embedded
loki_val has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
cr1901_ has quit [Remote host closed the connection]
cr1901_ has joined #rust-embedded
hwj has joined #rust-embedded
dc740 has joined #rust-embedded
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
hwj has quit [Ping timeout: 260 seconds]
hwj has joined #rust-embedded
<re_irc>
< (@orclev:matrix.org)> is there any good equivalent to a RwLock in no-std, or is that too complicated of a problem to solve in a common way?
<re_irc>
< (@orclev:matrix.org)> I guess with no universal mechanism for blocking and transferring execution to another piece of code there really wouldn't be a way to prevent it from just deadlocking permanently.
<re_irc>
<Ralph> Hi all, I'm looking for some advice on writing a Rust-wrapper around the C-driver for this TOF sensor: http://st.com/VL53L3CX
<re_irc>
the C implementation can be freely downloaded from ST (with a legal text telling you that you can't re-distribute it but then all files in the ZIP say that it's GPL & BSD dual-licensed... i'm not a lawyer, so i'll hold off for the moment with sharing it in a public repo :/) and it's a pretty big thing (i.e. not something you just quickly re-implement in Rust).
<re_irc>
the driver they deliver is split in two parts: a "core" part (which implements the actual logic) and a "platform" part which has all the platform-specific things. the platform part is used in two ways: some of its APIs are called by the core part (e.g. to do the actual talking with the device, as the core part isn't aware of I2C & co. - esp. not any specific implementation thereof - or doing a delay) and by the consumer (because...
<re_irc>
... you need to give the I2C handle (or whatever you have) to it).
<re_irc>
<Ralph> and, to add one more complication: it seems that i need to define the delay as "&'a dyn DelayUs<u8>", which seems to force me to use a global allocator? is there any better way to get a delay into a driver? (note: i can't pass it on every method invocation since the delay gets called from within the C code)
<re_irc>
< (@chemicstry:matrix.org)> Usually it's just easier to write the driver in Rust, than trying to glue C. Especially for simple I2C sensors that only contain a few register reads and a couple of data conversion functions. I'm not sure if that's the case for the sensor in question. Does the lib do a lot of complicated software processing?
<re_irc>
< (@chemicstry:matrix.org)> It's hard to answer your original question without the code sample and how everything interracts. You do not need allocator for "&'a dyn DelayUs<u8>", you only need it if your "Box<>" it
<re_irc>
< (@chemicstry:matrix.org)> : oh god, I was wondering why datasheet has no register information :D
emerent has quit [Ping timeout: 252 seconds]
emerent_ has joined #rust-embedded
emerent_ is now known as emerent
<re_irc>
< (@grantm11235:matrix.org)> I'm guessing that almost all of that is software processing
<re_irc>
<Ralph> : sadly this isn't a simple driver. the code provided by ST is thousands of lines long. it contains a ton of logic.
<re_irc>
(note: this is for a university project - they usually do it in C or C++ but i thought that i want to show them how much better Rust is suited for these things - so i'm not getting paid to write that driver, so things have to stay in a reasonable effort and can be a bit hacky if needed)
<re_irc>
< (@chemicstry:matrix.org)> also, it's C++ code, that's way worse than C in terms of Rust ffi
<re_irc>
<Ralph> : interesting, that's not the implementation they offer on their website (there you get a pure C thing, also it's completely differently structured. but the function names seem to be similar)
<re_irc>
< (@chemicstry:matrix.org)> then you're in lucky at least in that part, wrapping C++ is much harder
<re_irc>
<Ralph> you have to implement APIs like this:
<re_irc>
<Ralph> "VL53LX_Dev_t" is a struct which you can extend as needed to e.g. contain your I2C reference (or, in my case, the reference back to something in Rust)
<re_irc>
< (@chemicstry:matrix.org)> and they are glued at link time? i.e. you don't pass a function pointer to your "VL53LX_WaitUs" implementation during initialization?
<re_irc>
<Ralph> the way i've started this is that i'm building the C library using "cc" in my "build.rs" and also use "bindgen" there to get the things i need to implement in Rust back into rust. i'm not doing that for the APIs listed here as they contain references to things i don't need/want in Rust, instead i'd write a small indirection there.
<re_irc>
e.g. i had planned on doing something like this:
<re_irc>
< (@chemicstry:matrix.org)> is "VL53LX_Dev_t" an opaque struct? Meaning you can pass any pointer there? Then you could have a "struct Vl53LxDev<'a> { delay: &'a dyn DelayUs<u8>, i2c: &'a mut I2c }", which is constructed in rust with your delay and i2c drivers, i.e. "let dev = Vl53LxDev { delay: ..., i2c: ... }" and then you can cast it as a pointer "&dev as *mut Vl53LxDev as *mut VL53LX_Dev_t", the second type being opaque...
<re_irc>
... struct type from bindgen. Then in your given "rust_delay" you can cast it back to original rust struct. Of course you have to ensure that lifetimes are respected and everything is cleaned up before dropping rust struct
<re_irc>
< (@chemicstry:matrix.org)> I think you can also implement "VL53LX_WaitUs" directly in Rust with "extern "C""
<re_irc>
< (@chemicstry:matrix.org)> no need to double wrap it
<re_irc>
< (@chemicstry:matrix.org)> is "VL53LX_Dev_t" an opaque struct? Meaning you can pass any pointer there? Then you could have a "struct Vl53LxDev<'a> { delay: &'a dyn DelayUs<u8>, i2c: &'a mut I2c }", which is constructed in rust with your delay and i2c drivers, i.e. "let dev = Vl53LxDev { delay: ..., i2c: ... }" and then you can cast it as a pointer "&mut dev as *mut Vl53LxDev as *mut VL53LX_Dev_t", the second type being opaque...
<re_irc>
... struct type from bindgen. Then in your given "rust_delay" you can cast it back to original rust struct. Of course you have to ensure that lifetimes are respected and everything is cleaned up before dropping rust struct
dc740 has quit [Remote host closed the connection]
<re_irc>
<Ralph> thanks for all your feedback so far!
<re_irc>
"VL53LX_Dev_t" isn't opaque, it contains some fields which are being accessed by the "core" code (i just double-checked again; it's there but they are hiding it behind some "#define"s so you could put the data elsewhere). thus directly implementing that method in Rust isn't a great option for me as I'd then need to use "bindgen" to map all those additional structs (and enums) into Rust.
<re_irc>
my struct looks mostly like your example (though i did steal this trick (https://github.com/juliangaal/mpu6050/blob/master/src/lib.rs#L86) to not reference the I2C from my HAL (there doesn't seem to be an I2C trait in the latest embedded-hal 0.x (i just checked and saw that my HAL also has an additional dependency for 1.0.0-alpha.8, so if that one includes a proper I2C trait i could also switch to that?).
<re_irc>
< (@grantm11235:matrix.org)> You don't need to take a dyn DelayUs, you can add that as another type parameter
<re_irc>
< (@chemicstry:matrix.org)> Ralph: you have to define a lifetime for "&mut dyn DelayUs<u8>", which is equal or greater than "Self". if you do "impl<'a, I> VL53LX<'a, I>", then you could use "&'a mut dyn DelayUs<u8>"
<re_irc>
< (@chemicstry:matrix.org)> btw, I highly doubt that generics will work in this case, because in your C implementation you will have to cast pointer back to concrete type
<re_irc>
< (@grantm11235:matrix.org)> That's a good point. It would probably be easiest to just skip all the generic stuff for now and use concrete types.
<re_irc>
<Ralph> : good point! got one step further:
<re_irc>
| ^^^ unconstrained type parameter
<re_irc>
13 | impl<I, D, UXX, E> VL53LX<I, D>
<re_irc>
<Ralph> : i didn't plan on calling the generic stuff from C - my plan was that from C i'd just call a simple API in Rust which i pass the pointer to the struct and then i'd access the actual stuff in there in the Rust code. or will that not work?
<re_irc>
< (@chemicstry:matrix.org)> I'm not sure if "extern "C"" functions can be generic, porbably not. Try to write implementation for "VL53LX_WaitUs" and I think you'll see the problem
<re_irc>
< (@chemicstry:matrix.org)> * probably
<re_irc>
<Ralph> : ah, i guess the API would have to contain the generic in the parameter? though i think i've seen somewhere that unsafe rust (for FFI at least?) has the equivalent of "void*"? so i guess i could also use that for the input parameter and then cast it inside?
<re_irc>
< (@chemicstry:matrix.org)> you don't know which type to cast it to. Rust does monomorphisation when resolving generics, it generates code for each generic type used. But in FFI it can't infer what types will be used
<re_irc>
< (@chemicstry:matrix.org)> as an alternative you can create a trait containing all methods that will be called from FFI side and implement it for your "VL53LX", then you pass it into C as "&dyn Trait"
conplan has joined #rust-embedded
causal has quit [Quit: WeeChat 3.7.1]
<re_irc>
< (@firefrommoonlight:matrix.org)> Ralph: Hey I made one
<re_irc>
< (@firefrommoonlight:matrix.org)> Haven't tested on hardware yet though do to low pri
<re_irc>
< (@firefrommoonlight:matrix.org)> Probably some bugs floating around
<re_irc>
< (@firefrommoonlight:matrix.org)> I just translated the C lib
<re_irc>
< (@firefrommoonlight:matrix.org)> Haven't had much luck on FFI with things that need hardware interaction
<re_irc>
< (@firefrommoonlight:matrix.org)> (This has some hard-codings for STM32 in the I2c fns)
<re_irc>
< (@firefrommoonlight:matrix.org)> Note that that module has a lot of...unrusty code
<re_irc>
< (@firefrommoonlight:matrix.org)> I think I chagned some of it to a more rusty style, but not all
<re_irc>
< (@firefrommoonlight:matrix.org)> To amke it easier to cross-ref with future versions
<re_irc>
< (@firefrommoonlight:matrix.org)> An ST dev told me they left the register API so complicated because they coudn't settle on a best way to set it up, so they left it open to future driver updates...
<re_irc>
< (@firefrommoonlight:matrix.org)> * eng
<re_irc>
< (@firefrommoonlight:matrix.org)> : This is not a simple I2c sensor
<re_irc>
< (@firefrommoonlight:matrix.org)> It's a weird one
<re_irc>
< (@firefrommoonlight:matrix.org)> To make it work with your proj, replace the "pac::I2C1" with whatever your HAL uses. It's set up to work on H7 and G4; IIRC the F4 I2C periph is slightly diff
<re_irc>
< (@firefrommoonlight:matrix.org)> Also pulls in an external lib for mild quaternion/vector logic on offsetting readings based on bank angle, but you can delete that stuff
hwj has quit [Ping timeout: 252 seconds]
<re_irc>
<Ralph> oh, wow, thanks ! that must've been a lot of work!
<re_irc>
do you think that one will work for the VL53L3CX? acc. to your initial comment yours is based STSW-IMG019 / STSW-IMG009, however mine is using STSW-IMG-015 (i think just the API is the same and the implementation differs?)
<re_irc>
< (@firefrommoonlight:matrix.org)> It was mainly tedium
<re_irc>
< (@firefrommoonlight:matrix.org)> I suspect similar
<re_irc>
< (@firefrommoonlight:matrix.org)> I also recall there are differnet ST drivers of different complexity, and this is based on one of teh simpler ones (believe it or not...)
<re_irc>
< (@firefrommoonlight:matrix.org)> Unrelated: Do "defmt::println" statements that fire in your code when you're not connected to a debugger impact performance?
<re_irc>
< (@firefrommoonlight:matrix.org)> *Hmm, not sure if the sensor variants you and I are using use the same code or not, as you observed
<re_irc>
< (@firefrommoonlight:matrix.org)> VL51 vs VL53
<re_irc>
< (@firefrommoonlight:matrix.org)> * VL53L1 vs VL51L3
<re_irc>
<Ralph> : i think not (i downloaded the different C drivers for some of them and they looked different). acc. to the datasheets the different sensors also have different features.
<re_irc>
<Ralph> for now it seems to work with just hardcoding my HAL and not using any generics. i guess now it's mainly a bit of effort. i'll invest into that tomorrow, hopefully getting some results out of my sensor then.
<re_irc>
thanks everyone for your feedback!
<re_irc>
< (@firefrommoonlight:matrix.org)> GL!
<re_irc>
< (@firefrommoonlight:matrix.org)> I might take a stab at getting mine working this weekend
<re_irc>
< (@firefrommoonlight:matrix.org)> I'm highly suspicious it will need more work
<re_irc>
< (@firefrommoonlight:matrix.org)> I've had a 0% success rate in using driver crates, but will give it a go
<re_irc>
< (@firefrommoonlight:matrix.org)> That oen looks full-up from a skim
<re_irc>
< (@dkhayes117:matrix.org)> Slightly off-topic question, If I'm using CoAP over a DTLS socket with LTE-M, are these loosely related to the OSI model layers of
<re_irc>
Transport layer : DTLS
<re_irc>
Network layer: LTE-M
<re_irc>
Application Layer: CoAP
<re_irc>
< (@dkhayes117:matrix.org)> Or is it more of