Skip to content

Instantly share code, notes, and snippets.

@pftbest
Created April 17, 2020 21:48
Show Gist options
  • Save pftbest/c5d89849e22d103278a104704c4624cb to your computer and use it in GitHub Desktop.
Save pftbest/c5d89849e22d103278a104704c4624cb to your computer and use it in GitHub Desktop.
use kernel::common::{cells::OptionalCell, dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState}};
use kernel::hil;
use kernel::hil::uart::{Parameters, Configure, Receive, ReceiveClient, TransmitClient, Transmit};
use kernel::{ReturnCode, static_init};
use capsules::virtual_uart::UartDevice;
use kernel::component::Component;
use std::sync::mpsc;
struct Uart<'a> {
tx_client: OptionalCell<&'a dyn TransmitClient>,
rx_client: OptionalCell<&'a dyn ReceiveClient>,
chan: mpsc::Sender<(&'static mut [u8], usize)>,
}
impl<'a> Transmit<'a> for Uart<'a> {
fn set_transmit_client(&self, client: &'a dyn TransmitClient) {
self.tx_client.set(client);
}
fn transmit_buffer(
&self,
tx_data: &'static mut [u8],
_tx_len: usize,
) -> (ReturnCode, Option<&'static mut [u8]>) {
(ReturnCode::FAIL, Some(tx_data))
}
fn transmit_word(&self, _word: u32) -> ReturnCode {
ReturnCode::FAIL
}
fn transmit_abort(&self) -> ReturnCode {
ReturnCode::FAIL
}
}
impl<'a> Configure for Uart<'a> {
fn configure(&self, _params: Parameters) -> ReturnCode {
ReturnCode::SUCCESS
}
}
impl<'a> Receive<'a> for Uart<'a> {
fn set_receive_client(&self, client: &'a dyn ReceiveClient) {
self.rx_client.set(client);
}
fn receive_buffer(
&self,
rx_buffer: &'static mut [u8],
rx_len: usize,
) -> (ReturnCode, Option<&'static mut [u8]>) {
println!("UART::receive_buffer {:?} {:?}", rx_buffer.as_ptr(), rx_len);
self.chan.send((rx_buffer, rx_len)).unwrap();
(ReturnCode::SUCCESS, None)
}
fn receive_word(&self) -> ReturnCode {
ReturnCode::FAIL
}
fn receive_abort(&self) -> ReturnCode {
println!("UART::receive_abort");
ReturnCode::FAIL
}
}
impl<'a> hil::uart::UartData<'a> for Uart<'a> {}
impl<'a> hil::uart::Uart<'a> for Uart<'a> {}
unsafe fn setup(uart: &'static Uart) {
let dynamic_deferred_call_clients =
static_init!([DynamicDeferredCallClientState; 2], Default::default());
let dynamic_deferred_caller = static_init!(
DynamicDeferredCall,
DynamicDeferredCall::new(dynamic_deferred_call_clients)
);
DynamicDeferredCall::set_global_instance(dynamic_deferred_caller);
let uart_mux = components::console::UartMuxComponent::new(
uart,
115200,
dynamic_deferred_caller,
)
.finalize(());
//let console_uart = static_init!(UartDevice, UartDevice::new(uart_mux, true));
//console_uart.setup();
let process_console_uart = static_init!(UartDevice, UartDevice::new(uart_mux, true));
process_console_uart.setup();
struct Client {
uart: &'static UartDevice<'static>,
};
impl ReceiveClient for Client {
fn received_buffer(
&self,
buf: &'static mut [u8],
len: usize,
ret: kernel::ReturnCode,
err: kernel::hil::uart::Error,
) {
println!("Client::received_buffer {:?} ret {:?} err {:?}", &buf[..len], ret, err);
self.uart.receive_buffer(buf, 1);
}
}
let c = static_init!(Client, Client { uart: process_console_uart });
let b = static_init!([u8; 10], [0; 10]);
process_console_uart.set_receive_client(c);
process_console_uart.receive_buffer(b, 1);
}
fn main() {
let (tx, rx) = mpsc::channel();
let uart = Box::leak(Box::new(Uart {
tx_client: OptionalCell::empty(),
rx_client: OptionalCell::empty(),
chan: tx,
}));
unsafe {
setup(uart);
}
println!("Init done!");
let mut counter = 0;
for (rx_buffer, rx_len) in rx {
for b in rx_buffer[..rx_len].iter_mut() {
*b = counter;
counter += 1;
}
uart.rx_client.map(move |client| {
client.received_buffer(rx_buffer, rx_len, ReturnCode::SUCCESS, hil::uart::Error::None);
});
if counter == 10 {
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment