Hacker News new | ask | show | jobs
by wallacoloo 3030 days ago
Also working in the same space. I had the opportunity to evaluate Rust for our development environment back in late September. The killer feature it offered us is serde - rust's general purpose SERializer DEserializer library.

So much of our code is centered around taking measurements with a bare metal system and then transmitting them to a linux box for processing. Being able to just write `#[derive(Serialize, Deserialize)]` above a struct and then be able to send/receive it across the channel via `rpmsg.send(mystruct)` or `let mystruct: MyStruct = rpmsg.recv()` is magic. Furthermore, by encapsulating each possible message type as an enum variant, match statements provide a really great way for dispatching the message to the appropriate handler after we deserialize it.

As for the borrow checker, I actually did find it useful in bare metal. But more for handling hardware resources. Different measurements require different sets of power supplies to be activated, and exclusive control over different I/Os, etc. The ownership model made it easier to ensure statically that we sequence the measurements in a way such that the different measurement routines can never reconfigure resources that are in use by a different routine.

Anyway, we sadly aren't using Rust yet in production, even after that. Holding off until we start the next product.

1 comments

What data format do you use with Serde on embedded? JSON? I read somewhere that Serde works in no-std environments, but wasn't sure whether it does that with all possible data formats.
Serde is middleware, which really just shuttles calls between a serializable object and the serializing backend in a standard (and performant!) way. That middleware works in no_std environments, but not all backends do.

I'm not up to date on which backends support no_std, and which backends support no-alloc - some backends support no_std but require an allocator. When I looked into this in Sept, ssmarshal was the only general-purpose backend I could find that supported no_std & didn't need an allocator. There was some talk of adding no_std support to bincode - looks like it hasn't gone anywhere: https://github.com/TyOverby/bincode/issues/189

My one gripe with ssmarshal is that - in Sept - it would refuse to serialize collections whose size isn't compile-time constant. Obviously, you aren't going to be serializing Vec, Map, etc, in a no_std environment. But one could very well wish to serialize stack-allocated equivalents (e.g. arrayvec, where you have a vector that stores all data on the stack and grows up to the space allocated for it). In order to serialize an arrayvec, I had to write wrapper code that serialized the entire underlying fixed-size storage, regardless of how much was actually in use.

Things move fast in rust-land - ssmarshal might have a feature that allows serializing dynamically-sized types, or there might be new/more versatile backends since Sept.

I think the most difficult thing about deserializing JSON in a no-std environment is that strings can have escape sequences. So when you deserialize a string, you can't just pass a reference into your buffer up to the frontend - you have to decode the string. Usually one would heap-allocate in the backend for that, but if you have the ability to mutate the buffer you're deserializing from, I don't see any fundamental reason why you couldn't decode the string in place and then yield it - I'm pretty sure all encoded JSON strings are at least as long as their decoded version. The easy alternative is to deserialize the string as a [Char] sequence (i.e. pass it to the frontend character by character) and let the frontend worry about memory management, which isn't even necessarily so bad, with things like ArrayString.