Use bindgen for rust bindings
This commit is contained in:
parent
cece963e91
commit
e8099fc681
@ -12,3 +12,6 @@ crate-type = ["staticlib"]
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
getopts = "0.2"
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.53.1"
|
||||
|
32
build.rs
Normal file
32
build.rs
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
extern crate bindgen;
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
// Tell cargo to invalidate the built crate whenever the wrapper changes
|
||||
println!("cargo:rerun-if-changed=radio.h");
|
||||
|
||||
// The bindgen::Builder is the main entry point
|
||||
// to bindgen, and lets you build up options for
|
||||
// the resulting bindings.
|
||||
let bindings = bindgen::Builder::default()
|
||||
// The input header we would like to generate
|
||||
// bindings for.
|
||||
.header("radio.h")
|
||||
// Tell cargo to invalidate the built crate whenever any of the
|
||||
// included header files changed.
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
|
||||
.whitelist_type("radio_device_t")
|
||||
// Finish the builder and generate the bindings.
|
||||
.generate()
|
||||
// Unwrap the Result and panic on failure.
|
||||
.expect("Unable to generate bindings for radio.h");
|
||||
|
||||
// Write the bindings to the $OUT_DIR/bindings.rs file.
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
bindings
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.expect("Couldn't write bindings!");
|
||||
}
|
2
radio.h
2
radio.h
@ -29,6 +29,8 @@
|
||||
//
|
||||
// Check for compatible radio model.
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
int radio_is_compatible(const char *ident);
|
||||
|
||||
//
|
||||
|
@ -1,7 +1,12 @@
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use libc::{c_int, c_char};
|
||||
use getopts::Options;
|
||||
use std::process::exit;
|
||||
|
||||
|
||||
mod radio;
|
||||
|
||||
const COPYRIGHT: &'static str = "Copyright (C) 2018 Serge Vakulenko KK6ABQ";
|
||||
|
45
src/radio.rs
45
src/radio.rs
@ -2,22 +2,21 @@ use std::ffi::CString;
|
||||
use libc::{c_char, c_int};
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct RadioDeviceT { _private: [u8; 0] }
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
|
||||
extern {
|
||||
fn radio_connect() -> *const RadioDeviceT;
|
||||
fn radio_connect() -> *const radio_device_t;
|
||||
|
||||
fn radio_download(device: *const RadioDeviceT);
|
||||
fn radio_upload(device: *const RadioDeviceT, cont_flag: c_int);
|
||||
fn radio_download(device: *const radio_device_t);
|
||||
fn radio_upload(device: *const radio_device_t, cont_flag: c_int);
|
||||
fn radio_list_c();
|
||||
fn radio_verify_config(device: *const RadioDeviceT);
|
||||
fn radio_print_version(device: *const RadioDeviceT, stdout: *const libc::FILE);
|
||||
fn radio_print_config(device: *const RadioDeviceT, file: *const libc::FILE, verbose: c_int);
|
||||
fn radio_read_image(filename: *const c_char) -> *const RadioDeviceT;
|
||||
fn radio_save_image(device: *const RadioDeviceT, filename: *const c_char);
|
||||
fn radio_parse_config(device: *const RadioDeviceT, filename: *const c_char);
|
||||
fn radio_write_csv(device: *const RadioDeviceT, filename: *const c_char);
|
||||
fn radio_verify_config(device: *const radio_device_t);
|
||||
fn radio_print_version(device: *const radio_device_t, stdout: *const libc::FILE);
|
||||
fn radio_print_config(device: *const radio_device_t, file: *const libc::FILE, verbose: c_int);
|
||||
fn radio_read_image(filename: *const c_char) -> *const radio_device_t;
|
||||
fn radio_save_image(device: *const radio_device_t, filename: *const c_char);
|
||||
fn radio_parse_config(device: *const radio_device_t, filename: *const c_char);
|
||||
fn radio_write_csv(device: *const radio_device_t, filename: *const c_char);
|
||||
|
||||
fn dfu_reboot();
|
||||
fn dfu_close();
|
||||
@ -27,7 +26,7 @@ extern {
|
||||
|
||||
/// Connect to the radio via the serial port.
|
||||
/// Identify the type of device.
|
||||
pub fn connect() -> *const RadioDeviceT {
|
||||
pub fn connect() -> *const radio_device_t {
|
||||
unsafe {
|
||||
radio_connect()
|
||||
}
|
||||
@ -47,14 +46,14 @@ pub fn disconnect() {
|
||||
}
|
||||
|
||||
/// Read firmware image from the device
|
||||
pub fn download(device: *const RadioDeviceT) {
|
||||
pub fn download(device: *const radio_device_t) {
|
||||
unsafe {
|
||||
radio_download(device)
|
||||
}
|
||||
}
|
||||
|
||||
/// Write firmware image to the device.
|
||||
pub fn upload(device: *const RadioDeviceT, cont_flag: c_int) {
|
||||
pub fn upload(device: *const radio_device_t, cont_flag: c_int) {
|
||||
unsafe {
|
||||
radio_upload(device, cont_flag)
|
||||
}
|
||||
@ -69,14 +68,14 @@ pub fn list() {
|
||||
}
|
||||
|
||||
/// Check the configuration.
|
||||
pub fn verify_config(device: *const RadioDeviceT) {
|
||||
pub fn verify_config(device: *const radio_device_t) {
|
||||
unsafe {
|
||||
radio_verify_config(device);
|
||||
}
|
||||
}
|
||||
|
||||
/// Read firmware image from the binary file.
|
||||
pub fn read_image(filename: &str) -> *const RadioDeviceT {
|
||||
pub fn read_image(filename: &str) -> *const radio_device_t {
|
||||
let filename = CString::new(filename.to_string()).unwrap();
|
||||
unsafe {
|
||||
radio_read_image(filename.as_ptr())
|
||||
@ -84,7 +83,7 @@ pub fn read_image(filename: &str) -> *const RadioDeviceT {
|
||||
}
|
||||
|
||||
/// Save firmware image to the binary file.
|
||||
pub fn save_image(device: *const RadioDeviceT, filename: &str) {
|
||||
pub fn save_image(device: *const radio_device_t, filename: &str) {
|
||||
let filename = CString::new(filename.to_string()).unwrap();
|
||||
unsafe {
|
||||
radio_save_image(device, filename.as_ptr())
|
||||
@ -92,7 +91,7 @@ pub fn save_image(device: *const RadioDeviceT, filename: &str) {
|
||||
}
|
||||
|
||||
/// Read the configuration from text file, and modify the firmware.
|
||||
pub fn parse_config(device: *const RadioDeviceT, filename: &str) {
|
||||
pub fn parse_config(device: *const radio_device_t, filename: &str) {
|
||||
let filename = CString::new(filename.to_string()).unwrap();
|
||||
unsafe {
|
||||
radio_parse_config(device, filename.as_ptr())
|
||||
@ -100,7 +99,7 @@ pub fn parse_config(device: *const RadioDeviceT, filename: &str) {
|
||||
}
|
||||
|
||||
/// Print full information about the device configuration.
|
||||
pub fn print_config(device: *const RadioDeviceT, filename: &str) {
|
||||
pub fn print_config(device: *const radio_device_t, filename: &str) {
|
||||
let file = std::fs::File::create(filename).unwrap();
|
||||
let fd = file.as_raw_fd();
|
||||
let mode = CString::new("w").unwrap();
|
||||
@ -111,7 +110,7 @@ pub fn print_config(device: *const RadioDeviceT, filename: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_config_to_stdout(device: *const RadioDeviceT) {
|
||||
pub fn print_config_to_stdout(device: *const radio_device_t) {
|
||||
let mode = CString::new("w").unwrap();
|
||||
unsafe {
|
||||
let stdout = libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr());
|
||||
@ -125,7 +124,7 @@ pub fn print_config_to_stdout(device: *const RadioDeviceT) {
|
||||
}
|
||||
|
||||
/// Print generic information about the device.
|
||||
pub fn print_version(device: *const RadioDeviceT) {
|
||||
pub fn print_version(device: *const radio_device_t) {
|
||||
let mode = CString::new("w").unwrap();
|
||||
unsafe {
|
||||
radio_print_version(device, libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr()));
|
||||
@ -133,7 +132,7 @@ pub fn print_version(device: *const RadioDeviceT) {
|
||||
}
|
||||
|
||||
/// Update CSV contacts database.
|
||||
pub fn write_csv(device: *const RadioDeviceT, filename: &str) {
|
||||
pub fn write_csv(device: *const radio_device_t, filename: &str) {
|
||||
let filename = CString::new(filename.to_string()).unwrap();
|
||||
unsafe {
|
||||
radio_write_csv(device, filename.as_ptr());
|
||||
|
Loading…
Reference in New Issue
Block a user