This is an automated email from the ASF dual-hosted git repository. utzig pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 529d38f7d98b07de40b3c6c84ebe5edcb9415469 Author: Casper Meijn <cas...@meijn.net> AuthorDate: Sun Aug 23 08:54:53 2020 +0200 apps/rust_blinky: Use bindgen to convert C-header to Rust Use bindgen to generate Rust code from the actual C-header as used for the C code. Then use the generated code in the Rust application to make it compatible with all BSP. --- apps/rust_blinky/Cargo.toml | 4 +++ apps/rust_blinky/build.rs | 69 ++++++++++++++++++++++++++++++++++++++++ apps/rust_blinky/pkg.yml | 1 + apps/rust_blinky/src/bindings.rs | 23 ++++++++++++++ apps/rust_blinky/src/lib.rs | 39 ++++++++++++----------- apps/rust_blinky/wrapper.h | 22 +++++++++++++ 6 files changed, 140 insertions(+), 18 deletions(-) diff --git a/apps/rust_blinky/Cargo.toml b/apps/rust_blinky/Cargo.toml index 1c583ae..6c95eae 100644 --- a/apps/rust_blinky/Cargo.toml +++ b/apps/rust_blinky/Cargo.toml @@ -22,6 +22,10 @@ edition = "2018" [dependencies] panic-halt = "0.2.0" +cty = "0.2.1" + +[build-dependencies] +bindgen = "0.54.0" [lib] crate-type = ["staticlib"] diff --git a/apps/rust_blinky/build.rs b/apps/rust_blinky/build.rs new file mode 100644 index 0000000..fffbcbe --- /dev/null +++ b/apps/rust_blinky/build.rs @@ -0,0 +1,69 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2020 Casper Meijn <cas...@meijn.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +extern crate bindgen; + +use std::env; +use std::path::PathBuf; +use std::process::Command; +use std::str; + +fn main() { + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs"); + + let mut builder = bindgen::Builder::default() + .use_core() + .derive_default(true) + .ctypes_prefix("cty") + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .header("wrapper.h"); + println!("cargo:rerun-if-changed=wrapper.h"); + + // If available, set the sysroot as mynewt would do + if let Ok(cc_path) = env::var("MYNEWT_CC_PATH") { + let cc_output = Command::new(cc_path) + .arg("-print-sysroot") + .output() + .expect("failed to execute gcc"); + if !cc_output.status.success() { + panic!("Error: C-compiler failed to provide sysroot"); + } + let sysroot_path = str::from_utf8(&cc_output.stdout).unwrap().trim(); + builder = builder.clang_arg(format!("--sysroot={}", sysroot_path)); + } + + // If available, set the include directories as mynewt would do + if let Ok(include_path_list) = env::var("MYNEWT_INCLUDE_PATH") { + for include_path in include_path_list.split(":") { + builder = builder.clang_arg("--include-directory=".to_owned() + include_path); + } + } + // If available, set the CFLAGS as mynewt would do + if let Ok(cflag_list) = env::var("MYNEWT_CFLAGS") { + for cflag in cflag_list.split(" ") { + builder = builder.clang_arg(cflag); + } + } + + builder + .generate() + .map_err(|_| "Failed to generate") + .unwrap() + .write_to_file(out_path) + .map_err(|e| format!("Failed to write output: {}", e)) + .unwrap(); +} diff --git a/apps/rust_blinky/pkg.yml b/apps/rust_blinky/pkg.yml index cace556..93f8dc4 100644 --- a/apps/rust_blinky/pkg.yml +++ b/apps/rust_blinky/pkg.yml @@ -29,6 +29,7 @@ pkg.pre_build_cmds: pkg.deps: - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-core/hw/hal" - "@apache-mynewt-core/sys/console/stub" - "@apache-mynewt-core/sys/log/stub" - "@apache-mynewt-core/sys/stats/stub" diff --git a/apps/rust_blinky/src/bindings.rs b/apps/rust_blinky/src/bindings.rs new file mode 100644 index 0000000..814505e --- /dev/null +++ b/apps/rust_blinky/src/bindings.rs @@ -0,0 +1,23 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2020 Casper Meijn <cas...@meijn.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/apps/rust_blinky/src/lib.rs b/apps/rust_blinky/src/lib.rs index c36920f..087d810 100644 --- a/apps/rust_blinky/src/lib.rs +++ b/apps/rust_blinky/src/lib.rs @@ -16,36 +16,39 @@ #![no_std] -extern "C" { - fn sysinit_start(); - fn sysinit_app(); - fn sysinit_end(); - fn hal_gpio_init_out(pin: i32, val: i32) -> i32; - fn hal_gpio_toggle(pin: i32); - fn os_time_delay(osticks: u32); -} +mod bindings; extern crate panic_halt; -const OS_TICKS_PER_SEC: u32 = 128; - -const LED_BLINK_PIN: i32 = 23; - +// Define a safe wrapper for os_time_delay +fn os_time_delay_ms(ms: u32) { + let mut ticks: bindings::os_time_t = 0; + let result = unsafe { bindings::os_time_ms_to_ticks(ms, &mut ticks) }; + assert!(result == 0); + unsafe { bindings::os_time_delay(ticks) }; +} #[no_mangle] pub extern "C" fn main() { /* Initialize all packages. */ - unsafe { sysinit_start(); } - unsafe { sysinit_app(); } - unsafe { sysinit_end(); } + unsafe { + bindings::sysinit_start(); + bindings::sysinit_app(); + bindings::sysinit_end(); + } - unsafe { hal_gpio_init_out(LED_BLINK_PIN, 1); } + /* Turn on the LED */ + unsafe { + bindings::hal_gpio_init_out(bindings::LED_BLINK_PIN as i32, 1); + } loop { /* Wait one second */ - unsafe { os_time_delay(OS_TICKS_PER_SEC); } + os_time_delay_ms(1000); /* Toggle the LED */ - unsafe { hal_gpio_toggle(LED_BLINK_PIN); } + unsafe { + bindings::hal_gpio_toggle(bindings::LED_BLINK_PIN as i32); + } } } diff --git a/apps/rust_blinky/wrapper.h b/apps/rust_blinky/wrapper.h new file mode 100644 index 0000000..b5463c8 --- /dev/null +++ b/apps/rust_blinky/wrapper.h @@ -0,0 +1,22 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2020 Casper Meijn <cas...@meijn.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <inttypes.h> +#include "bsp/bsp.h" +#include "os/os_time.h" +#include "hal/hal_gpio.h" +#include "sysinit/sysinit.h"