mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-08 04:56:43 +00:00
fix RTC callbacks
This commit is contained in:
parent
1994b730b7
commit
75295485a7
11 changed files with 98 additions and 76 deletions
|
|
@ -3,7 +3,7 @@
|
|||
<device schemaVersion="1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="CMSIS-SVD.xsd" >
|
||||
<vendor>litex</vendor>
|
||||
<name>SOC</name>
|
||||
<description><![CDATA[Litex SoC 2021-04-12 22:13:49]]></description>
|
||||
<description><![CDATA[Litex SoC 2021-04-12 22:36:11]]></description>
|
||||
|
||||
<addressUnitBits>8</addressUnitBits>
|
||||
<width>32</width>
|
||||
|
|
@ -2803,7 +2803,7 @@ again until the interrupt is serviced.]]></description>
|
|||
<name>SEED1</name>
|
||||
<description><![CDATA[Bits 32-63 of `SEED_SEED`. Seed used for the build]]></description>
|
||||
<addressOffset>0x0000</addressOffset>
|
||||
<resetValue>0x64af9099</resetValue>
|
||||
<resetValue>0x9878c8f</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
|
|
@ -2818,7 +2818,7 @@ again until the interrupt is serviced.]]></description>
|
|||
<name>SEED0</name>
|
||||
<description><![CDATA[Bits 0-31 of `SEED_SEED`.]]></description>
|
||||
<addressOffset>0x0004</addressOffset>
|
||||
<resetValue>0x108cfc08</resetValue>
|
||||
<resetValue>0x8f844c5</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ pub(crate) const SERVER_NAME: &str = "_Callback test server_";
|
|||
pub(crate) enum Opcode {
|
||||
RegisterTickListener,
|
||||
RegisterReqListener,
|
||||
UnregisterReqListener,
|
||||
Tick,
|
||||
Req,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,12 +43,18 @@ impl CbTestServer {
|
|||
}
|
||||
}
|
||||
pub fn hook_req_callback(&mut self, cb: fn(u32)) -> Result<(), xous::Error> {
|
||||
log::trace!("hooking req callback");
|
||||
log::info!("hooking req callback");
|
||||
if unsafe{REQ_CB}.is_some() {
|
||||
return Err(xous::Error::MemoryInUse)
|
||||
}
|
||||
unsafe{REQ_CB = Some(cb)};
|
||||
if self.req_cb_sid.is_none() {
|
||||
if let Some(sid) = self.req_cb_sid {
|
||||
let sid_tuple = sid.to_u32();
|
||||
xous::send_message(self.conn,
|
||||
Message::new_scalar(Opcode::RegisterReqListener.to_usize().unwrap(),
|
||||
sid_tuple.0 as usize, sid_tuple.1 as usize, sid_tuple.2 as usize, sid_tuple.3 as usize
|
||||
)).unwrap();
|
||||
} else {
|
||||
let sid = xous::create_server().unwrap();
|
||||
self.req_cb_sid = Some(sid);
|
||||
let sid_tuple = sid.to_u32();
|
||||
|
|
@ -61,6 +67,10 @@ impl CbTestServer {
|
|||
Ok(())
|
||||
}
|
||||
pub fn unhook_req_callback(&mut self) -> Result<(), xous::Error> {
|
||||
log::info!("UNhooking req callback");
|
||||
unsafe{REQ_CB = None};
|
||||
|
||||
/*
|
||||
if let Some(sid) = self.req_cb_sid.take() {
|
||||
// tell my handler thread to quit
|
||||
log::trace!("connect for unhook");
|
||||
|
|
@ -78,8 +88,14 @@ impl CbTestServer {
|
|||
}
|
||||
}
|
||||
log::trace!("nullifying local state");
|
||||
self.req_cb_sid = None;
|
||||
unsafe{REQ_CB = None};
|
||||
self.req_cb_sid = None; */
|
||||
if let Some(sid) = self.req_cb_sid {
|
||||
let sid_tuple = sid.to_u32();
|
||||
xous::send_message(self.conn,
|
||||
Message::new_scalar(Opcode::UnregisterReqListener.to_usize().unwrap(),
|
||||
sid_tuple.0 as usize, sid_tuple.1 as usize, sid_tuple.2 as usize, sid_tuple.3 as usize
|
||||
)).unwrap();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -124,7 +140,7 @@ fn tick_cb_server(sid0: usize, sid1: usize, sid2: usize, sid3: usize) {
|
|||
|
||||
fn req_cb_server(sid0: usize, sid1: usize, sid2: usize, sid3: usize) {
|
||||
let sid = xous::SID::from_u32(sid0 as u32, sid1 as u32, sid2 as u32, sid3 as u32);
|
||||
log::trace!("req callback server started");
|
||||
log::info!("req callback server started with SID {:x?}", sid);
|
||||
loop {
|
||||
let msg = xous::receive_message(sid).unwrap();
|
||||
log::trace!("req callback got msg: {:?}", msg);
|
||||
|
|
@ -134,7 +150,10 @@ fn req_cb_server(sid0: usize, sid1: usize, sid2: usize, sid3: usize) {
|
|||
if let Some(cb) = REQ_CB {
|
||||
cb(result as u32)
|
||||
} else {
|
||||
break;
|
||||
// we got a callback message after we unregistered
|
||||
// not fatal, it just means the server may not have received
|
||||
// our unregistration message in time
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
|
@ -146,6 +165,6 @@ fn req_cb_server(sid0: usize, sid1: usize, sid2: usize, sid3: usize) {
|
|||
}
|
||||
}
|
||||
}
|
||||
log::trace!("req callback server exiting");
|
||||
log::info!("req callback server exiting");
|
||||
xous::destroy_server(sid).expect("can't destroy my server on exit!");
|
||||
}
|
||||
|
|
@ -26,14 +26,14 @@ fn pump_thread() {
|
|||
loop {
|
||||
xous::send_message(server_conn,
|
||||
xous::Message::new_scalar(Opcode::Tick.to_usize().unwrap(), 0, 0, 0, 0)).expect("couldn't send Tick message");
|
||||
ticktimer.sleep_ms(500).expect("couldn't sleep");
|
||||
ticktimer.sleep_ms(100).expect("couldn't sleep");
|
||||
}
|
||||
}
|
||||
|
||||
#[xous::xous_main]
|
||||
fn shell_main() -> ! {
|
||||
log_server::init_wait().unwrap();
|
||||
log::set_max_level(log::LevelFilter::Debug);
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
log::info!("my PID is {}", xous::process::id());
|
||||
|
||||
let xns = xous_names::XousNames::new().unwrap();
|
||||
|
|
@ -43,7 +43,7 @@ fn shell_main() -> ! {
|
|||
log::info!("pump thread started");
|
||||
|
||||
let mut tick_cb: [Option<ScalarCallback>; 32] = [None; 32];
|
||||
let mut req_cb: [bool; 32] = [false; 32];
|
||||
let mut req_cb: [bool; 34] = [false; 34];
|
||||
|
||||
let mut ticks = 0;
|
||||
let mut state = 0;
|
||||
|
|
@ -83,21 +83,20 @@ fn shell_main() -> ! {
|
|||
} else {
|
||||
log::error!("cid out of allowable range");
|
||||
}
|
||||
/*
|
||||
let mut found = false;
|
||||
for entry in req_cb.iter_mut() {
|
||||
if *entry == None {
|
||||
*entry = cid;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}),
|
||||
Some(Opcode::UnregisterReqListener) => msg_scalar_unpack!(msg, sid0, sid1, sid2, sid3, {
|
||||
let sid = xous::SID::from_u32(sid0 as _, sid1 as _, sid2 as _, sid3 as _);
|
||||
let cid = xous::connect(sid).unwrap(); // if the connection already exists, this just looks it up in the table
|
||||
log::info!("UnregisterReqListener cid {}", cid);
|
||||
if (cid as usize) < req_cb.len() {
|
||||
req_cb[cid as usize] = false;
|
||||
} else {
|
||||
log::error!("cid out of allowable range");
|
||||
}
|
||||
if !found {
|
||||
log::error!("RegisterTickListener ran out of space registering callback");
|
||||
}*/
|
||||
unsafe{xous::disconnect(cid).unwrap()};
|
||||
}),
|
||||
Some(Opcode::Req) => msg_scalar_unpack!(msg, _, _, _, _, {
|
||||
//log::debug!("req_cb: {:?}", req_cb);
|
||||
log::debug!("req_cb: {:?}", req_cb);
|
||||
// send results to request listeners
|
||||
for cid in 1..req_cb.len() { // 0 is not a valid connection
|
||||
if req_cb[cid as usize] {
|
||||
|
|
|
|||
|
|
@ -601,7 +601,7 @@ fn xmain() -> ! {
|
|||
let dbglistener = true;
|
||||
let dbgcanvas = false;
|
||||
log_server::init_wait().unwrap();
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
info!("my PID is {}", xous::process::id());
|
||||
|
||||
let xns = xous_names::XousNames::new().unwrap();
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ pub(crate) enum Opcode {
|
|||
/// register a callback for the datetime
|
||||
RegisterDateTimeCallback,
|
||||
|
||||
/// unregister a callback for the datetime
|
||||
UnregisterDateTimeCallback,
|
||||
|
||||
/// sets the datetime
|
||||
SetDateTime, //(DateTime),
|
||||
|
||||
|
|
|
|||
|
|
@ -30,25 +30,14 @@ impl Rtc {
|
|||
buf.lend(self.conn, Opcode::SetDateTime.to_u32().unwrap()).map(|_| ())
|
||||
}
|
||||
pub fn unhook_rtc_callback(&mut self) -> Result<(), xous::Error> {
|
||||
if let Some(sid) = self.callback_sid.take() {
|
||||
// tell my handler thread to quit
|
||||
log::trace!("connect for unhook");
|
||||
let cid = xous::connect(sid).expect("can't connect to CB server for disconnect message");
|
||||
log::trace!("sending drop to conn {}", cid);
|
||||
send_message(cid,
|
||||
Message::new_scalar(Return::Drop.to_usize().unwrap(), 0, 0, 0, 0)
|
||||
).unwrap();
|
||||
log::trace!("disconnecting unhook connection");
|
||||
unsafe{
|
||||
match xous::disconnect(cid) {
|
||||
Ok(_) => log::trace!("disconnected unhook connection"),
|
||||
Err(e) => log::error!("unhook rtc got error: {:?}", e),
|
||||
};
|
||||
}
|
||||
}
|
||||
log::trace!("nullifying local state");
|
||||
self.callback_sid = None;
|
||||
unsafe{RTC_CB = None};
|
||||
if let Some(sid) = self.callback_sid {
|
||||
let sid_tuple = sid.to_u32();
|
||||
xous::send_message(self.conn,
|
||||
Message::new_scalar(Opcode::UnregisterDateTimeCallback.to_usize().unwrap(),
|
||||
sid_tuple.0 as usize, sid_tuple.1 as usize, sid_tuple.2 as usize, sid_tuple.3 as usize
|
||||
)).unwrap();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn hook_rtc_callback(&mut self, cb: fn(DateTime)) -> Result<(), xous::Error> {
|
||||
|
|
@ -57,7 +46,13 @@ impl Rtc {
|
|||
return Err(xous::Error::MemoryInUse)
|
||||
}
|
||||
unsafe{RTC_CB = Some(cb)};
|
||||
if self.callback_sid.is_none() {
|
||||
if let Some(sid) = self.callback_sid {
|
||||
let sid_tuple = sid.to_u32();
|
||||
xous::send_message(self.conn,
|
||||
Message::new_scalar(Opcode::RegisterDateTimeCallback.to_usize().unwrap(),
|
||||
sid_tuple.0 as usize, sid_tuple.1 as usize, sid_tuple.2 as usize, sid_tuple.3 as usize
|
||||
)).unwrap();
|
||||
} else {
|
||||
let sid = xous::create_server().unwrap();
|
||||
self.callback_sid = Some(sid);
|
||||
let sid_tuple = sid.to_u32();
|
||||
|
|
@ -135,7 +130,10 @@ fn rtc_cb_server(sid0: usize, sid1: usize, sid2: usize, sid3: usize) {
|
|||
if let Some(cb) = RTC_CB {
|
||||
cb(dt)
|
||||
} else {
|
||||
break;
|
||||
// callback happened after we unregistered
|
||||
// this is a race condition, but it's also a harmless side effect
|
||||
// we handle it by just ignoring the message
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ mod api;
|
|||
use num_traits::{FromPrimitive, ToPrimitive};
|
||||
use xous_ipc::Buffer;
|
||||
use api::{Return, Opcode, DateTime};
|
||||
use xous::{CID, msg_scalar_unpack};
|
||||
use xous::msg_scalar_unpack;
|
||||
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
static CB_TO_MAIN_CONN: AtomicU32 = AtomicU32::new(0);
|
||||
|
|
@ -534,7 +534,7 @@ fn xmain() -> ! {
|
|||
use crate::implementation::Rtc;
|
||||
|
||||
log_server::init_wait().unwrap();
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
log::info!("my PID is {}", xous::process::id());
|
||||
|
||||
let xns = xous_names::XousNames::new().unwrap();
|
||||
|
|
@ -549,7 +549,7 @@ fn xmain() -> ! {
|
|||
let mut rtc = Rtc::new(&xns);
|
||||
|
||||
let ticktimer = ticktimer_server::Ticktimer::new().expect("can't connect to ticktimer");
|
||||
let mut dt_cb_conns: [Option<CID>; 32] = [None; 32];
|
||||
let mut dt_cb_conns: [bool; 34] = [false; 34];
|
||||
log::trace!("ready to accept requests");
|
||||
loop {
|
||||
let msg = xous::receive_message(rtc_sid).unwrap();
|
||||
|
|
@ -586,33 +586,35 @@ fn xmain() -> ! {
|
|||
},
|
||||
Some(Opcode::RegisterDateTimeCallback) => msg_scalar_unpack!(msg, sid0, sid1, sid2, sid3, {
|
||||
let sid = xous::SID::from_u32(sid0 as _, sid1 as _, sid2 as _, sid3 as _);
|
||||
let cid = Some(xous::connect(sid).unwrap());
|
||||
let mut found = false;
|
||||
for entry in dt_cb_conns.iter_mut() {
|
||||
if *entry == None {
|
||||
*entry = cid;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
log::error!("RegisterDateTimeCallback listener ran out of space registering callback");
|
||||
let cid = xous::connect(sid).unwrap();
|
||||
if (cid as usize) < dt_cb_conns.len() {
|
||||
dt_cb_conns[cid as usize] = true;
|
||||
} else {
|
||||
log::trace!("RegisterDateTimeCallback completed");
|
||||
// this should "never" happen because we only have up to 32 connections possible per server
|
||||
log::error!("RegisterDateTimeCallback received a CID out of range");
|
||||
}
|
||||
}),
|
||||
Some(Opcode::UnregisterDateTimeCallback) => msg_scalar_unpack!(msg, sid0, sid1, sid2, sid3, {
|
||||
let sid = xous::SID::from_u32(sid0 as _, sid1 as _, sid2 as _, sid3 as _);
|
||||
let cid = xous::connect(sid).unwrap();
|
||||
if (cid as usize) < dt_cb_conns.len() {
|
||||
dt_cb_conns[cid as usize] = false;
|
||||
} else {
|
||||
log::error!("UnregisterDateTimeCallback CID out of allowable range");
|
||||
}
|
||||
}),
|
||||
Some(Opcode::ResponseDateTime) => {
|
||||
let incoming_buffer = unsafe { Buffer::from_memory_message(msg.body.memory_message().unwrap()) };
|
||||
let dt = incoming_buffer.to_original::<DateTime, _>().unwrap();
|
||||
log::trace!("ResponseDateTime received: {:?}", dt);
|
||||
for maybe_conn in dt_cb_conns.iter_mut() {
|
||||
if let Some(conn) = maybe_conn {
|
||||
for cid in 1..dt_cb_conns.len() { // 0 is not a valid connection
|
||||
if dt_cb_conns[cid as usize] {
|
||||
let outgoing_buf = Buffer::into_buf(dt).or(Err(xous::Error::InternalError)).unwrap();
|
||||
log::trace!("ResponeDateTime sending to {}", *conn);
|
||||
match outgoing_buf.lend(*conn, Return::ReturnDateTime.to_u32().unwrap()) {
|
||||
log::trace!("ResponeDateTime sending to {}", cid);
|
||||
match outgoing_buf.lend(cid as u32, Return::ReturnDateTime.to_u32().unwrap()) {
|
||||
Err(xous::Error::ServerNotFound) => {
|
||||
log::trace!("ServerNotFound, dropping connection");
|
||||
*maybe_conn = None
|
||||
dt_cb_conns[cid] = false;
|
||||
},
|
||||
Ok(_) => {
|
||||
log::trace!("RespondeDateTime sent successfully");
|
||||
|
|
@ -667,14 +669,14 @@ fn xmain() -> ! {
|
|||
xous::disconnect(cb_to_main_conn).unwrap();
|
||||
}
|
||||
}
|
||||
for entry in dt_cb_conns.iter_mut() {
|
||||
if let Some(conn) = entry {
|
||||
xous::send_message(*conn,
|
||||
for cid in 1..dt_cb_conns.len() {
|
||||
if dt_cb_conns[cid as usize] {
|
||||
xous::send_message(cid as u32,
|
||||
xous::Message::new_scalar(Return::Drop.to_usize().unwrap(), 0, 0, 0, 0)
|
||||
).unwrap();
|
||||
unsafe{xous::disconnect(*conn).unwrap();}
|
||||
unsafe{xous::disconnect(cid as u32).unwrap();}
|
||||
dt_cb_conns[cid as usize] = false;
|
||||
}
|
||||
*entry = None;
|
||||
}
|
||||
xns.unregister_server(rtc_sid).unwrap();
|
||||
xous::destroy_server(rtc_sid).unwrap();
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ pub(crate) const SERVER_NAME_SHELLCHAT: &str = "_Shell chat application_";
|
|||
#[xous::xous_main]
|
||||
fn xmain() -> ! {
|
||||
log_server::init_wait().unwrap();
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
info!("my PID is {}", xous::process::id());
|
||||
|
||||
let xns = xous_names::XousNames::new().unwrap();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<device schemaVersion="1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="CMSIS-SVD.xsd" >
|
||||
<vendor>litex</vendor>
|
||||
<name>SOC</name>
|
||||
<description><![CDATA[Litex SoC 2021-04-12 22:13:49]]></description>
|
||||
<description><![CDATA[Litex SoC 2021-04-12 22:36:11]]></description>
|
||||
|
||||
<addressUnitBits>8</addressUnitBits>
|
||||
<width>32</width>
|
||||
|
|
@ -2803,7 +2803,7 @@ again until the interrupt is serviced.]]></description>
|
|||
<name>SEED1</name>
|
||||
<description><![CDATA[Bits 32-63 of `SEED_SEED`. Seed used for the build]]></description>
|
||||
<addressOffset>0x0000</addressOffset>
|
||||
<resetValue>0x64af9099</resetValue>
|
||||
<resetValue>0x9878c8f</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
|
|
@ -2818,7 +2818,7 @@ again until the interrupt is serviced.]]></description>
|
|||
<name>SEED0</name>
|
||||
<description><![CDATA[Bits 0-31 of `SEED_SEED`.]]></description>
|
||||
<addressOffset>0x0004</addressOffset>
|
||||
<resetValue>0x108cfc08</resetValue>
|
||||
<resetValue>0x8f844c5</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ fn try_main() -> Result<(), DynError> {
|
|||
&cbtest_pkgs,
|
||||
)?,
|
||||
Some("renode-image-debug") => renode_image(true, &hw_pkgs)?,
|
||||
Some("run") => run(false, &cbtest_pkgs)?,
|
||||
Some("run") => run(false, &hw_pkgs)?,
|
||||
Some("hw-image") => build_hw_image(false, env::args().nth(2), &hw_pkgs)?,
|
||||
Some("benchmark") => build_hw_image(false, env::args().nth(2), &benchmark_pkgs)?,
|
||||
Some("fcc-agent") => build_hw_image(false, env::args().nth(2), &fcc_pkgs)?,
|
||||
|
|
|
|||
Loading…
Reference in a new issue