Skip to content

Commit

Permalink
Add lib/rust_px4_nuttx library
Browse files Browse the repository at this point in the history
  • Loading branch information
jnippula committed Sep 4, 2024
1 parent 597cfa8 commit 169644b
Show file tree
Hide file tree
Showing 13 changed files with 541 additions and 0 deletions.
75 changes: 75 additions & 0 deletions src/lib/rust_px4_nuttx/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions src/lib/rust_px4_nuttx/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "px4_nuttx"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"

[dependencies]
log = "0.4"
embedded-io = "0.6.1"
no-std-net = "0.6.0"
px4_nuttx_macros = { path = "./px4_nuttx_macros" }
14 changes: 14 additions & 0 deletions src/lib/rust_px4_nuttx/px4_nuttx_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "px4_nuttx_macros"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
proc-macro = true

[dependencies]
proc-macro2 = "1.0"
syn = { version = "2.0", features = ["full"] }
quote = "1.0"
19 changes: 19 additions & 0 deletions src/lib/rust_px4_nuttx/px4_nuttx_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![recursion_limit = "128"]

extern crate proc_macro;

use proc_macro::TokenStream;

mod module_main;

/*
#[proc_macro_attribute]
pub fn px4_message(args: TokenStream, input: TokenStream) -> TokenStream {
message::px4_message(args, input)
}
*/

#[proc_macro_attribute]
pub fn px4_module_main(attr: TokenStream, input: TokenStream) -> TokenStream {
module_main::px4_module_main(attr, input)
}
41 changes: 41 additions & 0 deletions src/lib/rust_px4_nuttx/px4_nuttx_macros/src/module_main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use proc_macro::TokenStream;
use proc_macro2::{Ident, Span};
use quote::quote;
use syn::parse_macro_input;

pub fn px4_module_main(attr: TokenStream, input: TokenStream) -> TokenStream {
if !attr.is_empty() {
panic!("px4_module_main does not take any arguments");
}
let crate_name = std::env::var("CARGO_PKG_NAME").unwrap();
let main_fndef = Ident::new(&format!("rust_{}_main", &crate_name), Span::call_site());

let fndef = parse_macro_input!(input as syn::ItemFn);
let name = &fndef.sig.ident;
let expanded = quote! {
use core::panic::PanicInfo;
use px4_nuttx::alloc::format;

extern "C" {
pub fn printf(format: *const u8, ...) -> i32;
}

#[panic_handler]
fn rust_panic(info: &PanicInfo<'_>) -> ! {
let mut message = format!("PANIC: [{}] {:}", #crate_name, info);
message.push('\0');
unsafe {
printf(b"%s\n\0" as *const u8, message.as_bytes().as_ptr());
}
loop {}
}

#fndef

#[no_mangle]
pub extern "C" fn #main_fndef(argc: u32, argv: *mut *mut u8) -> i32 {
unsafe { px4_nuttx::_run(concat!(module_path!(), "\0").as_bytes(), argc, argv, #name) }
}
};
expanded.into()
}
81 changes: 81 additions & 0 deletions src/lib/rust_px4_nuttx/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#![no_std]
#![no_main]

pub mod nuttx;
pub mod px4;

pub use nuttx::alloc;
pub use px4::logger;
pub use px4_nuttx_macros::px4_module_main;

use nuttx::alloc::vec::Vec;
use core::ffi::CStr;

pub fn init() {
px4::logger::init();
}

#[doc(hidden)]
pub unsafe fn _run<F, R>(_modulename: &'static [u8], argc: u32, argv: *mut *mut u8, f: F) -> i32
where
F: Fn(&[&str]) -> R + core::panic::UnwindSafe,
R: MainStatusCode,
{
logger::init();
let mut args = Vec::with_capacity(argc as usize);
for i in 0..argc {
args.push(
CStr::from_ptr(*argv.offset(i as isize) as *const i8)
.to_str()
.unwrap_or_else(|_| panic!("Invalid UTF-8 in arguments.")),
);
}
f(&args).to_status_code()
}

/// The return type of your `#[px4_module_main]` function.
pub trait MainStatusCode {
/// The status code to return.
fn to_status_code(self) -> i32;

/// The status code to return in case of a panic.
///
/// −1 by default.
fn panic_status_code() -> i32 {
-1
}
}

/// Returns 0.
impl MainStatusCode for () {
fn to_status_code(self) -> i32 {
0
}
}

/// Returns the `i32` itself.
impl MainStatusCode for i32 {
fn to_status_code(self) -> i32 {
self
}
}

/// Returns 0 for `Ok`, and 1 for `Err`.
impl MainStatusCode for Result<(), ()> {
fn to_status_code(self) -> i32 {
match self {
Ok(()) => 0,
Err(()) => 1,
}
}
}

/// Returns 0 for `Ok`, and the `i32` itself for `Err`.
impl MainStatusCode for Result<(), i32> {
fn to_status_code(self) -> i32 {
match self {
Ok(()) => 0,
Err(s) => s,
}
}
}
5 changes: 5 additions & 0 deletions src/lib/rust_px4_nuttx/src/nuttx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod galloc;
pub mod net;
pub mod time;

pub use galloc::alloc;
23 changes: 23 additions & 0 deletions src/lib/rust_px4_nuttx/src/nuttx/galloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pub extern crate alloc;
use alloc::alloc::{GlobalAlloc, Layout};

#[global_allocator]
static ALLOCATOR: Gallocator = Gallocator;

extern "C" { // Import C Function
fn aligned_alloc(align: usize, size: usize) -> *mut u8;
fn free(p: *const u8);
}

struct Gallocator;
unsafe impl GlobalAlloc for Gallocator {
unsafe fn alloc(&self, l: Layout) -> *mut u8 {
unsafe {
aligned_alloc(l.align(), l.size())
}
}
unsafe fn dealloc(&self, p: *mut u8, _: Layout) {
free(p);
}
}

2 changes: 2 additions & 0 deletions src/lib/rust_px4_nuttx/src/nuttx/net.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod udp;
pub use udp::UdpSocket;
Loading

0 comments on commit 169644b

Please sign in to comment.