1
0
forked from M-Labs/kirdy

main: Add checks before sock send/recv are called

This commit is contained in:
linuswck 2024-04-29 17:57:45 +08:00
parent b8241d1f27
commit 70fed23c51
2 changed files with 57 additions and 40 deletions

View File

@ -140,8 +140,6 @@ fn main() -> ! {
laser.load_settings_from_summary(laser_settings); laser.load_settings_from_summary(laser_settings);
} }
State::MainLoop => { State::MainLoop => {
let mut eth_is_pending = false;
laser.poll_and_update_output_current(); laser.poll_and_update_output_current();
if thermostat.poll_adc() { if thermostat.poll_adc() {
@ -155,12 +153,16 @@ fn main() -> ! {
net::net::for_each(|mut socket, id| { net::net::for_each(|mut socket, id| {
if net::net::eth_is_socket_active(socket) && net::net::eth_is_socket_connected(socket) { if net::net::eth_is_socket_active(socket) && net::net::eth_is_socket_connected(socket) {
if active_report[id] { if active_report[id] {
net::cmd_handler::send_status_report( if net::net::eth_can_sock_send(socket) {
eth_data_buffer, net::cmd_handler::send_status_report(
&mut laser, eth_data_buffer,
&mut thermostat, &mut laser,
&mut socket, &mut thermostat,
); &mut socket,
);
} else {
debug!("Socket {:?} is not ready to send status report", id)
}
} }
} else { } else {
active_report[id] = false; active_report[id] = false;
@ -169,13 +171,10 @@ fn main() -> ! {
thermostat.start_tec_readings_conversion(); thermostat.start_tec_readings_conversion();
} }
cortex_m::interrupt::free(|cs| {
eth_is_pending = net::net::is_pending(cs); net::net::for_each(|mut socket, id| {
net::net::clear_pending(cs); if net::net::eth_is_socket_active(socket) && net::net::eth_is_socket_connected(socket) {
}); if net::net::eth_can_sock_recv(socket) && net::net::eth_can_sock_send(socket) {
if eth_is_pending {
net::net::for_each(|mut socket, id| {
if net::net::eth_is_socket_active(socket) && net::net::eth_is_socket_connected(socket) {
let bytes = net::net::eth_recv(eth_data_buffer, socket); let bytes = net::net::eth_recv(eth_data_buffer, socket);
if bytes != 0 { if bytes != 0 {
info!("Ts: {:?}", sys_timer::now()); info!("Ts: {:?}", sys_timer::now());
@ -192,9 +191,11 @@ fn main() -> ! {
&mut active_report[id], &mut active_report[id],
); );
} }
} else {
debug!("Socket {:?} is not ready to process command", id);
} }
}) }
}; })
} }
State::SaveLdThermostatSettings => { State::SaveLdThermostatSettings => {
// State Transition // State Transition

View File

@ -1,7 +1,5 @@
use core::{cell::RefCell, use core::mem::{self, MaybeUninit};
mem::{self, MaybeUninit}};
use cortex_m::interrupt::{CriticalSection, Mutex};
use log::{debug, info}; use log::{debug, info};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use smoltcp::{iface::{self, Interface, SocketHandle, SocketSet, SocketStorage}, use smoltcp::{iface::{self, Interface, SocketHandle, SocketSet, SocketStorage},
@ -36,10 +34,6 @@ impl Default for IpSettings {
} }
} }
/// Interrupt pending flag: set by the `ETH` interrupt handler, should
/// be cleared before polling the interface.
static NET_PENDING: Mutex<RefCell<bool>> = Mutex::new(RefCell::new(false));
pub struct ServerHandle { pub struct ServerHandle {
socket_handles: [SocketHandle; NUM_OF_SOCKETS], socket_handles: [SocketHandle; NUM_OF_SOCKETS],
socket_set: SocketSet<'static>, socket_set: SocketSet<'static>,
@ -230,9 +224,15 @@ impl ServerHandle {
pub fn send(&mut self, buffer: &mut [u8], num_bytes: usize, socket_handles: SocketHandle) { pub fn send(&mut self, buffer: &mut [u8], num_bytes: usize, socket_handles: SocketHandle) {
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(); match socket.send_slice(&buffer[..num_bytes]) {
self.poll_iface(); Ok(_) => {
info!("Sent {} bytes.", num_bytes); self.poll_iface();
info!("Sent {} bytes.", num_bytes);
}
Err(err) => {
info!("Bytes cannot be sent. Error: {:?}", err)
}
};
} }
} }
@ -258,6 +258,14 @@ impl ServerHandle {
let socket = self.socket_set.get_mut::<Socket>(socket_handles); let socket = self.socket_set.get_mut::<Socket>(socket_handles);
socket.abort(); socket.abort();
} }
pub fn can_send(&mut self, socket_handles: SocketHandle) -> bool {
self.socket_set.get_mut::<Socket>(socket_handles).can_send()
}
pub fn can_recv(&mut self, socket_handles: SocketHandle) -> bool {
self.socket_set.get_mut::<Socket>(socket_handles).can_recv()
}
} }
use ieee802_3_miim::{phy::{lan87xxa::{LAN8720A, LAN8742A}, use ieee802_3_miim::{phy::{lan87xxa::{LAN8720A, LAN8742A},
@ -357,6 +365,26 @@ impl<M: Miim> EthernetPhy<M> {
} }
} }
pub fn eth_can_sock_send(socket_handles: SocketHandle) -> bool {
unsafe {
if let Some(ref mut server_handle) = SERVER_HANDLE {
server_handle.can_send(socket_handles)
} else {
panic!("eth_check_if_sock_can_send is called before init");
}
}
}
pub fn eth_can_sock_recv(socket_handles: SocketHandle) -> bool {
unsafe {
if let Some(ref mut server_handle) = SERVER_HANDLE {
server_handle.can_recv(socket_handles)
} else {
panic!("eth_check_if_sock_can_recv is called before init");
}
}
}
pub fn eth_poll_link_status_and_update_link_speed() -> bool { pub fn eth_poll_link_status_and_update_link_speed() -> bool {
unsafe { unsafe {
if let Some(ref mut server_handle) = SERVER_HANDLE { if let Some(ref mut server_handle) = SERVER_HANDLE {
@ -457,22 +485,10 @@ pub fn for_each<F: FnMut(SocketHandle, usize)>(mut callback: F) {
#[interrupt] #[interrupt]
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(|_| {
if interrupt_reason.rx { if interrupt_reason.rx {
*NET_PENDING.borrow(cs).borrow_mut() = true;
eth_poll_iface(); eth_poll_iface();
} }
}); });
debug!("Ethernet Interrupt{:?}", interrupt_reason); debug!("Ethernet Interrupt{:?}", interrupt_reason);
} }
/// Has an interrupt occurred since last call to `clear_pending()`?
pub fn is_pending(cs: &CriticalSection) -> bool {
*NET_PENDING.borrow(cs).borrow()
}
/// Clear the interrupt pending flag before polling the interface for
/// data.
pub fn clear_pending(cs: &CriticalSection) {
*NET_PENDING.borrow(cs).borrow_mut() = false;
}