GithubHelp home page GithubHelp logo

rust-riot-sys's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-riot-sys's Issues

incompatible `i2c_t` types

When trying to generate bindings for the bmx280 device driver, I noticed that the size of the struct bmx280_params_t differs from C to Rust. I used the module USEMODULE += bmp280_i2c and added these lines to rust-riot-sys/riot-headers.h to generate the bindings:

#include "bmx280.h"
#include "bmx280_params.h"

The struct contains an i2c_dev of type i2c_t which seems to be the reason for the difference. I used the following programs to print the sizes. In C:

#include <stdio.h>
#include <bmx280.h>
int main(void) {
    printf("sizeof bmx280_params_t = %d\n", sizeof(bmx280_params_t));
    printf("sizeof i2c_t = %d\n", sizeof(i2c_t));
}
sizeof bmx280_params_t = 32
sizeof i2c_t = 4

In Rust:

use riot_wrappers::{println, riot_main};
use riot_sys::{bmx280_params_t, i2c_t};
use core::mem::size_of;
riot_main!(main);
fn main() {
    println!("sizeof bmx280_params_t = {}", size_of::<bmx280_params_t>());
    println!("sizeof i2c_t = {}", size_of::<i2c_t>());
}
sizeof bmx280_params_t = 28
sizeof i2c_t = 1

In the file RIOT/drivers/include/periph/i2c.h the type is defined as follows:

#ifndef HAVE_I2C_T
typedef uint_fast8_t i2c_t;
#endif

For native, xtensa, risc-v and arm, it seems like all the fast integer types are defined through internal compiler defines like typedef __INT_FAST8_TYPE__ int_fast8_t; These types differ since RIOT is compiled by gcc and the Rust bindings are created with llvm. I did some tests and got the following types using different architectures. The cells show the actual type when using gcc / clang:

Bit Native (x86-64) Xtensa RISC-V ARM
8 char / char int / char int / char int / char
16 long int / short int / short int / short int / short
32 long int / int int / int int / int int / int
64 long int / long int long long int /
long long int
long long int /
long long int
long long int /
long long int

One workaround is to redefine these macros when generating the bindings so that they match the types used by gcc. For the uint_fast8_t this can be done by adding the following lines to riot-bindgen.h and riot-c2rust.h:

#undef __UINT_FAST8_TYPE__
#define __UINT_FAST8_TYPE__ unsigned int

Alternatively, this also works:

#define HAVE_I2C_T
typedef unsigned int i2c_t

However there should be a better way that actually guarantees that the same type is used when compiling RIOT and creating the bindings.

Random-ish build failure around preprocessor_successor.h

There are build errors cropping up with:

   --- stderr
  /__w/rust-riot-wrappers/rust-riot-wrappers/RIOT/sys/include/auto_init_utils.h:35:10: fatal error: 'preprocessor_successor.h' file not found
  thread 'main' panicked at /github/home/.cargo/git/checkouts/rust-riot-sys-d12733b89271907c/c985a6b/build.rs:224:10:
  Unable to generate bindings: ClangDiagnostic("/__w/rust-riot-wrappers/rust-riot-wrappers/RIOT/sys/include/auto_init_utils.h:35:10: fatal error: 'preprocessor_successor.h' file not found\n")

I've now traced this down to being caused by compile-commands.json files where the -I.../bin/native/preprocessor entry is not in the first of the included files.

Build script fails on Alpine / muslibc

When building on Alpine (which is muslibc based), building Rust based RIOT applications fails:

  --- stderr
  thread 'main' panicked at 'Unable to find libclang: "the `libclang` shared library at /usr/lib/libclang.so.13.0.1 could not be opened: Dynamic loading not supported"', /root/.cargo/registry/src/github.com-1ecc6299db9ec823/bindgen-0.60.1/src/lib.rs:2172:31
  stack backtrace:
     0: rust_begin_unwind
               at /rustc/d394408fb38c4de61f765a3ed5189d2731a1da91/library/std/src/panicking.rs:584:5
     1: core::panicking::panic_fmt
               at /rustc/d394408fb38c4de61f765a3ed5189d2731a1da91/library/core/src/panicking.rs:142:14
     2: core::result::unwrap_failed
               at /rustc/d394408fb38c4de61f765a3ed5189d2731a1da91/library/core/src/result.rs:1814:5
     3: core::result::Result<T,E>::expect
     4: core::ops::function::FnOnce::call_once
     5: lazy_static::lazy::Lazy<T>::get::{{closure}}
     6: std::sync::once::Once::call_once::{{closure}}
     7: std::sync::once::Once::call_inner
               at /rustc/d394408fb38c4de61f765a3ed5189d2731a1da91/library/std/src/sync/once.rs:434:21
     8: std::sync::once::Once::call_once
     9: <bindgen::ensure_libclang_is_loaded::LIBCLANG as core::ops::deref::Deref>::deref
    10: bindgen::ensure_libclang_is_loaded
    11: bindgen::Bindings::generate
    12: bindgen::Builder::generate
    13: build_script_build::main
    14: core::ops::function::FnOnce::call_once
  note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
make: *** [/tmp/RIOT/makefiles/cargo-targets.inc.mk:44: /tmp/RIOT/examples/rust-hello-world/bin/microbit-v2/target/thumbv7em-none-eabihf/release/librust_hello_world.a] Error 101

Reproducing

I've tested this inside the container set up per immunant/c2rust#724 with maribu's resolution (RUSTFLAGS=-Ctarget-feature=-crt-static cargo install --locked c2rust) with an extra of (the former is generally needed for RIOT, the latter target specific and make would have told us later anyway):

$ apk add git gcc-arm-none-eabi newlib-arm-none-eabi
$ rustup target add thumbv7em-none-eabihf

Then run (ideally after RIOT-OS/RIOT#18904 is in, or apply it manually):

$ make -C examples/rust-hello-world BOARD=microbit-v2

Towards fixing

When switching riot-sys's bindgen dependency to /static (btw, we don't really use the default features it seems...), the build script instead segfaults in a way similar to rust-lang/rust-bindgen#2333:

error: failed to run custom build command for `riot-sys v0.7.9 (/tmp/riot-sys)`

Caused by:
  process didn't exit successfully: `/tmp/RIOT/examples/rust-hello-world/bin/microbit-v2/target/release/build/riot-sys-1835746e88917b5e/build-script-build` (signal: 11, SIGSEGV: invalid memory reference)

CC @maribu who originally found this.

[edit: more precise setup instructions]

`#![warn(unaligned_references)]`

The way bindgen derives Debug for packed structs has long raised warnigns about unaligned references; recently, these warnings were made into errors (breaking previously working builds under the update policy that it's OK to do that on unsound behavior).

Starting v0.7.8, the compiler change is counteracted by a #![warn(unaligned_references)], but that only stops the screaming and not the pain. (The pain is not that bad on most RIOT boards as their processors are rather tolerant of unaligned access, but it's still UB under Rust's memory model).

There's an issue on the bindgen side, but no clear path forward -- disabling Debug for riot-sys generated structs will be a breaking change, and worse, some riot-wrappers structs rely on thee to provide their Debug (and they may lose that silently if generics are involved, or visibly).

I don't have a good plan forward here yet, but at least it's documented now.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.