Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

possible to target wasm32-wasi? #57

Closed
proohit opened this issue May 5, 2021 · 6 comments
Closed

possible to target wasm32-wasi? #57

proohit opened this issue May 5, 2021 · 6 comments

Comments

@proohit
Copy link

proohit commented May 5, 2021

I think it would be amazing to be able to compile to WASM + WASI, so that we can compile code, that has only access to given devices. In my understanding, it should be possible, since /dev/gpiochipX are handled as files** and could be preopened via fs over WASI. I'm a total noob though, so I don't know if that's even possible.

Following, some interesing infos I've found:

  • I've seen examples from wasm3 runtime that use WASI with Arduinos by passing the needed functions into WASM.
  • WASI has no official support for hardware peripheral abstractions as derived from this WASI issue.
  • In this tutorial by wasmtime, they demonstrate how files or dirs can be passed into the WASM sandbox env

Currently building to target wasm32-wasi results in several errors.

** on Linux

@nastevens
Copy link
Member

I'm not familiar with the capabilities/restrictions of WASM + WASI - are ioctls allowed? gpio-cdev makes extensive use of them, so using this library directly would be difficult without ioctl support.

@nastevens
Copy link
Member

Fat fingered "close", sorry

@nastevens nastevens reopened this May 5, 2021
@proohit
Copy link
Author

proohit commented May 6, 2021

Oh I don't know either and research is a little confusing. Please let me share my findings with you:

  • According to this WASI issue, there is no official support for things like /dev/X. They may come in the future. The main problem here is that those files are rather Linux specific and WASI/WASM aims to be platform-independent
  • If we take a look at the WASI core, it seems like all necessary APIs are defined: __wasi_path_open(), which sounds awfully lot like fopen in C. Next ones are __wasi_fd_write() and __wasi_fd_write() to actually R/W from/to a file. Those APIs are implemented by runtimes.
  • In this issue, someone tried to make use of /dev/urandom from inside WASI and seemed to succeed. He passed the directory /dev into the wasmtime like described in the wasmtime tutorial, so that he can access it from inside WASM.
  • Maybe what we're missing are some adjustments to be able to compile into WASI. It seems like in sysfs-gpio there was a pull request to achieve exactly this. As mentioned, I'm noob in Rust and WASM :(.

Maybe it helps to show you the compiling errors:

$ cargo build --release --target=wasm32-wasi
error[E0433]: failed to resolve: could not find `unix` in `os`
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/lib.rs:95:14
   |
95 | use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
   |              ^^^^ could not find `unix` in `os`

error: cannot find macro `ioctl_read` in this scope
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:75:5
   |
75 |     ioctl_read!(gpio_get_chipinfo_ioctl, 0xB4, 0x01, gpiochip_info),
   |     ^^^^^^^^^^

error: cannot find macro `ioctl_readwrite` in this scope
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:79:5
   |
79 |     ioctl_readwrite!(gpio_get_lineinfo_ioctl, 0xB4, 0x02, gpioline_info),
   |     ^^^^^^^^^^^^^^^

error: cannot find macro `ioctl_readwrite` in this scope
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:83:5
   |
83 |     ioctl_readwrite!(gpio_get_linehandle_ioctl, 0xB4, 0x03, gpiohandle_request),
   |     ^^^^^^^^^^^^^^^

error: cannot find macro `ioctl_readwrite` in this scope
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:87:5
   |
87 |     ioctl_readwrite!(gpio_get_lineevent_ioctl, 0xB4, 0x04, gpioevent_request),
   |     ^^^^^^^^^^^^^^^

error: cannot find macro `ioctl_readwrite` in this scope
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:92:5
   |
92 |     ioctl_readwrite!(
   |     ^^^^^^^^^^^^^^^

error: cannot find macro `ioctl_readwrite` in this scope
   --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:101:5
    |
101 |     ioctl_readwrite!(
    |     ^^^^^^^^^^^^^^^

error[E0433]: failed to resolve: could not find `errno` in `nix`
   --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/lib.rs:955:60
    |
955 |             Ok(None) => Err(event_err(nix::Error::Sys(nix::errno::Errno::EIO))),
    |                                                            ^^^^^ could not find `errno` in `nix`

error[E0433]: failed to resolve: could not find `unistd` in `nix`
   --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/lib.rs:990:31
    |
990 |         let bytes_read = nix::unistd::read(self.file.as_raw_fd(), &mut data_as_buf)?;
    |                               ^^^^^^ could not find `unistd` in `nix`

error[E0412]: cannot find type `Error` in crate `nix`
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/errors.rs:19:16
   |
19 |     Event(nix::Error),
   |                ^^^^^ not found in `nix`
   |
help: consider importing one of these items
   |
5  | use core::fmt::Error;
   |
5  | use crate::Error;
   |
5  | use crate::errors::fmt::Error;
   |
5  | use std::error::Error;
   |
     and 2 other candidates

error[E0412]: cannot find type `Error` in crate `nix`
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/errors.rs:21:42
   |
21 |     Ioctl { kind: IoctlKind, cause: nix::Error },
   |                                          ^^^^^ not found in `nix`
   |
help: consider importing one of these items
   |
5  | use core::fmt::Error;
   |
5  | use crate::Error;
   |
5  | use crate::errors::fmt::Error;
   |
5  | use std::error::Error;
   |
     and 2 other candidates

error[E0412]: cannot find type `Error` in crate `nix`
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/errors.rs:26:54
   |
26 | pub(crate) fn ioctl_err(kind: IoctlKind, cause: nix::Error) -> Error {
   |                                                      ^^^^^ not found in `nix`
   |
help: consider importing one of these items
   |
5  | use core::fmt::Error;
   |
5  | use crate::Error;
   |
5  | use crate::errors::fmt::Error;
   |
5  | use std::error::Error;
   |
     and 2 other candidates

error[E0412]: cannot find type `Error` in crate `nix`
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/errors.rs:44:35
   |
44 | pub(crate) fn event_err(err: nix::Error) -> Error {
   |                                   ^^^^^ not found in `nix`
   |
help: consider importing one of these items
   |
5  | use core::fmt::Error;
   |
5  | use crate::Error;
   |
5  | use crate::errors::fmt::Error;
   |
5  | use std::error::Error;
   |
     and 2 other candidates

error[E0425]: cannot find function `gpio_get_chipinfo_ioctl` in module `gpio_get_chipinfo_ioctl`
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:75:17
   |
75 |     ioctl_read!(gpio_get_chipinfo_ioctl, 0xB4, 0x01, gpiochip_info),
   |                 ^^^^^^^^^^^^^^^^^^^^^^^ not found in `gpio_get_chipinfo_ioctl`

error[E0425]: cannot find function `gpio_get_lineinfo_ioctl` in module `gpio_get_lineinfo_ioctl`
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:79:22
   |
79 |     ioctl_readwrite!(gpio_get_lineinfo_ioctl, 0xB4, 0x02, gpioline_info),
   |                      ^^^^^^^^^^^^^^^^^^^^^^^ not found in `gpio_get_lineinfo_ioctl`

error[E0425]: cannot find function `gpio_get_linehandle_ioctl` in module `gpio_get_linehandle_ioctl`
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:83:22
   |
83 |     ioctl_readwrite!(gpio_get_linehandle_ioctl, 0xB4, 0x03, gpiohandle_request),
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^ not found in `gpio_get_linehandle_ioctl`

error[E0425]: cannot find function `gpio_get_lineevent_ioctl` in module `gpio_get_lineevent_ioctl`
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:87:22
   |
87 |     ioctl_readwrite!(gpio_get_lineevent_ioctl, 0xB4, 0x04, gpioevent_request),
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ not found in `gpio_get_lineevent_ioctl`

error[E0425]: cannot find function `gpiohandle_get_line_values_ioctl` in module `gpiohandle_get_line_values_ioctl`
  --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:93:9
   |
93 |         gpiohandle_get_line_values_ioctl,
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in `gpiohandle_get_line_values_ioctl`

error[E0425]: cannot find function `gpiohandle_set_line_values_ioctl` in module `gpiohandle_set_line_values_ioctl`
   --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/ffi.rs:102:9
    |
102 |         gpiohandle_set_line_values_ioctl,
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in `gpiohandle_set_line_values_ioctl`

error[E0405]: cannot find trait `AsRawFd` in this scope
   --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/lib.rs:691:6
    |
691 | impl AsRawFd for LineHandle {
    |      ^^^^^^^ not found in this scope
    |
help: consider importing this trait
    |
90  | use std::os::wasi::io::AsRawFd;
    |

error[E0412]: cannot find type `RawFd` in this scope
   --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/lib.rs:693:28
    |
693 |     fn as_raw_fd(&self) -> RawFd {
    |                            ^^^^^ not found in this scope
    |
help: consider importing this type alias
    |
90  | use std::os::wasi::io::RawFd;
    |

error[E0405]: cannot find trait `AsRawFd` in this scope
   --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/lib.rs:869:6
    |
869 | impl AsRawFd for MultiLineHandle {
    |      ^^^^^^^ not found in this scope
    |
help: consider importing this trait
    |
90  | use std::os::wasi::io::AsRawFd;
    |

error[E0412]: cannot find type `RawFd` in this scope
   --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/lib.rs:871:28
    |
871 |     fn as_raw_fd(&self) -> RawFd {
    |                            ^^^^^ not found in this scope
    |
help: consider importing this type alias
    |
90  | use std::os::wasi::io::RawFd;
    |

error[E0433]: failed to resolve: could not find `Error` in `nix`
   --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/lib.rs:955:44
    |
955 |             Ok(None) => Err(event_err(nix::Error::Sys(nix::errno::Errno::EIO))),
    |                                            ^^^^^ not found in `nix`
    |
help: consider importing one of these items
    |
90  | use core::fmt::Error;
    |
90  | use crate::errors::Error;
    |
90  | use std::error::Error;
    |
90  | use std::fmt::Error;
    |
      and 1 other candidate

error[E0412]: cannot find type `Error` in crate `nix`
   --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/lib.rs:982:84
    |
982 |     pub(crate) fn read_event(&self) -> std::result::Result<Option<LineEvent>, nix::Error> {
    |                                                                                    ^^^^^ not found in `nix`
    |
help: consider importing one of these items
    |
90  | use core::fmt::Error;
    |
90  | use crate::errors::Error;
    |
90  | use std::error::Error;
    |
90  | use std::fmt::Error;
    |
      and 1 other candidate

error[E0405]: cannot find trait `AsRawFd` in this scope
    --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/lib.rs:1000:6
     |
1000 | impl AsRawFd for LineEventHandle {
     |      ^^^^^^^ not found in this scope
     |
help: consider importing this trait
     |
90   | use std::os::wasi::io::AsRawFd;
     |

error[E0412]: cannot find type `RawFd` in this scope
    --> /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/gpio-cdev-0.4.0/src/lib.rs:1002:28
     |
1002 |     fn as_raw_fd(&self) -> RawFd {
     |                            ^^^^^ not found in this scope
     |
help: consider importing this type alias
     |
90   | use std::os::wasi::io::RawFd;
     |

error: aborting due to 27 previous errors

Furthermore, I noticed those lines here:

help: consider importing this trait
    |
90  | use std::os::wasi::io::AsRawFd;

Maybe it's possible to import them only for specific build targets?

Please let me hear your opinion :).

@posborne
Copy link
Member

posborne commented May 6, 2021

This crate is very much so only intended to target Linux and wasm/wasi is not that. I think a more interesting approach in general would for there to be some project which seeks to provide an implementation of the https://github.com/rust-embedded/embedded-hal traits that could execute within an environment like wasm32-wasi which would proxy requests through some mechanism to an implementation in the host environment. At least, that's my intuition while not having extensive experience with wasm. This would seem to be much more well suited to implementing things portably and securely across platforms which is one of the reasons that people often are deciding to target wasm.

@proohit
Copy link
Author

proohit commented May 7, 2021

That's a fair point. We'd be mixing separations there.

Trying to bring it on wasm without an official API also feels kinda hacky. The complexity comes from the goal to portability across platforms. embedding-hal proposes to provide custom implementations for specific targets and that's exactly what my intention was.

We're at a dead end here, I guess :/

@proohit proohit closed this as completed May 7, 2021
@fpagliughi
Copy link
Contributor

I agree with @posborne. This is a very system-specific crate to target a Linux subsystem. It is not intended to be portable across platforms. If a generic GPIO library exists, that would be a proper choice for something like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants