Read the article and docs...
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
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
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 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