forked from M-Labs/nac3
add moninj skeleton (WIP)
This commit is contained in:
parent
3a77ddbcc9
commit
b310e068d4
|
@ -21,7 +21,9 @@ use libsupport_zynq::alloc::{vec, vec::Vec};
|
||||||
use libasync::{smoltcp::{Sockets, TcpStream}, task};
|
use libasync::{smoltcp::{Sockets, TcpStream}, task};
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
|
|
||||||
|
use crate::proto::*;
|
||||||
use crate::kernel;
|
use crate::kernel;
|
||||||
|
use crate::moninj;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
@ -51,54 +53,6 @@ impl From<smoltcp::Error> for Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn expect(stream: &TcpStream, pattern: &[u8]) -> Result<()> {
|
|
||||||
stream.recv(|buf| {
|
|
||||||
for (i, b) in buf.iter().enumerate() {
|
|
||||||
if *b == pattern[i] {
|
|
||||||
if i + 1 == pattern.len() {
|
|
||||||
return Poll::Ready((i + 1, Ok(())));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Poll::Ready((i + 1, Err(Error::UnexpectedPattern)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Poll::Pending
|
|
||||||
}).await?
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_i8(stream: &TcpStream) -> Result<i8> {
|
|
||||||
Ok(stream.recv(|buf| {
|
|
||||||
Poll::Ready((1, buf[0] as i8))
|
|
||||||
}).await?)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_i32(stream: &TcpStream) -> Result<i32> {
|
|
||||||
Ok(stream.recv(|buf| {
|
|
||||||
if buf.len() >= 4 {
|
|
||||||
let value =
|
|
||||||
((buf[0] as i32) << 24)
|
|
||||||
| ((buf[1] as i32) << 16)
|
|
||||||
| ((buf[2] as i32) << 8)
|
|
||||||
| (buf[3] as i32);
|
|
||||||
Poll::Ready((4, value))
|
|
||||||
} else {
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
}).await?)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_drain(stream: &TcpStream, total: usize) -> Result<()> {
|
|
||||||
let mut done = 0;
|
|
||||||
while done < total {
|
|
||||||
let count = stream.recv(|buf| {
|
|
||||||
let count = min(total - done, buf.len());
|
|
||||||
Poll::Ready((count, count))
|
|
||||||
}).await?;
|
|
||||||
done += count;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_chunk(stream: &TcpStream, destination: &mut [u8]) -> Result<()> {
|
async fn read_chunk(stream: &TcpStream, destination: &mut [u8]) -> Result<()> {
|
||||||
let total = destination.len();
|
let total = destination.len();
|
||||||
let destination = RefCell::new(destination);
|
let destination = RefCell::new(destination);
|
||||||
|
@ -115,7 +69,7 @@ async fn read_chunk(stream: &TcpStream, destination: &mut [u8]) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromPrimitive, ToPrimitive)]
|
#[derive(Debug, FromPrimitive, ToPrimitive)]
|
||||||
enum Request {
|
enum Request {
|
||||||
SystemInfo = 3,
|
SystemInfo = 3,
|
||||||
LoadKernel = 5,
|
LoadKernel = 5,
|
||||||
|
@ -124,7 +78,7 @@ enum Request {
|
||||||
RPCException = 8,
|
RPCException = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromPrimitive, ToPrimitive)]
|
#[derive(Debug, FromPrimitive, ToPrimitive)]
|
||||||
enum Reply {
|
enum Reply {
|
||||||
SystemInfo = 2,
|
SystemInfo = 2,
|
||||||
LoadCompleted = 5,
|
LoadCompleted = 5,
|
||||||
|
@ -137,15 +91,6 @@ enum Reply {
|
||||||
ClockFailure = 15,
|
ClockFailure = 15,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn write_i32(stream: &TcpStream, value: i32) -> Result<()> {
|
|
||||||
stream.send([
|
|
||||||
(value >> 24) as u8,
|
|
||||||
(value >> 16) as u8,
|
|
||||||
(value >> 8) as u8,
|
|
||||||
value as u8].iter().copied()).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn write_chunk(stream: &TcpStream, chunk: &[u8]) -> Result<()> {
|
async fn write_chunk(stream: &TcpStream, chunk: &[u8]) -> Result<()> {
|
||||||
write_i32(stream, chunk.len() as i32).await?;
|
write_i32(stream, chunk.len() as i32).await?;
|
||||||
stream.send(chunk.iter().copied()).await?;
|
stream.send(chunk.iter().copied()).await?;
|
||||||
|
@ -160,7 +105,9 @@ async fn write_header(stream: &TcpStream, reply: Reply) -> Result<()> {
|
||||||
async fn handle_connection(stream: &TcpStream, control: Rc<RefCell<kernel::Control>>) -> Result<()> {
|
async fn handle_connection(stream: &TcpStream, control: Rc<RefCell<kernel::Control>>) -> Result<()> {
|
||||||
expect(&stream, b"ARTIQ coredev\n").await?;
|
expect(&stream, b"ARTIQ coredev\n").await?;
|
||||||
loop {
|
loop {
|
||||||
expect(&stream, &[0x5a, 0x5a, 0x5a, 0x5a]).await?;
|
if !expect(&stream, &[0x5a, 0x5a, 0x5a, 0x5a]).await? {
|
||||||
|
return Err(Error::UnexpectedPattern)
|
||||||
|
}
|
||||||
let request: Request = FromPrimitive::from_i8(read_i8(&stream).await?)
|
let request: Request = FromPrimitive::from_i8(read_i8(&stream).await?)
|
||||||
.ok_or(Error::UnrecognizedPacket)?;
|
.ok_or(Error::UnrecognizedPacket)?;
|
||||||
match request {
|
match request {
|
||||||
|
@ -242,7 +189,6 @@ pub fn main() {
|
||||||
Sockets::init(32);
|
Sockets::init(32);
|
||||||
|
|
||||||
let control: Rc<RefCell<kernel::Control>> = Rc::new(RefCell::new(kernel::Control::start(8192)));
|
let control: Rc<RefCell<kernel::Control>> = Rc::new(RefCell::new(kernel::Control::start(8192)));
|
||||||
|
|
||||||
task::spawn(async move {
|
task::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
let stream = TcpStream::accept(1381, 2048, 2048).await.unwrap();
|
let stream = TcpStream::accept(1381, 2048, 2048).await.unwrap();
|
||||||
|
@ -250,13 +196,15 @@ pub fn main() {
|
||||||
task::spawn(async {
|
task::spawn(async {
|
||||||
let _ = handle_connection(&stream, control)
|
let _ = handle_connection(&stream, control)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| warn!("Connection: {}", e));
|
.map_err(|e| warn!("connection terminated: {}", e));
|
||||||
let _ = stream.flush().await;
|
let _ = stream.flush().await;
|
||||||
let _ = stream.abort().await;
|
let _ = stream.abort().await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
moninj::start();
|
||||||
|
|
||||||
let mut time = 0u32;
|
let mut time = 0u32;
|
||||||
Sockets::run(&mut iface, || {
|
Sockets::run(&mut iface, || {
|
||||||
time += 1;
|
time += 1;
|
||||||
|
|
|
@ -12,10 +12,12 @@ use libboard_zynq::{
|
||||||
};
|
};
|
||||||
use libsupport_zynq::{logger, ram};
|
use libsupport_zynq::{logger, ram};
|
||||||
|
|
||||||
|
mod proto;
|
||||||
mod comms;
|
mod comms;
|
||||||
mod pl;
|
mod pl;
|
||||||
mod rtio;
|
mod rtio;
|
||||||
mod kernel;
|
mod kernel;
|
||||||
|
mod moninj;
|
||||||
|
|
||||||
|
|
||||||
fn identifier_read(buf: &mut [u8]) -> &str {
|
fn identifier_read(buf: &mut [u8]) -> &str {
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
use core::fmt;
|
||||||
|
use log::{info, warn};
|
||||||
|
|
||||||
|
use libboard_zynq::smoltcp;
|
||||||
|
use libasync::task;
|
||||||
|
use libasync::smoltcp::TcpStream;
|
||||||
|
|
||||||
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
|
use num_traits::{FromPrimitive, ToPrimitive};
|
||||||
|
|
||||||
|
use crate::proto::*;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum Error {
|
||||||
|
NetworkError(smoltcp::Error),
|
||||||
|
UnexpectedPattern,
|
||||||
|
UnrecognizedPacket,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = core::result::Result<T, Error>;
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&Error::NetworkError(error) => write!(f, "network error: {}", error),
|
||||||
|
&Error::UnexpectedPattern => write!(f, "unexpected pattern"),
|
||||||
|
&Error::UnrecognizedPacket => write!(f, "unrecognized packet"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<smoltcp::Error> for Error {
|
||||||
|
fn from(error: smoltcp::Error) -> Self {
|
||||||
|
Error::NetworkError(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, FromPrimitive, ToPrimitive)]
|
||||||
|
enum HostMessage {
|
||||||
|
MonitorProbe = 0,
|
||||||
|
MonitorInjection = 3,
|
||||||
|
Inject = 1,
|
||||||
|
GetInjectionStatus = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, FromPrimitive, ToPrimitive)]
|
||||||
|
enum DeviceMessage {
|
||||||
|
MonitorStatus = 0,
|
||||||
|
InjectionStatus = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_connection(stream: &TcpStream) -> Result<()> {
|
||||||
|
if !expect(&stream, b"ARTIQ moninj\n").await? {
|
||||||
|
return Err(Error::UnexpectedPattern);
|
||||||
|
}
|
||||||
|
loop {
|
||||||
|
let message: HostMessage = FromPrimitive::from_i8(read_i8(&stream).await?)
|
||||||
|
.ok_or(Error::UnrecognizedPacket)?;
|
||||||
|
info!("{:?}", message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start() {
|
||||||
|
task::spawn(async move {
|
||||||
|
loop {
|
||||||
|
let stream = TcpStream::accept(1383, 2048, 2048).await.unwrap();
|
||||||
|
task::spawn(async {
|
||||||
|
let _ = handle_connection(&stream)
|
||||||
|
.await
|
||||||
|
.map_err(|e| warn!("connection terminated: {}", e));
|
||||||
|
let _ = stream.flush().await;
|
||||||
|
let _ = stream.abort().await;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
use core::task::Poll;
|
||||||
|
use core::cmp::min;
|
||||||
|
|
||||||
|
use libboard_zynq::smoltcp;
|
||||||
|
use libasync::smoltcp::TcpStream;
|
||||||
|
|
||||||
|
|
||||||
|
pub type Result<T> = core::result::Result<T, smoltcp::Error>;
|
||||||
|
|
||||||
|
pub async fn expect(stream: &TcpStream, pattern: &[u8]) -> Result<bool> {
|
||||||
|
stream.recv(|buf| {
|
||||||
|
for (i, b) in buf.iter().enumerate() {
|
||||||
|
if *b == pattern[i] {
|
||||||
|
if i + 1 == pattern.len() {
|
||||||
|
return Poll::Ready((i + 1, Ok(true)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Poll::Ready((i + 1, Ok(false)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Poll::Pending
|
||||||
|
}).await?
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn read_i8(stream: &TcpStream) -> Result<i8> {
|
||||||
|
Ok(stream.recv(|buf| {
|
||||||
|
Poll::Ready((1, buf[0] as i8))
|
||||||
|
}).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn read_i32(stream: &TcpStream) -> Result<i32> {
|
||||||
|
Ok(stream.recv(|buf| {
|
||||||
|
if buf.len() >= 4 {
|
||||||
|
let value =
|
||||||
|
((buf[0] as i32) << 24)
|
||||||
|
| ((buf[1] as i32) << 16)
|
||||||
|
| ((buf[2] as i32) << 8)
|
||||||
|
| (buf[3] as i32);
|
||||||
|
Poll::Ready((4, value))
|
||||||
|
} else {
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
}).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn read_drain(stream: &TcpStream, total: usize) -> Result<()> {
|
||||||
|
let mut done = 0;
|
||||||
|
while done < total {
|
||||||
|
let count = stream.recv(|buf| {
|
||||||
|
let count = min(total - done, buf.len());
|
||||||
|
Poll::Ready((count, count))
|
||||||
|
}).await?;
|
||||||
|
done += count;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn write_i32(stream: &TcpStream, value: i32) -> Result<()> {
|
||||||
|
stream.send([
|
||||||
|
(value >> 24) as u8,
|
||||||
|
(value >> 16) as u8,
|
||||||
|
(value >> 8) as u8,
|
||||||
|
value as u8].iter().copied()).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue