Skip to content

[Feature] no_std support #42

Open
Open

Description

@deltronix

Problem description

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.

Activity

  1. changed the title [-][Feature] Actual no_std support[/-] [+][Feature] no_std support[/+] on Dec 26, 2025
  2. bruingineer commented on Dec 26, 2025

    @bruingineer
    Contributor

    are you looking for parsing support only, or do you want full sync/sequencing/timeouts/discovery support on the embedded target?

  3. deltronix commented on Dec 27, 2025

    @deltronix
    Author

    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?

  4. bruingineer commented on Dec 27, 2025

    @bruingineer
    Contributor

    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?

  5. deltronix commented on Dec 30, 2025

    @deltronix
    Author

    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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions