lupyuen / bl602-rust-wrapper

Rust Wrapper for BL602 IoT SDK
https://lupyuen.github.io/articles/adc
Apache License 2.0
16 stars 1 forks source link
bl602 bl604 macro riscv riscv32 rust

Rust Wrapper for BL602 IoT SDK

Read the article and docs...

Usage

Here's how we call the Rust Wrapper for BL602 GPIO HAL in our BL602 Rust Firmware...

use bl602_sdk::gpio;
...
//  Configure the LED GPIO for output (instead of input)
gpio::enable_output(LED_GPIO, 0, 0)        //  No pullup, no pulldown
    .expect("GPIO enable output failed");  //  Halt on error

//  Blink the LED 5 times
for i in 0..10 {  //  Iterates 10 times from 0 to 9 (`..` excludes 10)

    //  Toggle the LED GPIO between 0 (on) and 1 (off)
    gpio::output_set(  //  Set the GPIO output (from BL602 GPIO HAL)
        LED_GPIO,      //  GPIO pin number
        i % 2          //  0 for low, 1 for high
    ).expect("GPIO output failed");  //  Halt on error

From sdk_app_rust_gpio/rust/src/lib.rs

Build the BL602 Firmware with the run.sh script

Generate Rust Wrapper

To generate the Rust Wrapper...

#  Install bindgen and clang: https://rust-lang.github.io/rust-bindgen/requirements.html 
cargo install bindgen
sudo apt install llvm-dev libclang-dev clang

#  Download the source code
git clone --recursive https://github.com/lupyuen/bl602-rust-wrapper
git clone --recursive https://github.com/lupyuen/bl_iot_sdk

#  Generate the Rust Bindings for BL602 IoT SDK
cd bl602-rust-wrapper
scripts/gen-bindings.sh

#  Build the docs and the test project
scripts/build.sh

How It Works

This script...

Reads the BL602 IoT SDK Header Files...

//  Function Declarations from BL602 IoT SDK (GPIO HAL)
//  https://github.com/lupyuen/bl_iot_sdk/blob/master/components/hal_drv/bl602_hal/bl_gpio.h
int bl_gpio_enable_output(uint8_t pin, uint8_t pullup, uint8_t pulldown);
int bl_gpio_output_set(uint8_t pin, uint8_t value);

And auto-generates the Rust Bindings...

//  Rust Bindings for BL602 GPIO generated by gen-bindings.sh
#[safe_wrap(_)] extern "C" {
    pub fn bl_gpio_enable_output(pin: u8, pullup: u8, pulldown: u8) -> ::cty::c_int;
}

#[safe_wrap(_)] extern "C" {
    pub fn bl_gpio_output_set(pin: u8, value: u8) -> ::cty::c_int;
}

Which call the safe_wrap Procedural Macro...

To produce the Rust Wrapper for BL602 IoT SDK...

//  Expanded version of `safe_wrap` macros for the GPIO Rust Bindings
#[doc = "Configure a GPIO Pin for Output Mode. See `bl_gpio_enable_output` in \"Enable GPIO\" <https://lupyuen.github.io/articles/led#enable-gpio>"]
pub fn enable_output(pin: u8, pullup: u8, pulldown: u8)
    -> BlResult<()> {
    "----------Extern Decl----------";
    extern "C" {
        pub fn bl_gpio_enable_output(pin: u8, pullup: u8, pulldown: u8)
        -> ::cty::c_int;
    }
    "----------Validation----------";
    unsafe {
        "----------Call----------";
        let res =
            bl_gpio_enable_output(pin as u8, pullup as u8,
                                    pulldown as u8);
        "----------Result----------";
        match res { 0 => Ok(()), _ => Err(BlError::from(res)), }
    }
}

#[doc = "Set output value of GPIO Pin. See `bl_gpio_output_set` in \"Read and Write GPIO\" <https://lupyuen.github.io/articles/led#read-and-write-gpio>"]
pub fn output_set(pin: u8, value: u8) -> BlResult<()> {
    "----------Extern Decl----------";
    extern "C" {
        pub fn bl_gpio_output_set(pin: u8, value: u8)
        -> ::cty::c_int;
    }
    "----------Validation----------";
    unsafe {
        "----------Call----------";
        let res = bl_gpio_output_set(pin as u8, value as u8);
        "----------Result----------";
        match res { 0 => Ok(()), _ => Err(BlError::from(res)), }
    }
}

Links to "The RISC-V BL602 Book" are defined here...

Build Log

Build the docs and the test project with this script...

+ export RUST_BACKTRACE=1
+ RUST_BACKTRACE=1
+ rust_build_options='     --target riscv32imacf-unknown-none-elf.json     -Z build-std=core '
+ pushd bl602-macros
/mnt/c/pinecone/bl602-rust-wrapper/bl602-macros /mnt/c/pinecone/bl602-rust-wrapper
+ cargo build
   Compiling proc-macro2 v1.0.27
   Compiling unicode-xid v0.2.2
   Compiling memchr v2.4.0
   Compiling syn v1.0.73
   Compiling cty v0.2.1
   Compiling rustc-serialize v0.3.24
   Compiling lazy_static v1.4.0
   Compiling cstr_core v0.2.4
   Compiling quote v1.0.9
   Compiling bl602-macros v0.0.2 (/mnt/c/pinecone/bl602-rust-wrapper/bl602-macros)
    Finished dev [unoptimized + debuginfo] target(s) in 50.67s
+ popd
/mnt/c/pinecone/bl602-rust-wrapper
+ cp bl602-sdk/doclinks.md .
+ pushd bl602-sdk
/mnt/c/pinecone/bl602-rust-wrapper/bl602-sdk /mnt/c/pinecone/bl602-rust-wrapper
+ cargo rustc --target riscv32imacf-unknown-none-elf.json -Z build-std=core -- -Z unstable-options --pretty expanded
   Compiling compiler_builtins v0.1.47
   Compiling core v0.0.0 (/home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core)
   Compiling heapless v0.7.3
   Compiling rustc-std-workspace-core v1.99.0 (/home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/rustc-std-workspace-core)
   Compiling byteorder v1.4.3
   Compiling stable_deref_trait v1.2.0
   Compiling cty v0.2.1
   Compiling hash32 v0.2.1
   Compiling bl602-sdk v0.0.6 (/mnt/c/pinecone/bl602-rust-wrapper/bl602-sdk)
    Finished dev [unoptimized + debuginfo] target(s) in 33.50s
+ cargo build --target riscv32imacf-unknown-none-elf.json -Z build-std=core
   Compiling bl602-sdk v0.0.6 (/mnt/c/pinecone/bl602-rust-wrapper/bl602-sdk)
    Finished dev [unoptimized + debuginfo] target(s) in 7.85s
+ cargo doc --target riscv32imacf-unknown-none-elf.json -Z build-std=core
    Checking unicode-xid v0.2.2
 Documenting unicode-xid v0.2.2
    Checking cty v0.2.1
 Documenting cty v0.2.1
    Checking lazy_static v1.4.0
 Documenting rustc-serialize v0.3.24
    Checking rustc-serialize v0.3.24
 Documenting lazy_static v1.4.0
    Checking memchr v2.4.0
 Documenting memchr v2.4.0
    Checking proc-macro2 v1.0.27
    Checking byteorder v1.4.3
 Documenting byteorder v1.4.3
    Checking stable_deref_trait v1.2.0
 Documenting stable_deref_trait v1.2.0
    Checking cstr_core v0.2.4
 Documenting proc-macro2 v1.0.27
    Checking quote v1.0.9
 Documenting cstr_core v0.2.4
    Checking hash32 v0.2.1
    Checking syn v1.0.73
    Checking heapless v0.7.3
 Documenting hash32 v0.2.1
 Documenting quote v1.0.9
 Documenting heapless v0.7.3
 Documenting syn v1.0.73
 Documenting bl602-macros v0.0.2 (/mnt/c/pinecone/bl602-rust-wrapper/bl602-macros)
 Documenting bl602-sdk v0.0.6 (/mnt/c/pinecone/bl602-rust-wrapper/bl602-sdk)
    Finished dev [unoptimized + debuginfo] target(s) in 48.79s
+ popd
/mnt/c/pinecone/bl602-rust-wrapper
+ echo 'Moved to [`bl602-sdk/doclinks.md`](bl602-sdk/doclinks.md)'
+ cp -r target/riscv32imacf-unknown-none-elf/doc/bl602_sdk docs    
+ cp -r target/riscv32imacf-unknown-none-elf/doc/src docs