mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-08 04:56:43 +00:00
parent
024d95e75b
commit
cb875cf54e
2 changed files with 76 additions and 14 deletions
|
|
@ -49,15 +49,78 @@ impl ProcessPid for XousTarget {
|
|||
}
|
||||
}
|
||||
|
||||
fn receive_irq(uart: &mut GdbUart) {
|
||||
while let Some(c) = uart.getc() {
|
||||
process_character(c);
|
||||
struct MicroRingBuf<const N: usize> {
|
||||
buffer: [u8; N],
|
||||
head: usize,
|
||||
tail: usize,
|
||||
}
|
||||
|
||||
impl<const N: usize> Default for MicroRingBuf<N> {
|
||||
fn default() -> Self {
|
||||
MicroRingBuf {
|
||||
buffer: [0u8; N],
|
||||
head: 0,
|
||||
tail: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> MicroRingBuf<N> {
|
||||
// pub fn capacity(&self) -> usize {
|
||||
// self.buffer.len()
|
||||
// }
|
||||
// pub fn len(&self) -> usize {
|
||||
// self.head.wrapping_sub(self.tail) % N
|
||||
// }
|
||||
|
||||
pub fn is_full(&self) -> bool {
|
||||
(self.tail.wrapping_sub(1) % N) == self.head
|
||||
}
|
||||
|
||||
// If the GDB server goes away for some reason, reconstitute it
|
||||
unsafe {
|
||||
if GDB_STATE.is_none() {
|
||||
init();
|
||||
pub fn try_push(&mut self, val: u8) -> Result<(), ()> {
|
||||
if self.is_full() {
|
||||
return Err(());
|
||||
}
|
||||
self.buffer[self.head] = val;
|
||||
self.head = (self.head + 1) % N;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn try_pop(&mut self) -> Option<u8> {
|
||||
if self.tail == self.head {
|
||||
return None;
|
||||
}
|
||||
let val = self.buffer[self.tail];
|
||||
self.tail = (self.tail + 1) % N;
|
||||
Some(val)
|
||||
}
|
||||
}
|
||||
|
||||
fn receive_irq(uart: &mut GdbUart) {
|
||||
let mut buffer = MicroRingBuf::<32>::default();
|
||||
loop {
|
||||
// Try to fill up the ring buffer with as many characters
|
||||
// as can fit. This is to compensate for the fact that we do
|
||||
// all of this processing in an interrupt context, and the
|
||||
// hardware UART buffer is only a few characters deep.
|
||||
while !buffer.is_full() {
|
||||
if let Some(c) = uart.getc() {
|
||||
buffer.try_push(c).ok();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If there is a character in the buffer, process it. Otherwise,
|
||||
// we're done.
|
||||
let Some(c) = buffer.try_pop() else { break };
|
||||
process_character(c);
|
||||
|
||||
// If the GDB server goes away for some reason, reconstitute it
|
||||
unsafe {
|
||||
if GDB_STATE.is_none() {
|
||||
init();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,14 +142,13 @@ impl SerialRead for GdbUart {
|
|||
fn getc(&mut self) -> Option<u8> {
|
||||
// If EV_PENDING_RX is 1, return the pending character.
|
||||
// Otherwise, return None.
|
||||
match self.uart_csr.rf(utra::app_uart::EV_PENDING_RX) {
|
||||
0 => None,
|
||||
_ => {
|
||||
let ret = Some(self.uart_csr.r(utra::app_uart::RXTX) as u8);
|
||||
self.uart_csr.wfo(utra::app_uart::EV_PENDING_RX, 1);
|
||||
ret
|
||||
}
|
||||
if self.uart_csr.r(utra::app_uart::RXEMPTY) != 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let ret = self.uart_csr.r(utra::app_uart::RXTX) as u8;
|
||||
self.uart_csr.wfo(utra::app_uart::EV_PENDING_RX, 1);
|
||||
Some(ret)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue