2023-08-31 17:36:01 +08:00
|
|
|
use alloc::vec::Vec;
|
|
|
|
|
|
|
|
use cslice::CSlice;
|
|
|
|
|
2023-09-06 16:06:38 +08:00
|
|
|
use super::{Message, SubkernelStatus, KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0};
|
2023-09-05 16:21:39 +08:00
|
|
|
use crate::{artiq_raise, rpc::send_args};
|
2023-08-31 17:36:01 +08:00
|
|
|
|
2023-12-12 10:19:17 +08:00
|
|
|
pub extern "C" fn load_run(id: u32, destination: u8, run: bool) {
|
2023-08-31 17:36:01 +08:00
|
|
|
unsafe {
|
|
|
|
KERNEL_CHANNEL_1TO0
|
|
|
|
.as_mut()
|
|
|
|
.unwrap()
|
2023-12-12 10:19:17 +08:00
|
|
|
.send(Message::SubkernelLoadRunRequest {
|
|
|
|
id: id,
|
|
|
|
destination: destination,
|
|
|
|
run: run,
|
|
|
|
});
|
2023-08-31 17:36:01 +08:00
|
|
|
}
|
|
|
|
match unsafe { KERNEL_CHANNEL_0TO1.as_mut().unwrap() }.recv() {
|
|
|
|
Message::SubkernelLoadRunReply { succeeded: true } => (),
|
|
|
|
Message::SubkernelLoadRunReply { succeeded: false } => {
|
|
|
|
artiq_raise!("SubkernelError", "Error loading or running the subkernel")
|
|
|
|
}
|
|
|
|
_ => panic!("Expected SubkernelLoadRunReply after SubkernelLoadRunRequest!"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-30 14:04:11 +08:00
|
|
|
pub extern "C" fn await_finish(id: u32, timeout: i64) {
|
2023-08-31 17:36:01 +08:00
|
|
|
unsafe {
|
|
|
|
KERNEL_CHANNEL_1TO0
|
|
|
|
.as_mut()
|
|
|
|
.unwrap()
|
|
|
|
.send(Message::SubkernelAwaitFinishRequest {
|
|
|
|
id: id,
|
|
|
|
timeout: timeout,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
match unsafe { KERNEL_CHANNEL_0TO1.as_mut().unwrap() }.recv() {
|
|
|
|
Message::SubkernelAwaitFinishReply {
|
|
|
|
status: SubkernelStatus::NoError,
|
|
|
|
} => (),
|
|
|
|
Message::SubkernelAwaitFinishReply {
|
|
|
|
status: SubkernelStatus::IncorrectState,
|
|
|
|
} => artiq_raise!("SubkernelError", "Subkernel not running"),
|
|
|
|
Message::SubkernelAwaitFinishReply {
|
|
|
|
status: SubkernelStatus::Timeout,
|
|
|
|
} => artiq_raise!("SubkernelError", "Subkernel timed out"),
|
|
|
|
Message::SubkernelAwaitFinishReply {
|
|
|
|
status: SubkernelStatus::CommLost,
|
|
|
|
} => artiq_raise!("SubkernelError", "Lost communication with satellite"),
|
|
|
|
Message::SubkernelAwaitFinishReply {
|
|
|
|
status: SubkernelStatus::OtherError,
|
|
|
|
} => artiq_raise!("SubkernelError", "An error occurred during subkernel operation"),
|
|
|
|
_ => panic!("expected SubkernelAwaitFinishReply after SubkernelAwaitFinishRequest"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-12 10:19:17 +08:00
|
|
|
pub extern "C" fn send_message(
|
|
|
|
id: u32,
|
|
|
|
is_return: bool,
|
|
|
|
destination: u8,
|
|
|
|
count: u8,
|
|
|
|
tag: &CSlice<u8>,
|
|
|
|
data: *const *const (),
|
|
|
|
) {
|
2023-08-31 17:36:01 +08:00
|
|
|
let mut buffer = Vec::<u8>::new();
|
2023-10-18 11:56:38 +08:00
|
|
|
send_args(&mut buffer, 0, tag.as_ref(), data, false).expect("RPC encoding failed");
|
2023-09-21 17:31:49 +08:00
|
|
|
// overwrite service tag, include how many tags are in the message
|
|
|
|
buffer[3] = count;
|
2023-08-31 17:36:01 +08:00
|
|
|
unsafe {
|
|
|
|
KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::SubkernelMsgSend {
|
|
|
|
id: id,
|
2023-12-12 10:19:17 +08:00
|
|
|
destination: if is_return { None } else { Some(destination) },
|
2023-09-21 17:31:49 +08:00
|
|
|
data: buffer[3..].to_vec(),
|
2023-08-31 17:36:01 +08:00
|
|
|
});
|
|
|
|
}
|
2023-09-05 16:21:39 +08:00
|
|
|
match unsafe { KERNEL_CHANNEL_0TO1.as_mut().unwrap() }.recv() {
|
|
|
|
Message::SubkernelMsgSent => (),
|
|
|
|
_ => panic!("expected SubkernelMsgSent after SubkernelMsgSend"),
|
|
|
|
}
|
2023-08-31 17:36:01 +08:00
|
|
|
}
|
|
|
|
|
2024-01-30 14:04:11 +08:00
|
|
|
pub extern "C" fn await_message(id: i32, timeout: i64, tags: &CSlice<u8>, min: u8, max: u8) {
|
2023-08-31 17:36:01 +08:00
|
|
|
unsafe {
|
|
|
|
KERNEL_CHANNEL_1TO0
|
|
|
|
.as_mut()
|
|
|
|
.unwrap()
|
|
|
|
.send(Message::SubkernelMsgRecvRequest {
|
|
|
|
id: id,
|
|
|
|
timeout: timeout,
|
2023-10-18 11:56:38 +08:00
|
|
|
tags: tags.as_ref().to_vec(),
|
2023-08-31 17:36:01 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
match unsafe { KERNEL_CHANNEL_0TO1.as_mut().unwrap() }.recv() {
|
|
|
|
Message::SubkernelMsgRecvReply {
|
|
|
|
status: SubkernelStatus::NoError,
|
2023-10-09 11:50:47 +08:00
|
|
|
count,
|
2023-09-21 17:31:49 +08:00
|
|
|
} => {
|
|
|
|
if min > count || count > max {
|
|
|
|
artiq_raise!("SubkernelError", "Received more or less arguments than required")
|
|
|
|
}
|
2023-10-09 11:50:47 +08:00
|
|
|
}
|
2023-08-31 17:36:01 +08:00
|
|
|
Message::SubkernelMsgRecvReply {
|
|
|
|
status: SubkernelStatus::IncorrectState,
|
2023-09-21 17:31:49 +08:00
|
|
|
..
|
2023-08-31 17:36:01 +08:00
|
|
|
} => artiq_raise!("SubkernelError", "Subkernel not running"),
|
|
|
|
Message::SubkernelMsgRecvReply {
|
|
|
|
status: SubkernelStatus::Timeout,
|
2023-09-21 17:31:49 +08:00
|
|
|
..
|
2023-08-31 17:36:01 +08:00
|
|
|
} => artiq_raise!("SubkernelError", "Subkernel timed out"),
|
|
|
|
Message::SubkernelMsgRecvReply {
|
|
|
|
status: SubkernelStatus::CommLost,
|
2023-09-21 17:31:49 +08:00
|
|
|
..
|
2023-08-31 17:36:01 +08:00
|
|
|
} => artiq_raise!("SubkernelError", "Lost communication with satellite"),
|
|
|
|
Message::SubkernelMsgRecvReply {
|
|
|
|
status: SubkernelStatus::OtherError,
|
2023-09-21 17:31:49 +08:00
|
|
|
..
|
2023-08-31 17:36:01 +08:00
|
|
|
} => artiq_raise!("SubkernelError", "An error occurred during subkernel operation"),
|
|
|
|
_ => panic!("expected SubkernelMsgRecvReply after SubkernelMsgRecvRequest"),
|
|
|
|
}
|
|
|
|
// RpcRecvRequest should be called after this to receive message data
|
|
|
|
}
|