You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As a side project I've been foraying into creating an open-source DMX node based on an STM32F7 series microcontroller. Using the embassy framework, which includes the embassy_net stack (this is mostly a wrapper around smoltcp). I have been able to receive sACN dataframes through multi and unicast. However I've hit a roadblock and that's that this library (as far as I can tell the only complete sACN library available for Rust for which my gratitude) does not support a no_std environment.
Solutions
There are 3 possible solutions to this problem as far as I can see:
A pretty major rewrite of this library to support no-std environments using the "std" feature as a negating flag.
Splitting this library into a "sacn-core" crate that does not rely on std/alloc but has enough functionality to be useful in an embedded environment and an "sacn" crate that imports "sacn-core" but provides a higher-level interface.
A "new" library, specifically designed for no_std environments.
Resolution
Do you have any opinion on this, or have you considered any approach? And are you, the authors/maintainers of this crate, willing and able to spend some time and effort to aid me in this endeavour. As I am not very experienced in contributing to open-source projects yet.
are you looking for parsing support only, or do you want full sync/sequencing/timeouts/discovery support on the embedded target?
Just parsing support would be great. With the wide range of embedded targets and use cases it's probably better to leave the handling of "sync/sequencing/timeouts/discovery" and such up to the user of the crate.
I've forked the repo and am attempting to make mod packet and the accompanying error modules compile without std/alloc. The main issues that I've ran into are:
Error Handling
A lot of the SacnError and ParsePacketError enum variants contain an std::string::String, in most cases this could be a &'static str however some of the String's are formatted at runtime. So I propose to either have those variants contain a &'a str or a heapless::String of some max length. A next step might then be to implement optional support for defmt.
Usage of std::borrow::Cow and Vec
I haven't used a clone-on-write before and am unsure about a no_std alternative that does not use an allocator. I see it's used to store the DataPacket property values (so the actual DMX data) and the source name among others so it's a pretty major part of the crate.
The Vec's in packet.rs could be replaced with heapless::Vec this would require deciding on a reasonable upper bound for the vectors sizes.
Besides that I see that in packet.rs the implementations are wrapped in a macro that sets a lifetime. But is then only used to generate the implementations with <'a>. Is there a reason for this?
Would a core + alloc solution for packet.rs be acceptable, or for your use cases, would core only and no alloc at all be preferable?
Yes that would be an acceptable trade-off. I've been working on this for a bit on my own branch. To not depend on socket2 I've rewritten fn universe_to_ipv4_multicast_addr() and fn universe_to_ipv6_multicast_addr() to return core::net::SocketAddress instead of socket2::SockAddr which requires rewriting a bunch of tests and a few functions in receive.rs and source.rs.
Would you prefer if I open a pull request on this code, or should I finish up rewriting those tests first? You can check my branch here
Activity
[-][Feature] Actual no_std support[/-][+][Feature] no_std support[/+]bruingineer commentedon Dec 26, 2025
are you looking for parsing support only, or do you want full sync/sequencing/timeouts/discovery support on the embedded target?
deltronix commentedon Dec 27, 2025
Just parsing support would be great. With the wide range of embedded targets and use cases it's probably better to leave the handling of "sync/sequencing/timeouts/discovery" and such up to the user of the crate.
I've forked the repo and am attempting to make
mod packetand the accompanying error modules compile without std/alloc. The main issues that I've ran into are:Error Handling
A lot of the
SacnErrorandParsePacketErrorenum variants contain anstd::string::String, in most cases this could be a&'static strhowever some of the String's are formatted at runtime. So I propose to either have those variants contain a&'a stror aheapless::Stringof some max length. A next step might then be to implement optional support for defmt.Usage of
std::borrow::CowandVecI haven't used a clone-on-write before and am unsure about a no_std alternative that does not use an allocator. I see it's used to store the DataPacket property values (so the actual DMX data) and the source name among others so it's a pretty major part of the crate.
The Vec's in
packet.rscould be replaced withheapless::Vecthis would require deciding on a reasonable upper bound for the vectors sizes.Besides that I see that in
packet.rsthe implementations are wrapped in a macro that sets a lifetime. But is then only used to generate the implementations with <'a>. Is there a reason for this?bruingineer commentedon Dec 27, 2025
Would a
core + allocsolution for packet.rs be acceptable, or for your use cases, wouldcoreonly and noallocat all be preferable?deltronix commentedon Dec 30, 2025
Yes that would be an acceptable trade-off. I've been working on this for a bit on my own branch. To not depend on
socket2I've rewrittenfn universe_to_ipv4_multicast_addr()andfn universe_to_ipv6_multicast_addr()to return core::net::SocketAddress instead of socket2::SockAddr which requires rewriting a bunch of tests and a few functions inreceive.rsandsource.rs.Would you prefer if I open a pull request on this code, or should I finish up rewriting those tests first? You can check my branch here