eth: Poll Iface In ETH IRQ

- Improve responsiveness of TCP packets handling
- Fix a bug when one client is connected and active report is ON, the other client's cmds do not receive Ack from Kirdy
This commit is contained in:
linuswck 2024-03-20 14:25:35 +08:00
parent e525a3f354
commit 7d2e14ef2f
2 changed files with 32 additions and 21 deletions

View File

@ -159,19 +159,16 @@ fn main() -> ! {
} }
}); });
} }
net::net::for_each(|mut socket, id| { cortex_m::interrupt::free(|cs|
if net::net::eth_is_socket_active(socket) { {
cortex_m::interrupt::free(|cs| eth_is_pending = net::net::is_pending(cs);
{ net::net::clear_pending(cs);
eth_is_pending = net::net::is_pending(cs); }
} );
); if eth_is_pending {
net::net::for_each(|mut socket, id| {
if eth_is_pending { if net::net::eth_is_socket_active(socket) && net::net::eth_is_socket_connected(socket){
unsafe{ unsafe{
cortex_m::interrupt::free(|cs| {
net::net::clear_pending(cs);
});
let bytes = net::net::eth_recv(&mut ETH_DATA_BUFFER, socket); let bytes = net::net::eth_recv(&mut ETH_DATA_BUFFER, socket);
if bytes != 0 { if bytes != 0 {
info!("Ts: {:?}", sys_timer::now()); info!("Ts: {:?}", sys_timer::now());
@ -184,8 +181,8 @@ fn main() -> ! {
if has_temp_reading { if has_temp_reading {
thermostat.start_tec_readings_conversion(); thermostat.start_tec_readings_conversion();
} }
} })
}); };
} }
State::SaveFlashSettings => { State::SaveFlashSettings => {
// State Transition // State Transition

View File

@ -207,8 +207,11 @@ impl ServerHandle {
self.link_was_up = self.phy.phy_link_up(); self.link_was_up = self.phy.phy_link_up();
} }
pub fn recv(&mut self, buffer: &mut [u8], socket_handles: SocketHandle)-> Result<usize, smoltcp::socket::tcp::RecvError> { pub fn poll_iface(&mut self) {
self.iface.poll(now_fn(), &mut &mut self.dma, &mut self.socket_set); self.iface.poll(now_fn(), &mut &mut self.dma, &mut self.socket_set);
}
pub fn recv(&mut self, buffer: &mut [u8], socket_handles: SocketHandle)-> Result<usize, smoltcp::socket::tcp::RecvError> {
let socket = self.socket_set.get_mut::<Socket>(socket_handles); let socket = self.socket_set.get_mut::<Socket>(socket_handles);
socket.recv_slice(buffer) socket.recv_slice(buffer)
@ -218,11 +221,9 @@ impl ServerHandle {
let socket = self.socket_set.get_mut::<Socket>(socket_handles); let socket = self.socket_set.get_mut::<Socket>(socket_handles);
if num_bytes > 0 { if num_bytes > 0 {
socket.send_slice(&buffer[..num_bytes]).ok(); socket.send_slice(&buffer[..num_bytes]).ok();
self.poll_iface();
info!("Sent {} bytes.", num_bytes); info!("Sent {} bytes.", num_bytes);
} }
// Send bytes out
self.iface.poll(now_fn(), &mut &mut self.dma, &mut self.socket_set);
} }
pub fn is_socket_connected(&mut self, socket_handles: SocketHandle)->bool { pub fn is_socket_connected(&mut self, socket_handles: SocketHandle)->bool {
@ -362,6 +363,17 @@ pub fn eth_poll_and_update_link_speed() {
} }
} }
pub fn eth_poll_iface() {
unsafe {
if let Some(ref mut server_handle ) = SERVER_HANDLE {
server_handle.poll_iface();
}
else {
panic!("eth_poll_packet is called before init");
}
}
}
pub fn eth_send(buffer: &mut [u8], num_bytes: usize, socket_handles: SocketHandle) { pub fn eth_send(buffer: &mut [u8], num_bytes: usize, socket_handles: SocketHandle) {
unsafe { unsafe {
if let Some(ref mut server_handle ) = SERVER_HANDLE { if let Some(ref mut server_handle ) = SERVER_HANDLE {
@ -442,10 +454,12 @@ pub fn for_each<F: FnMut(SocketHandle, usize)>(mut callback: F) {
fn ETH() { fn ETH() {
let interrupt_reason = stm32_eth::eth_interrupt_handler(); let interrupt_reason = stm32_eth::eth_interrupt_handler();
cortex_m::interrupt::free(|cs| { cortex_m::interrupt::free(|cs| {
*NET_PENDING.borrow(cs) if interrupt_reason.rx {
.borrow_mut() = true; *NET_PENDING.borrow(cs)
.borrow_mut() = true;
eth_poll_iface();
}
}); });
debug!("Ethernet Interrupt{:?}", interrupt_reason); debug!("Ethernet Interrupt{:?}", interrupt_reason);
} }